diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c19386392fbfd9c7d56a6be41c8bf8a55f28854c
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,5 @@
+repos:
+-   repo: git://github.com/detailyang/pre-commit-shell
+    rev: 1.0.4
+    hooks:
+    - id: shell-lint
diff --git a/.travis.yml b/.travis.yml
index 9fc974add5b567748e8952aaa1c7477faf5d2b88..4390d4920b15ead9fd73d1a6f54556c1a652fefa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,9 +5,7 @@ rvm:
 - 2.4.4
 before_script:
   - gem install bundler -v 1.16.2
-  - bundle exec rake hatchet:setup_travis
-before_install:
-  - sudo bash etc/ci-setup.sh
+  - bundle exec hatchet ci:setup
 jobs:
   include:
   - stage: Bash linting (shellcheck)
@@ -35,5 +33,6 @@ env:
   - HATCHET_RETRIES=3
   - IS_RUNNING_ON_CI=true
   - HATCHET_APP_LIMIT=5
+  - HATCHET_DEPLOY_STRATEGY=git
   - secure: yjtlPE5FbVxTKnjUy/tZUBgSEf4qADD3QOxtgziuid73S0U/1IEXlMGFULsQzIjtlHKmHeywZqpVVEpthIH4RuT7uoX1Pb7SSM/g0T8fT3VoEFbFK1uYl0oZQbUS4Klxv9tPiumj8if3m6ULEGIz1X0wZcMOC0tMLwVCnwmap0E=
   - secure: ZeFTHWwnpIKE9nAqs88ocmiQh7bKce84lilGm5J23nf3N6V4wNyLwqlkvsM008WGBCaOg9AUx7ZunasT0ANsR5gLP3eV2UUg7ILdRgV2Gy13eNRFheC4PHdN92RqQ3aKoqlIv2K999xlhVjod0NzhkQQXB6PddfQINbuU7ks6As=
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1a5e3a0e032e019be3728732e9a62ca9431ed009..826b4fb9e0000c6b445f28a7f1a0db2c58e2c678 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,19 +1,31 @@
 # Python Buildpack Changelog
 
-# 141 (2018-10-10)
+# 146 (2018-15-08)
+
+Python 3.7.1, 3.6.7, 3.5.6 and 3.4.9 now available on all Heroku stacks.
+
+# 145 (2018-11-08)
+
+Testing and tooling expanded to better support new runtimes
+
+# 144 (2018-10-10)
 
 Switch to cautious upgrade for Pipenv install to ensure the pinned pip version
 is used with Pipenv
 
-# 140 (2018-10-09)
+# 143 (2018-10-09)
 
 Add support for detecting SLUGIFY_USES_TEXT_UNIDECODE, which is required to
 install Apache Airflow version 1.10 or higher.
 
-# 139 (2018-10-08)
+# 142 (2018-10-08)
 
 Improvements to Python install messaging
 
+# 139, 140, 141
+
+No user-facing changes, documenting for version clarity
+
 # 138 (2018-08-01)
 
 Use stack image SQLite3 instead of vendoring
diff --git a/Gemfile.lock b/Gemfile.lock
index 621cd725af7a845fad9b193a293b6ef5bfe78976..6a6f314b6b78e926c6f60ed665984886619ab323 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -6,16 +6,16 @@ GEM
       i18n (>= 0.7, < 2)
       minitest (~> 5.1)
       tzinfo (~> 1.1)
-    concurrent-ruby (1.0.5)
+    concurrent-ruby (1.1.3)
     diff-lcs (1.3)
     erubis (2.7.0)
     excon (0.62.0)
-    heroics (0.0.24)
+    heroics (0.0.25)
       erubis (~> 2.0)
       excon
       moneta
       multi_json (>= 1.9.2)
-    heroku_hatchet (4.0.2)
+    heroku_hatchet (4.0.6)
       excon (~> 0)
       minitest-retry (~> 0.1.9)
       platform-api (~> 2)
@@ -23,16 +23,16 @@ GEM
       rrrretry (~> 1)
       thor (~> 0)
       threaded (~> 0)
-    i18n (1.1.0)
+    i18n (1.1.1)
       concurrent-ruby (~> 1.0)
     minitest (5.11.3)
     minitest-retry (0.1.9)
       minitest (>= 5.0)
-    moneta (0.8.1)
+    moneta (1.0.0)
     multi_json (1.13.1)
-    platform-api (2.1.0)
-      heroics (~> 0.0.23)
-      moneta (~> 0.8.1)
+    platform-api (2.2.0)
+      heroics (~> 0.0.25)
+      moneta (~> 1.0.0)
     rake (12.3.1)
     repl_runner (0.0.3)
       activesupport
@@ -52,7 +52,7 @@ GEM
     rspec-retry (0.6.1)
       rspec-core (> 3.3)
     rspec-support (3.8.0)
-    thor (0.20.0)
+    thor (0.20.3)
     thread_safe (0.3.6)
     threaded (0.0.4)
     tzinfo (1.2.5)
diff --git a/Makefile b/Makefile
index 6d6ac4c30b08a6d9581fd7e11d2dc6ed5e074341..43c2bbf8aef044f6ccf811d8a90b3570ce3344b0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 # These targets are not files
 .PHONY: tests
 
-test: test-heroku-16
+test: test-heroku-18 test-heroku-16
 
 check:
 	@shellcheck -x bin/compile bin/detect bin/release bin/test-compile bin/utils bin/warnings
diff --git a/README.md b/README.md
index a4a5bf962c754a35b2a72f13161181cf022f6de5..546e5ecd0c91a6955a490a3ec4761e5ac4aaf912 100644
--- a/README.md
+++ b/README.md
@@ -4,36 +4,54 @@
 
 [![Build Status](https://travis-ci.org/heroku/heroku-buildpack-python.svg?branch=master)](https://travis-ci.org/heroku/heroku-buildpack-python)
 
-This is the official [Heroku buildpack](https://devcenter.heroku.com/articles/buildpacks) for Python apps, powered by [Pipenv](http://docs.pipenv.org/), [pip](https://pip.pypa.io/) and other excellent software.
+This is the official [Heroku buildpack](https://devcenter.heroku.com/articles/buildpacks) for Python apps.
 
-Recommended web frameworks include **Django** and **Flask**. The recommended webserver is **Gunicorn**. There are no restrictions around what software can be used (as long as it's pip-installable). Web processes must bind to `$PORT`, and only the HTTP protocol is permitted for incoming connections.
+Recommended web frameworks include **Django** and **Flask**, among others. The recommended webserver is **Gunicorn**. There are no restrictions around what software can be used (as long as it's pip-installable). Web processes must bind to `$PORT`, and only the HTTP protocol is permitted for incoming connections.
 
-Python packages with C dependencies that are not [available on the stack image](https://devcenter.heroku.com/articles/stack-packages) are generally not supported, unless `manylinux` wheels are provided by the package maintainers (common). For recommended solutions, check out [this article](https://devcenter.heroku.com/articles/python-c-deps) for more information. 
+Python packages with C dependencies that are not [available on the stack image](https://devcenter.heroku.com/articles/stack-packages) are generally not supported, unless `manylinux` wheels are provided by the package maintainers (common). For recommended solutions, check out [this article](https://devcenter.heroku.com/articles/python-c-deps) for more information.
 
 See it in Action
 ----------------
-
-Deploying a Python application couldn't be easier:
-
-    $ ls
-    Pipfile		Pipfile.lock	Procfile	web.py
-
-    $ heroku create --buildpack heroku/python
-
-    $ git push heroku master
-    …
-    -----> Python app detected
-    -----> Installing python-3.6.6
-    -----> Installing pip
-    -----> Installing requirements with Pipenv 2018.5.18…
-           ...
-           Installing dependencies from Pipfile…
-    -----> Discovering process types
-           Procfile declares types -> (none)
-
-A `Pipfile` or `requirements.txt` must be present at the root of your application's repository.
-
-You can also specify the latest production release of this buildpack for upcoming builds of an existing application:
+```
+$ ls
+my-application		requirements.txt	runtime.txt
+
+$ git push heroku master
+Counting objects: 4, done.
+Delta compression using up to 8 threads.
+Compressing objects: 100% (2/2), done.
+Writing objects: 100% (4/4), 276 bytes | 276.00 KiB/s, done.
+Total 4 (delta 0), reused 0 (delta 0)
+remote: Compressing source files... done.
+remote: Building source:
+remote:
+remote: -----> Python app detected
+remote: -----> Installing python-3.7.1
+remote: -----> Installing pip
+remote: -----> Installing SQLite3
+remote: -----> Installing requirements with pip
+remote:        Collecting flask (from -r /tmp/build_c2c067ef79ff14c9bf1aed6796f9ed1f/requirements.txt (line 1))
+remote:          Downloading ...
+remote:        Installing collected packages: Werkzeug, click, MarkupSafe, Jinja2, itsdangerous, flask
+remote:        Successfully installed Jinja2-2.10 MarkupSafe-1.1.0 Werkzeug-0.14.1 click-7.0 flask-1.0.2 itsdangerous-1.1.0
+remote:
+remote: -----> Discovering process types
+remote:        Procfile declares types -> (none)
+remote:
+```
+
+A `requirements.txt` must be present at the root of your application's repository to deploy.
+
+To specify your python version, you also need a `runtime.txt` file - unless you are using the default Python runtime version.
+
+Current default Python Runtime: Python 3.6.7
+
+Alternatively, you can provide a `setup.py` file, or a `Pipfile`. Using `Pipenv` will generate `runtime.txt` based on `python-version` at build time.
+
+Specify a Buildpack Version
+---------------------------
+
+You can specify the latest production release of this buildpack for upcoming builds of an existing application:
 
     $ heroku buildpacks:set heroku/python
 
@@ -41,23 +59,30 @@ You can also specify the latest production release of this buildpack for upcomin
 Specify a Python Runtime
 ------------------------
 
-Specific versions of the Python runtime can be specified in your `Pipfile`:
+Supported runtime options include:
+
+- `python-3.7.1`
+- `python-3.6.7`
+- `python-2.7.15`
 
-    [requires]
-    python_version = "2.7"
+## Tests
 
-Or, more specifically:
+The buildpack tests use [Docker](https://www.docker.com/) to simulate
+Heroku's [stack images.](https://devcenter.heroku.com/articles/stack)
 
-    [requires]
-    python_full_version = "2.7.15"
+To run the test suite:
 
-Or, with a `runtime.txt` file:
+```
+make test
+```
 
-    $ cat runtime.txt
-    python-2.7.15
+Or to test in a particular stack:
 
-Runtime options include:
+```
+make test-heroku-18
+make test-heroku-16
+```
 
-- `python-3.7.0`
-- `python-3.6.6`
-- `python-2.7.15`
+The tests are run via the vendored
+[shunit2](https://github.com/kward/shunit2)
+test framework.
diff --git a/bin/compile b/bin/compile
index d97af680d5428c3abb0d5f72444608a72df2248e..2d7c661eb373d4505c0dfd006a67ba17be974409 100755
--- a/bin/compile
+++ b/bin/compile
@@ -49,17 +49,28 @@ export VENDOR_URL
 # These variables are used to specify which versions of Python to install by default,
 # as well as prompt the user to upgrade if they are using an un–supported version.
 # Note: When 3.7 lands, I recommend switching to LATEST_36 and LATEST_37.
-DEFAULT_PYTHON_VERSION="python-3.6.6"
-LATEST_36="python-3.6.6"
-LATEST_37="python-3.7.0"
-LATEST_2="python-2.7.15"
+DEFAULT_PYTHON_VERSION="python-3.6.7"
+LATEST_36="python-3.6.7"
+LATEST_37="python-3.7.1"
+LATEST_35="python-3.5.6"
+LATEST_34="python-3.4.9"
+LATEST_27="python-2.7.15"
+
+# Supported Python Branches
+PY37="python-3.7"
+PY36="python-3.6"
+PY35="python-3.5"
+PY34="python-3.4"
+PY27="python-2.7"
 
 # Which stack is used (for binary downloading), if none is provided (e.g. outside of Heroku)?
 DEFAULT_PYTHON_STACK="cedar-14"
 # If pip doesn't match this version (the version we install), run the installer.
 PIP_UPDATE="9.0.2"
 
-export DEFAULT_PYTHON_VERSION DEFAULT_PYTHON_STACK PIP_UPDATE LATEST_2 LATEST_36 LATEST_37
+export DEFAULT_PYTHON_VERSION DEFAULT_PYTHON_STACK PIP_UPDATE
+export LATEST_27 LATEST_36 LATEST_37 LATEST_35 LATEST_34
+export PY37 PY36 PY35 PY27 PY34
 
 # Common Problem Warnings:
 # This section creates a temporary file in which to stick the output of `pip install`.
diff --git a/bin/steps/pipenv-python-version b/bin/steps/pipenv-python-version
index c8ee06dba2266d1bb1b284f6e3486db48b2e443f..dcdf3c2617559689019f93f69ad62a626cb7a95a 100755
--- a/bin/steps/pipenv-python-version
+++ b/bin/steps/pipenv-python-version
@@ -19,7 +19,7 @@ if [[ -f $BUILD_DIR/Pipfile ]]; then
             if [[ "$PYTHON" == "null" ]]; then
                 PYTHON=$(jq -r '._meta.requires.python_version' "$BUILD_DIR/Pipfile.lock")
                 if [ "$PYTHON" = 2.7 ]; then
-                    echo "$LATEST_2" > "$BUILD_DIR/runtime.txt"
+                    echo "$LATEST_27" > "$BUILD_DIR/runtime.txt"
                 fi
                 if [ "$PYTHON" = 3.6 ]; then
                     echo "$LATEST_36" > "$BUILD_DIR/runtime.txt"
@@ -33,4 +33,3 @@ if [[ -f $BUILD_DIR/Pipfile ]]; then
         fi
     fi
 fi
-
diff --git a/bin/steps/python b/bin/steps/python
index ea623b1bfdf72daef78dcb7c12bfa766f44e352a..d10eccf23463b56bcbe0d7c0252d9d2db43509ec 100755
--- a/bin/steps/python
+++ b/bin/steps/python
@@ -7,41 +7,49 @@ PYTHON_VERSION=$(cat runtime.txt)
 # The location of the pre-compiled python binary.
 VENDORED_PYTHON="${VENDOR_URL}/runtimes/$PYTHON_VERSION.tar.gz"
 
-if [[ $PYTHON_VERSION =~ ^python-2 ]]; then
-  if [[ "$PYTHON_VERSION" != "$LATEST_2" ]]; then
-    puts-warn "The latest version of Python 2 is $LATEST_2 (you are using $PYTHON_VERSION, which is unsupported)."
-    puts-warn "We recommend upgrading by specifying the latest version ($LATEST_2)."
-    echo "       Learn More: https://devcenter.heroku.com/articles/python-runtimes"
-  else
-    echo "       Using supported version of Python 2 ($PYTHON_VERSION)"
+SECURITY_UPDATE="Python has released a security update! Please consider upgrading to"
+
+# check if runtime exists
+if curl --output /dev/null --silent --head --fail "$VENDORED_PYTHON"; then
+  if [[ "$PYTHON_VERSION" == $PY37* ]]; then
+    # do things to alert the user of security release available
+    if [ "$PYTHON_VERSION" != "$LATEST_37" ]; then
+      puts-warn "$SECURITY_UPDATE" "$LATEST_37"
+      echo "       Learn More: https://devcenter.heroku.com/articles/python-runtimes"
+    fi
   fi
-else
-  if [[ $PYTHON_VERSION =~ ^python-3 ]]; then
-    if [[ $PYTHON_VERSION =~ ^python-3.7 ]]; then
-      if [[ "$PYTHON_VERSION" != "$LATEST_37" ]]; then
-      puts-warn "The latest version of Python 3.7 is $LATEST_37 (you are using $PYTHON_VERSION, which is unsupported)."
-      puts-warn "We recommend upgrading by specifying the latest version ($LATEST_37)."
+  if [[ "$PYTHON_VERSION" == $PY36* ]]; then
+    # security update note
+    if [ "$PYTHON_VERSION" != "$LATEST_36" ]; then
+      puts-warn "$SECURITY_UPDATE" "$LATEST_36"
+      echo "       Learn More: https://devcenter.heroku.com/articles/python-runtimes"
+    fi
+  fi
+  if [[ "$PYTHON_VERSION" == $PY35* ]]; then
+    # security update note
+    if [ "$PYTHON_VERSION" != "$LATEST_35" ]; then
+      puts-warn "$SECURITY_UPDATE" "$LATEST_35"
       echo "       Learn More: https://devcenter.heroku.com/articles/python-runtimes"
-      else
-        echo "       Using supported version of Python 3.7 ($PYTHON_VERSION)"
-      fi
-    else
-      if [[ $PYTHON_VERSION =~ ^python-3.6 ]]; then
-        if [[ "$PYTHON_VERSION" != "$LATEST_36" ]]; then
-          puts-warn "The latest version of Python 3.6 is $LATEST_36 (you are using $PYTHON_VERSION, which is unsupported)."
-          puts-warn "We recommend upgrading by specifying the latest version ($LATEST_36)."
-          echo "       Learn More: https://devcenter.heroku.com/articles/python-runtimes"
-        else
-          echo "       Using supported version of Python 3.6 ($PYTHON_VERSION)"
-        fi
-      else
-        puts-warn "Heroku supports runtime versions $LATEST_37, $LATEST_36 and $LATEST_2." 
-        puts-warn "You are using $PYTHON_VERSION, which is unsupported."
-        puts-warn "We recommend upgrading by specifying the default supported version ($LATEST_36)."
-        echo "       Learn More: https://devcenter.heroku.com/articles/python-runtimes"
-      fi
     fi
   fi
+  if [[ "$PYTHON_VERSION" == $PY34* ]]; then
+    # security update note
+    if [ "$PYTHON_VERSION" != "$LATEST_34" ]; then
+      puts-warn "$SECURITY_UPDATE" "$LATEST_34"
+      echo "       Learn More: https://devcenter.heroku.com/articles/python-runtimes"
+    fi
+  fi
+  if [[ "$PYTHON_VERSION" == $PY27* ]]; then
+    # security update note
+    if [ "$PYTHON_VERSION" != "$LATEST_27" ]; then
+      puts-warn "$SECURITY_UPDATE" "$LATEST_27"
+      echo "       Learn More: https://devcenter.heroku.com/articles/python-runtimes"
+    fi
+  fi
+else
+  puts-warn "Requested runtime ($PYTHON_VERSION) is not available for this stack ($STACK)."
+  puts-warn "Aborting.  More info: https://devcenter.heroku.com/articles/python-support"
+  exit 1
 fi
 
 if [[ "$STACK" != "$CACHED_PYTHON_STACK" ]]; then
diff --git a/bin/utils b/bin/utils
index 2bbf82a32e59e33c84bc5be925e72f6437cb4e68..f625645dff0ddaf8b21e86e9cfe6e4b45e183fc8 100755
--- a/bin/utils
+++ b/bin/utils
@@ -89,10 +89,9 @@ python3_check() {
 # Check if Python version needs to install SQLite3
 python_sqlite3_check() {
   VERSION="$1"
-  MIN_PYTHON_3="python-3.6.6"
+  MIN_PYTHON_3="python-3.5.6"
   MIN_PYTHON_2="python-2.7.15"
 
   ( python2_check "$VERSION" && version_gte "$VERSION" "$MIN_PYTHON_2" ) \
-    || ( python3_check "$VERSION" && version_gte "$VERSION" "$MIN_PYTHON_3" ) \
-    || ( version_gte "$VERSION" "3.7.0" )
+    || ( python3_check "$VERSION" && version_gte "$VERSION" "$MIN_PYTHON_3" )
 }
diff --git a/builds/runtimes/python-3.4.9 b/builds/runtimes/python-3.4.9
new file mode 100755
index 0000000000000000000000000000000000000000..00cf5078458461fed5ca810e06d864419674dd09
--- /dev/null
+++ b/builds/runtimes/python-3.4.9
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+# Build Path: /app/.heroku/python/
+
+OUT_PREFIX=$1
+BIN_DIR="$(cd "$(dirname "$0")"/../.. || exit; pwd)/bin"
+export BIN_DIR
+
+# shellcheck source=bin/utils
+source "$BIN_DIR/steps/sqlite3"
+
+sqlite3_version
+echo "Setting up SQLite3 Headers for $SQLITE3_VERSION"
+sqlite3_install "$OUT_PREFIX" "$SQLITE3_VERSION" 1
+
+echo "Building Python…"
+SOURCE_TARBALL='https://python.org/ftp/python/3.4.9/Python-3.4.9.tgz'
+curl -L $SOURCE_TARBALL | tar xz
+mv Python-3.4.9 src
+cd src
+
+./configure --prefix=$OUT_PREFIX --with-ensurepip=no
+make
+make install
+
+# Remove unneeded test directories, similar to the official Docker Python images:
+# https://github.com/docker-library/python
+find "${OUT_PREFIX}" \( -type d -a \( -name test -o -name tests \) \) -exec rm -rf '{}' +
+
+# Remove spare /
+LOCATION=${OUT_PREFIX%?}
+
+ln $LOCATION/bin/python3 $LOCATION/bin/python
diff --git a/builds/runtimes/python-3.5.6 b/builds/runtimes/python-3.5.6
new file mode 100755
index 0000000000000000000000000000000000000000..0d179352b1f3c996b1003d0ba9d5999a5bbd8c7c
--- /dev/null
+++ b/builds/runtimes/python-3.5.6
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+# Build Path: /app/.heroku/python/
+
+OUT_PREFIX=$1
+BIN_DIR="$(cd "$(dirname "$0")"/../.. || exit; pwd)/bin"
+export BIN_DIR
+
+# shellcheck source=bin/utils
+source "$BIN_DIR/steps/sqlite3"
+
+sqlite3_version
+echo "Setting up SQLite3 Headers for $SQLITE3_VERSION"
+sqlite3_install "$OUT_PREFIX" "$SQLITE3_VERSION" 1
+
+echo "Building Python…"
+SOURCE_TARBALL='https://python.org/ftp/python/3.5.6/Python-3.5.6.tgz'
+curl -L $SOURCE_TARBALL | tar xz
+mv Python-3.5.6 src
+cd src
+
+./configure --prefix=$OUT_PREFIX --with-ensurepip=no
+make
+make install
+
+# Remove unneeded test directories, similar to the official Docker Python images:
+# https://github.com/docker-library/python
+find "${OUT_PREFIX}" \( -type d -a \( -name test -o -name tests \) \) -exec rm -rf '{}' +
+
+# Remove spare /
+LOCATION=${OUT_PREFIX%?}
+
+ln $LOCATION/bin/python3 $LOCATION/bin/python
diff --git a/builds/runtimes/python-3.6.7 b/builds/runtimes/python-3.6.7
new file mode 100755
index 0000000000000000000000000000000000000000..052ee1e2fb0275ed9f5cf164f00951c61eda4e1e
--- /dev/null
+++ b/builds/runtimes/python-3.6.7
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+# Build Path: /app/.heroku/python/
+
+OUT_PREFIX=$1
+BIN_DIR="$(cd "$(dirname "$0")"/../.. || exit; pwd)/bin"
+export BIN_DIR
+
+# shellcheck source=bin/utils
+source "$BIN_DIR/steps/sqlite3"
+
+sqlite3_version
+echo "Setting up SQLite3 Headers for $SQLITE3_VERSION"
+sqlite3_install "$OUT_PREFIX" "$SQLITE3_VERSION" 1
+
+echo "Building Python…"
+SOURCE_TARBALL='https://python.org/ftp/python/3.6.7/Python-3.6.7.tgz'
+curl -L $SOURCE_TARBALL | tar xz
+mv Python-3.6.7 src
+cd src
+
+./configure --prefix=$OUT_PREFIX --with-ensurepip=no
+make
+make install
+
+# Remove unneeded test directories, similar to the official Docker Python images:
+# https://github.com/docker-library/python
+find "${OUT_PREFIX}" \( -type d -a \( -name test -o -name tests \) \) -exec rm -rf '{}' +
+
+# Remove spare /
+LOCATION=${OUT_PREFIX%?}
+
+ln $LOCATION/bin/python3 $LOCATION/bin/python
diff --git a/builds/runtimes/python-3.7.1 b/builds/runtimes/python-3.7.1
new file mode 100755
index 0000000000000000000000000000000000000000..b8051393f22aaf95ac504c64ea082eb025c17ca0
--- /dev/null
+++ b/builds/runtimes/python-3.7.1
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+# Build Path: /app/.heroku/python/
+
+OUT_PREFIX=$1
+BIN_DIR="$(cd "$(dirname "$0")"/../.. || exit; pwd)/bin"
+export BIN_DIR
+
+# shellcheck source=bin/utils
+source "$BIN_DIR/steps/sqlite3"
+
+sqlite3_version
+echo "Setting up SQLite3 Headers for $SQLITE3_VERSION"
+sqlite3_install "$OUT_PREFIX" "$SQLITE3_VERSION" 1
+
+echo "Building Python…"
+SOURCE_TARBALL='https://python.org/ftp/python/3.7.1/Python-3.7.1.tgz'
+curl -L $SOURCE_TARBALL | tar xz
+mv Python-3.7.1 src
+cd src
+
+./configure --prefix=$OUT_PREFIX --with-ensurepip=no
+make
+make install
+
+# Remove unneeded test directories, similar to the official Docker Python images:
+# https://github.com/docker-library/python
+find "${OUT_PREFIX}" \( -type d -a \( -name test -o -name tests \) \) -exec rm -rf '{}' +
+
+# Remove spare /
+LOCATION=${OUT_PREFIX%?}
+
+ln $LOCATION/bin/python3 $LOCATION/bin/python
diff --git a/requirements.txt b/requirements.txt
index 35bd16651cfbdf08820a00aff48aa38404248e7f..ad7e217efaeda0436f9d51e25a75837e7e102b3a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,3 @@
 docopt==0.6.2
-bob-builder==0.0.13
+bob-builder
 boto==2.48.0
diff --git a/spec/hatchet/python_spec.rb b/spec/hatchet/python_spec.rb
index 5ae95ed1b24d51f0d979559f7640ddbe048edeb4..39c00269d990d6aabb2c5431c38993c7721f3c96 100644
--- a/spec/hatchet/python_spec.rb
+++ b/spec/hatchet/python_spec.rb
@@ -4,7 +4,7 @@ describe "Python!!!!!!!!!!!" do
   it "🐍" do
     Hatchet::Runner.new('python-getting-started', stack: DEFAULT_STACK).deploy do |app|
       expect(app.output).to           match(/Installing pip/)
-      expect(app.run('python -V')).to match(/3.6.6/)
+      expect(app.run('python -V')).to match(/3.6.7/)
     end
   end
 end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index d8a55da7a3c99c51047a61a1d3fa327949539001..12a11b8899b3d51856398c7f4b359b97220318c4 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,4 +1,4 @@
-ENV['HATCHET_BUILDPACK_BASE'] = 'https://github.com/heroku/heroku-buildpack-python.git'
+ENV['HATCHET_BUILDPACK_BASE'] = 'https://github.com/' + ENV['TRAVIS_REPO_SLUG'] + '.git'
 
 require 'rspec/core'
 require 'rspec/retry'
diff --git a/test/fixtures/pipenv-version/Pipfile b/test/fixtures/pipenv-version/Pipfile
index cd4e813138e32642c4c9979cf289d2b43241815c..91ec2539881bbcb249109cadc8ab078549398ae8 100644
--- a/test/fixtures/pipenv-version/Pipfile
+++ b/test/fixtures/pipenv-version/Pipfile
@@ -6,4 +6,4 @@ verify_ssl = true
 requests = "*"
 
 [requires]
-python_version = "3.6"
\ No newline at end of file
+python_version = "3.6"
diff --git a/test/fixtures/pipenv-version2/Pipfile b/test/fixtures/pipenv-version2/Pipfile
new file mode 100644
index 0000000000000000000000000000000000000000..3026dd10ac2e152ac8062b762d116ebcbe084c81
--- /dev/null
+++ b/test/fixtures/pipenv-version2/Pipfile
@@ -0,0 +1,11 @@
+[[source]]
+url = "https://pypi.org/simple"
+verify_ssl = true
+name = "pypi"
+
+[packages]
+
+[dev-packages]
+
+[requires]
+python_version = "2.7"
diff --git a/test/fixtures/pipenv-version2/Pipfile.lock b/test/fixtures/pipenv-version2/Pipfile.lock
new file mode 100644
index 0000000000000000000000000000000000000000..637b90ff5ed18a03d96f67a6e125ff69b1a5d7d4
--- /dev/null
+++ b/test/fixtures/pipenv-version2/Pipfile.lock
@@ -0,0 +1,20 @@
+{
+    "_meta": {
+        "hash": {
+            "sha256": "ae4bdd7d4157baab65ae9d0e8389a6011e6b640995372c45ec81fa5d1ddfae9f"
+        },
+        "pipfile-spec": 6,
+        "requires": {
+            "python_version": "2.7"
+        },
+        "sources": [
+            {
+                "name": "pypi",
+                "url": "https://pypi.org/simple",
+                "verify_ssl": true
+            }
+        ]
+    },
+    "default": {},
+    "develop": {}
+}
diff --git a/test/fixtures/python3/requirements.txt b/test/fixtures/python2_fail/requirements.txt
similarity index 100%
rename from test/fixtures/python3/requirements.txt
rename to test/fixtures/python2_fail/requirements.txt
diff --git a/test/fixtures/python2_fail/runtime.txt b/test/fixtures/python2_fail/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d42956de9c4f2893134ed473cf17671343f4ee35
--- /dev/null
+++ b/test/fixtures/python2_fail/runtime.txt
@@ -0,0 +1 @@
+python-2.7.16
diff --git a/test/fixtures/python2_warn/requirements.txt b/test/fixtures/python2_warn/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..663bd1f6a2ae02f29df59fb4963c17934034f731
--- /dev/null
+++ b/test/fixtures/python2_warn/requirements.txt
@@ -0,0 +1 @@
+requests
\ No newline at end of file
diff --git a/test/fixtures/python2_warn/runtime.txt b/test/fixtures/python2_warn/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..538568204a78b4e4ec20255b64fa25533b4edae3
--- /dev/null
+++ b/test/fixtures/python2_warn/runtime.txt
@@ -0,0 +1 @@
+python-2.7.14
diff --git a/test/fixtures/python3_4/requirements.txt b/test/fixtures/python3_4/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7e1060246fd6746a14204539a72e199a25469a05
--- /dev/null
+++ b/test/fixtures/python3_4/requirements.txt
@@ -0,0 +1 @@
+flask
diff --git a/test/fixtures/python3_4/runtime.txt b/test/fixtures/python3_4/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cc8325f75753b807e16f0c2a1d05ac2d24b269b0
--- /dev/null
+++ b/test/fixtures/python3_4/runtime.txt
@@ -0,0 +1 @@
+python-3.4.9
diff --git a/test/fixtures/python3_4_fail/requirements.txt b/test/fixtures/python3_4_fail/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7e1060246fd6746a14204539a72e199a25469a05
--- /dev/null
+++ b/test/fixtures/python3_4_fail/requirements.txt
@@ -0,0 +1 @@
+flask
diff --git a/test/fixtures/python3_4_fail/runtime.txt b/test/fixtures/python3_4_fail/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3b5c63e5912725bc4dec2bfc3135db3470d14d8e
--- /dev/null
+++ b/test/fixtures/python3_4_fail/runtime.txt
@@ -0,0 +1 @@
+python-3.4.10
diff --git a/test/fixtures/python3_4_warn/requirements.txt b/test/fixtures/python3_4_warn/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7e1060246fd6746a14204539a72e199a25469a05
--- /dev/null
+++ b/test/fixtures/python3_4_warn/requirements.txt
@@ -0,0 +1 @@
+flask
diff --git a/test/fixtures/python3_4_warn/runtime.txt b/test/fixtures/python3_4_warn/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fe5dcf7a3aeb68d0bb349ddd6f7d61ba731a1057
--- /dev/null
+++ b/test/fixtures/python3_4_warn/runtime.txt
@@ -0,0 +1 @@
+python-3.4.0
diff --git a/test/fixtures/python3_5/requirements.txt b/test/fixtures/python3_5/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..663bd1f6a2ae02f29df59fb4963c17934034f731
--- /dev/null
+++ b/test/fixtures/python3_5/requirements.txt
@@ -0,0 +1 @@
+requests
\ No newline at end of file
diff --git a/test/fixtures/python3_5/runtime.txt b/test/fixtures/python3_5/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e6391f4a68edd6f81269b05227977459a9fbd6a8
--- /dev/null
+++ b/test/fixtures/python3_5/runtime.txt
@@ -0,0 +1 @@
+python-3.5.6
diff --git a/test/fixtures/python3_5_fail/requirements.txt b/test/fixtures/python3_5_fail/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7e1060246fd6746a14204539a72e199a25469a05
--- /dev/null
+++ b/test/fixtures/python3_5_fail/requirements.txt
@@ -0,0 +1 @@
+flask
diff --git a/test/fixtures/python3_5_fail/runtime.txt b/test/fixtures/python3_5_fail/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..df4118a6a06eb46538803009ef7a69291fca95dd
--- /dev/null
+++ b/test/fixtures/python3_5_fail/runtime.txt
@@ -0,0 +1 @@
+python-3.5.7
diff --git a/test/fixtures/python3_5_warn/requirements.txt b/test/fixtures/python3_5_warn/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7e1060246fd6746a14204539a72e199a25469a05
--- /dev/null
+++ b/test/fixtures/python3_5_warn/requirements.txt
@@ -0,0 +1 @@
+flask
diff --git a/test/fixtures/python3_5_warn/runtime.txt b/test/fixtures/python3_5_warn/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5486d7adb9a188bcfc1d0d8844b4091b1c369ec9
--- /dev/null
+++ b/test/fixtures/python3_5_warn/runtime.txt
@@ -0,0 +1 @@
+python-3.5.3
diff --git a/test/fixtures/python3_6/requirements.txt b/test/fixtures/python3_6/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..663bd1f6a2ae02f29df59fb4963c17934034f731
--- /dev/null
+++ b/test/fixtures/python3_6/requirements.txt
@@ -0,0 +1 @@
+requests
\ No newline at end of file
diff --git a/test/fixtures/python3_6/runtime.txt b/test/fixtures/python3_6/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..34b35b713f56868abc889d5798cab36939bec38f
--- /dev/null
+++ b/test/fixtures/python3_6/runtime.txt
@@ -0,0 +1 @@
+python-3.6.7
diff --git a/test/fixtures/python3_6_fail/requirements.txt b/test/fixtures/python3_6_fail/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7e1060246fd6746a14204539a72e199a25469a05
--- /dev/null
+++ b/test/fixtures/python3_6_fail/requirements.txt
@@ -0,0 +1 @@
+flask
diff --git a/test/fixtures/python3_6_fail/runtime.txt b/test/fixtures/python3_6_fail/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9fbd3bf0a8cbd237fdc16f03556d84baf76522be
--- /dev/null
+++ b/test/fixtures/python3_6_fail/runtime.txt
@@ -0,0 +1 @@
+python-3.6.8
diff --git a/test/fixtures/python3_6_warn/requirements.txt b/test/fixtures/python3_6_warn/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..663bd1f6a2ae02f29df59fb4963c17934034f731
--- /dev/null
+++ b/test/fixtures/python3_6_warn/requirements.txt
@@ -0,0 +1 @@
+requests
\ No newline at end of file
diff --git a/test/fixtures/python3_6_warn/runtime.txt b/test/fixtures/python3_6_warn/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..486fcce127f00eba90a4096290b67c31adaef0bd
--- /dev/null
+++ b/test/fixtures/python3_6_warn/runtime.txt
@@ -0,0 +1 @@
+python-3.6.5
diff --git a/test/fixtures/python3_7/requirements.txt b/test/fixtures/python3_7/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..663bd1f6a2ae02f29df59fb4963c17934034f731
--- /dev/null
+++ b/test/fixtures/python3_7/requirements.txt
@@ -0,0 +1 @@
+requests
\ No newline at end of file
diff --git a/test/fixtures/python3_7/runtime.txt b/test/fixtures/python3_7/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4255f73ae6037a2a4a5ddd6a1093c841fc339845
--- /dev/null
+++ b/test/fixtures/python3_7/runtime.txt
@@ -0,0 +1 @@
+python-3.7.1
diff --git a/test/fixtures/python3_7_fail/requirements.txt b/test/fixtures/python3_7_fail/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7e1060246fd6746a14204539a72e199a25469a05
--- /dev/null
+++ b/test/fixtures/python3_7_fail/requirements.txt
@@ -0,0 +1 @@
+flask
diff --git a/test/fixtures/python3_7_fail/runtime.txt b/test/fixtures/python3_7_fail/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a01373a365d95c1ab01706aadd1ff7376441ccfa
--- /dev/null
+++ b/test/fixtures/python3_7_fail/runtime.txt
@@ -0,0 +1 @@
+python-3.7.2
diff --git a/test/fixtures/python3_7_warn/requirements.txt b/test/fixtures/python3_7_warn/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..663bd1f6a2ae02f29df59fb4963c17934034f731
--- /dev/null
+++ b/test/fixtures/python3_7_warn/requirements.txt
@@ -0,0 +1 @@
+requests
\ No newline at end of file
diff --git a/test/fixtures/python3_7_warn/runtime.txt b/test/fixtures/python3_7_warn/runtime.txt
new file mode 100644
index 0000000000000000000000000000000000000000..881a2db1abd7719381d1925771e0d4208fb46fb5
--- /dev/null
+++ b/test/fixtures/python3_7_warn/runtime.txt
@@ -0,0 +1 @@
+python-3.7.0
diff --git a/test/fixtures/pythonDefault/requirements.txt b/test/fixtures/pythonDefault/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7e1060246fd6746a14204539a72e199a25469a05
--- /dev/null
+++ b/test/fixtures/pythonDefault/requirements.txt
@@ -0,0 +1 @@
+flask
diff --git a/test/run b/test/run
index f6368161bae2719f3f75e8fa4d18febfe1fef5bd..ae200a11391be04303e8c424ce1cb26700cc2a3a 100755
--- a/test/run
+++ b/test/run
@@ -19,10 +19,15 @@ testPipenvLock() {
 
 testPipenvVersion() {
   compile "pipenv-version"
-  assertCaptured "3.6.6"
+  assertCaptured "3.6.7"
   assertCapturedSuccess
 }
 
+testPipenvVersion2() {
+  compile "pipenv-version2"
+  assertCaptured "2.7.15"
+  assertCapturedSuccess
+}
 testPipenvFullVersion() {
   compile "pipenv-full-version"
   assertCaptured "3.6.3"
@@ -87,18 +92,127 @@ testPylibmc() {
   assertCapturedSuccess
 }
 
+testPythonDefault() {
+  compile "pythonDefault"
+  assertCaptured "python-3.6.7"
+  assertCapturedSuccess
+}
+
 testPython2() {
     compile "python2"
     assertCaptured "python-2.7.15"
     assertCapturedSuccess
 }
 
-testPython3() {
-  compile "python3"
-  assertCaptured "python-3.6.6"
+testPython2_warn() {
+    compile "python2_warn"
+    if [[ $STACK = "heroku-18" ]]; then
+      assertCapturedError
+    else
+      assertCaptured "python-2.7.14"
+      assertCaptured "security update!"
+      assertCapturedSuccess
+    fi
+}
+
+testPython2_fail() {
+    compile "python2_fail"
+    assertCaptured "Aborting"
+    assertCapturedError
+}
+
+testPython3_4() {
+  compile "python3_4"
+  assertCaptured "python-3.4.9"
+  assertCapturedSuccess
+}
+
+testPython3_4_warn() {
+  compile "python3_4_warn"
+  if [[ $STACK = "cedar-14" ]]; then
+    assertCaptured "python-3.4.0"
+    assertCaptured "security update!"
+    assertCapturedSuccess
+  else
+    assertCapturedError
+  fi
+}
+
+testPython3_4_fail() {
+    compile "python3_4_fail"
+    assertCaptured "Aborting"
+    assertCapturedError
+}
+
+testPython3_5() {
+  compile "python3_5"
+  assertCaptured "python-3.5.6"
+  assertCapturedSuccess
+}
+
+testPython3_5_warn() {
+  compile "python3_5_warn"
+  if [[ $STACK = "cedar-14" ]]; then
+    assertCaptured "python-3.5.3"
+    assertCaptured "security update!"
+    assertCapturedError
+  else
+    assertCapturedError
+  fi
+}
+
+testPython3_5_fail() {
+    compile "python3_5_fail"
+    assertCaptured "Aborting"
+    assertCapturedError
+}
+
+testPython3_6() {
+  compile "python3_6"
+  assertCaptured "python-3.6.7"
   assertCapturedSuccess
 }
 
+testPython3_6_warn() {
+  compile "python3_6_warn"
+  assertCaptured "python-3.6.5"
+  assertCaptured "security update!"
+  assertCapturedSuccess
+}
+
+testPython3_6_fail() {
+    compile "python3_6_fail"
+    assertCaptured "Aborting"
+    assertCapturedError
+}
+
+testPython3_7() {
+  compile "python3_7"
+  if [[ $STACK = "cedar-14" ]]; then
+    assertCapturedError
+  else
+    assertCaptured "python-3.7.1"
+    assertCapturedSuccess
+  fi
+}
+
+testPython3_7_warn() {
+  compile "python3_7_warn"
+  if [[ $STACK = "cedar-14" ]]; then
+    assertCapturedError
+  else
+    assertCaptured "python-3.7.0"
+    assertCaptured "security update!"
+    assertCapturedSuccess
+  fi
+}
+
+testPython3_7_fail() {
+  compile "python3_7_fail"
+  assertCaptured "Aborting"
+  assertCapturedError
+}
+
 testGitEgg() {
   compile "git-egg"
   assertCaptured "requests"