summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--pkgs/applications/audio/ingen/default.nix2
-rw-r--r--pkgs/applications/misc/blender/default.nix10
-rw-r--r--pkgs/applications/networking/instant-messengers/profanity/default.nix2
-rw-r--r--pkgs/applications/science/misc/golly/beta.nix4
-rw-r--r--pkgs/applications/science/misc/golly/default.nix5
-rw-r--r--pkgs/development/interpreters/python/build-python-package-common.nix5
-rw-r--r--pkgs/development/interpreters/python/build-python-package-setuptools.nix11
-rw-r--r--pkgs/development/interpreters/python/build-python-package.nix5
-rw-r--r--pkgs/development/interpreters/python/cpython/2.7/default.nix72
-rw-r--r--pkgs/development/interpreters/python/cpython/3.5/default.nix212
-rw-r--r--pkgs/development/interpreters/python/cpython/3.6/default.nix228
-rw-r--r--pkgs/development/interpreters/python/cpython/default.nix (renamed from pkgs/development/interpreters/python/cpython/3.7/default.nix)152
-rw-r--r--pkgs/development/interpreters/python/default.nix154
-rw-r--r--pkgs/development/interpreters/python/mk-python-derivation.nix7
-rw-r--r--pkgs/development/interpreters/python/pypy/2.7/default.nix136
-rw-r--r--pkgs/development/interpreters/python/pypy/3/tk_tcl_paths.patch17
-rw-r--r--pkgs/development/interpreters/python/pypy/default.nix (renamed from pkgs/development/interpreters/python/pypy/3/default.nix)113
-rw-r--r--pkgs/development/interpreters/python/pypy/prebuilt.nix123
-rw-r--r--pkgs/development/interpreters/python/pypy/tk_tcl_paths.patch (renamed from pkgs/development/interpreters/python/pypy/2.7/tk_tcl_paths.patch)0
-rw-r--r--pkgs/development/interpreters/python/wrap-python.nix3
-rw-r--r--pkgs/development/interpreters/python/wrap.sh12
-rw-r--r--pkgs/development/libraries/physics/geant4/g4py/default.nix2
-rw-r--r--pkgs/development/python-modules/cypari2/default.nix7
-rw-r--r--pkgs/development/python-modules/pyyaml/default.nix4
-rw-r--r--pkgs/development/python-modules/setuptools/default.nix11
-rw-r--r--pkgs/development/python-modules/tensorflow/bin.nix2
-rw-r--r--pkgs/tools/misc/calamares/default.nix4
-rw-r--r--pkgs/tools/networking/unbound/python.nix6
-rw-r--r--pkgs/top-level/all-packages.nix30
-rw-r--r--pkgs/top-level/python-packages.nix16
30 files changed, 530 insertions, 825 deletions
diff --git a/pkgs/applications/audio/ingen/default.nix b/pkgs/applications/audio/ingen/default.nix
index e10a25b8917..1e249b51fb7 100644
--- a/pkgs/applications/audio/ingen/default.nix
+++ b/pkgs/applications/audio/ingen/default.nix
@@ -31,7 +31,7 @@ stdenv.mkDerivation  rec {
     for program in ingenams ingenish
     do
       wrapProgram $out/bin/$program \
-        --prefix PYTHONPATH : $out/lib/python${python.majorVersion}/site-packages:$PYTHONPATH
+        --prefix PYTHONPATH : $out/${python.sitePackages}:$PYTHONPATH
     done
   '';
 
diff --git a/pkgs/applications/misc/blender/default.nix b/pkgs/applications/misc/blender/default.nix
index b9d4b83e4f1..340c08a958e 100644
--- a/pkgs/applications/misc/blender/default.nix
+++ b/pkgs/applications/misc/blender/default.nix
@@ -51,10 +51,10 @@ stdenv.mkDerivation rec {
       "-DWITH_SYSTEM_OPENJPEG=ON"
       "-DWITH_PLAYER=ON"
       "-DWITH_OPENSUBDIV=ON"
-      "-DPYTHON_LIBRARY=python${python.majorVersion}m"
+      "-DPYTHON_LIBRARY=${python.libPrefix}"
       "-DPYTHON_LIBPATH=${python}/lib"
-      "-DPYTHON_INCLUDE_DIR=${python}/include/python${python.majorVersion}m"
-      "-DPYTHON_VERSION=${python.majorVersion}"
+      "-DPYTHON_INCLUDE_DIR=${python}/include/${python.libPrefix}"
+      "-DPYTHON_VERSION=${python.pythonVersion}"
       "-DWITH_PYTHON_INSTALL=OFF"
       "-DWITH_PYTHON_INSTALL_NUMPY=OFF"
     ]
@@ -66,7 +66,7 @@ stdenv.mkDerivation rec {
       ]
     ++ optional colladaSupport "-DWITH_OPENCOLLADA=ON";
 
-  NIX_CFLAGS_COMPILE = "-I${ilmbase.dev}/include/OpenEXR -I${python}/include/${python.libPrefix}m";
+  NIX_CFLAGS_COMPILE = "-I${ilmbase.dev}/include/OpenEXR -I${python}/include/${python.libPrefix}";
 
   # Since some dependencies are built with gcc 6, we need gcc 6's
   # libstdc++ in our RPATH. Sigh.
@@ -77,7 +77,7 @@ stdenv.mkDerivation rec {
   postInstall = optionalString enableNumpy
     ''
       wrapProgram $out/bin/blender \
-        --prefix PYTHONPATH : ${pythonPackages.numpy}/lib/python${python.majorVersion}/site-packages
+        --prefix PYTHONPATH : ${pythonPackages.numpy}/${python.sitePackages}
     '';
 
   meta = with stdenv.lib; {
diff --git a/pkgs/applications/networking/instant-messengers/profanity/default.nix b/pkgs/applications/networking/instant-messengers/profanity/default.nix
index 327b02b2352..cf852ada369 100644
--- a/pkgs/applications/networking/instant-messengers/profanity/default.nix
+++ b/pkgs/applications/networking/instant-messengers/profanity/default.nix
@@ -62,7 +62,7 @@ stdenv.mkDerivation rec {
     ++ optionals pythonPluginSupport [ "-I${python}/include/${python.libPrefix}" ];
 
   LDFLAGS = [ ]
-    ++ optionals pythonPluginSupport [ "-L${python}/lib" "-lpython${python.majorVersion}m" ];
+    ++ optionals pythonPluginSupport [ "-L${python}/lib" "-l${python.libPrefix}" ];
 
   meta = {
     description = "A console based XMPP client";
diff --git a/pkgs/applications/science/misc/golly/beta.nix b/pkgs/applications/science/misc/golly/beta.nix
index 83b9c5a04a1..6f11caf4d9a 100644
--- a/pkgs/applications/science/misc/golly/beta.nix
+++ b/pkgs/applications/science/misc/golly/beta.nix
@@ -4,7 +4,7 @@
 }:
 
 stdenv.mkDerivation rec {
-  name = "golly-${version}";
+  pname = "golly";
   version = "2.8.99.2.20161122";
   #src = fetchurl {
   #  url="mirror://sourceforge/project/golly/golly/golly-2.8/golly-2.8-src.tar.gz";
@@ -30,7 +30,7 @@ stdenv.mkDerivation rec {
   makeFlags=[
     "AM_LDFLAGS="
   ];
-  NIX_LDFLAGS="-lpython${python2.majorVersion} -lperl";
+  NIX_LDFLAGS="-l${python2.libPrefix} -lperl";
   preConfigure=''
     export NIX_LDFLAGS="$NIX_LDFLAGS -L$(dirname "$(find ${perl} -name libperl.so)")"
     export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE
diff --git a/pkgs/applications/science/misc/golly/default.nix b/pkgs/applications/science/misc/golly/default.nix
index cfa4dca4b0d..74fa4cc02ed 100644
--- a/pkgs/applications/science/misc/golly/default.nix
+++ b/pkgs/applications/science/misc/golly/default.nix
@@ -1,8 +1,7 @@
 {stdenv, fetchurl, wxGTK, perl, python2, zlib, libGLU_combined, libX11}:
 stdenv.mkDerivation rec {
-  baseName="golly";
+  pname = "golly";
   version = "3.2";
-  name="${baseName}-${version}";
 
   src = fetchurl {
     sha256 = "0cg9mbwmf4q6qxhqlnzrxh9y047banxdb8pd3hgj3smmja2zf0jd";
@@ -21,7 +20,7 @@ stdenv.mkDerivation rec {
   makeFlags=[
     "AM_LDFLAGS="
   ];
-  NIX_LDFLAGS="-lpython${python2.majorVersion} -lperl";
+  NIX_LDFLAGS="-l${python2.libPrefix} -lperl";
   preConfigure=''
     export NIX_LDFLAGS="$NIX_LDFLAGS -L$(dirname "$(find ${perl} -name libperl.so)")"
     export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE
diff --git a/pkgs/development/interpreters/python/build-python-package-common.nix b/pkgs/development/interpreters/python/build-python-package-common.nix
index 2b383fe985d..0f8e088d434 100644
--- a/pkgs/development/interpreters/python/build-python-package-common.nix
+++ b/pkgs/development/interpreters/python/build-python-package-common.nix
@@ -1,7 +1,6 @@
 # This function provides generic bits to install a Python wheel.
 
 { python
-, bootstrapped-pip
 }:
 
 { buildInputs ? []
@@ -10,7 +9,7 @@
 , ... } @ attrs:
 
 attrs // {
-  buildInputs = buildInputs ++ [ bootstrapped-pip ];
+  buildInputs = buildInputs ++ [ python.pythonForBuild.pkgs.bootstrapped-pip ];
 
   configurePhase = attrs.configurePhase or ''
     runHook preConfigure
@@ -24,7 +23,7 @@ attrs // {
     export PYTHONPATH="$out/${python.sitePackages}:$PYTHONPATH"
 
     pushd dist
-    ${bootstrapped-pip}/bin/pip install *.whl --no-index --prefix=$out --no-cache ${toString installFlags} --build tmpbuild
+    ${python.pythonForBuild.pkgs.bootstrapped-pip}/bin/pip install *.whl --no-index --prefix=$out --no-cache ${toString installFlags} --build tmpbuild
     popd
 
     runHook postInstall
diff --git a/pkgs/development/interpreters/python/build-python-package-setuptools.nix b/pkgs/development/interpreters/python/build-python-package-setuptools.nix
index bc512357acd..4c66fdec5f6 100644
--- a/pkgs/development/interpreters/python/build-python-package-setuptools.nix
+++ b/pkgs/development/interpreters/python/build-python-package-setuptools.nix
@@ -2,7 +2,6 @@
 
 { lib
 , python
-, bootstrapped-pip
 }:
 
 {
@@ -26,13 +25,13 @@ in attrs // {
   buildPhase = attrs.buildPhase or ''
     runHook preBuild
     cp ${setuppy} nix_run_setup
-    ${python.interpreter} nix_run_setup ${lib.optionalString (setupPyBuildFlags != []) ("build_ext " + (lib.concatStringsSep " " setupPyBuildFlags))} bdist_wheel
+    ${python.pythonForBuild.interpreter} nix_run_setup ${lib.optionalString (setupPyBuildFlags != []) ("build_ext " + (lib.concatStringsSep " " setupPyBuildFlags))} bdist_wheel
     runHook postBuild
   '';
 
   installCheckPhase = attrs.checkPhase or ''
     runHook preCheck
-    ${python.interpreter} nix_run_setup test
+    ${python.pythonForBuild.interpreter} nix_run_setup test
     runHook postCheck
   '';
 
@@ -47,9 +46,9 @@ in attrs // {
     if test -e setup.py; then
       tmp_path=$(mktemp -d)
       export PATH="$tmp_path/bin:$PATH"
-      export PYTHONPATH="$tmp_path/${python.sitePackages}:$PYTHONPATH"
-      mkdir -p $tmp_path/${python.sitePackages}
-      ${bootstrapped-pip}/bin/pip install -e . --prefix $tmp_path >&2
+      export PYTHONPATH="$tmp_path/${python.pythonForBuild.sitePackages}:$PYTHONPATH"
+      mkdir -p $tmp_path/${python.pythonForBuild.sitePackages}
+      ${python.pythonForBuild.pkgs.bootstrapped-pip}/bin/pip install -e . --prefix $tmp_path >&2
     fi
     ${postShellHook}
   '';
diff --git a/pkgs/development/interpreters/python/build-python-package.nix b/pkgs/development/interpreters/python/build-python-package.nix
index 391086a662e..b664cf0b14f 100644
--- a/pkgs/development/interpreters/python/build-python-package.nix
+++ b/pkgs/development/interpreters/python/build-python-package.nix
@@ -10,17 +10,16 @@
 , ensureNewerSourcesForZipFilesHook
 , toPythonModule
 , namePrefix
-, bootstrapped-pip
 , flit
 , writeScript
 , update-python-libraries
 }:
 
 let
-  setuptools-specific = import ./build-python-package-setuptools.nix { inherit lib python bootstrapped-pip; };
+  setuptools-specific = import ./build-python-package-setuptools.nix { inherit lib python; };
   flit-specific = import ./build-python-package-flit.nix { inherit python flit; };
   wheel-specific = import ./build-python-package-wheel.nix { };
-  common = import ./build-python-package-common.nix { inherit python bootstrapped-pip; };
+  common = import ./build-python-package-common.nix { inherit python; };
   mkPythonDerivation = import ./mk-python-derivation.nix {
     inherit lib config python wrapPython setuptools unzip ensureNewerSourcesForZipFilesHook;
     inherit toPythonModule namePrefix writeScript update-python-libraries;
diff --git a/pkgs/development/interpreters/python/cpython/2.7/default.nix b/pkgs/development/interpreters/python/cpython/2.7/default.nix
index ff1497a24e4..249c4ac9cf7 100644
--- a/pkgs/development/interpreters/python/cpython/2.7/default.nix
+++ b/pkgs/development/interpreters/python/cpython/2.7/default.nix
@@ -1,7 +1,9 @@
-{ stdenv, buildPackages, fetchurl
+{ stdenv, fetchurl, fetchpatch
 , bzip2
+, expat
+, libffi
 , gdbm
-, fetchpatch
+, db
 , ncurses
 , openssl
 , readline
@@ -10,15 +12,16 @@
 , zlib
 , callPackage
 , self
-, db
-, expat
-, libffi
 , CF, configd, coreutils
 , python-setup-hook
 # Some proprietary libs assume UCS2 unicode, especially on darwin :(
 , ucsEncoding ? 4
 # For the Python package set
 , packageOverrides ? (self: super: {})
+, buildPackages
+, sourceVersion
+, sha256
+, passthruFun
 }:
 
 assert x11Support -> tcl != null
@@ -29,16 +32,26 @@ assert x11Support -> tcl != null
 with stdenv.lib;
 
 let
-  majorVersion = "2.7";
-  minorVersion = "15";
-  minorVersionSuffix = "";
-  version = "${majorVersion}.${minorVersion}${minorVersionSuffix}";
-  libPrefix = "python${majorVersion}";
-  sitePackages = "lib/${libPrefix}/site-packages";
+
+  pythonForBuild = buildPackages.${"python${sourceVersion.major}${sourceVersion.minor}"};
+
+  passthru = passthruFun rec {
+    inherit self sourceVersion packageOverrides;
+    implementation = "cpython";
+    libPrefix = "python${pythonVersion}";
+    executable = libPrefix;
+    pythonVersion = with sourceVersion; "${major}.${minor}";
+    sitePackages = "lib/${libPrefix}/site-packages";
+    inherit pythonForBuild;
+  } // {
+    inherit ucsEncoding;
+  };
+
+  version = with sourceVersion; "${major}.${minor}.${patch}${suffix}";
 
   src = fetchurl {
-    url = "https://www.python.org/ftp/python/${majorVersion}.${minorVersion}/Python-${version}.tar.xz";
-    sha256 = "0x2mvz9dp11wj7p5ccvmk9s0hzjk2fa1m462p395l4r6bfnb3n92";
+    url = with sourceVersion; "https://www.python.org/ftp/python/${major}.${minor}.${patch}/Python-${version}.tar.xz";
+    inherit sha256;
   };
 
   hasDistutilsCxxPatch = !(stdenv.cc.isGNU or false);
@@ -191,12 +204,11 @@ let
   # Build the basic Python interpreter without modules that have
   # external dependencies.
 
-in stdenv.mkDerivation ({
-    name = "python-${version}";
-    pythonVersion = majorVersion;
+in with passthru; stdenv.mkDerivation ({
+    pname = "python";
+    inherit version;
 
-    inherit majorVersion version src patches buildInputs nativeBuildInputs
-            preConfigure configureFlags;
+    inherit src patches buildInputs nativeBuildInputs preConfigure configureFlags;
 
     LDFLAGS = stdenv.lib.optionalString (!stdenv.isDarwin) "-lgcc_s";
     inherit (mkPaths buildInputs) C_INCLUDE_PATH LIBRARY_PATH;
@@ -215,7 +227,7 @@ in stdenv.mkDerivation ({
       ''
         # needed for some packages, especially packages that backport
         # functionality to 2.x from 3.x
-        for item in $out/lib/python${majorVersion}/test/*; do
+        for item in $out/lib/${libPrefix}/test/*; do
           if [[ "$item" != */test_support.py*
              && "$item" != */test/support
              && "$item" != */test/regrtest.py* ]]; then
@@ -224,9 +236,9 @@ in stdenv.mkDerivation ({
             echo $item
           fi
         done
-        touch $out/lib/python${majorVersion}/test/__init__.py
-        ln -s $out/lib/python${majorVersion}/pdb.py $out/bin/pdb
-        ln -s $out/lib/python${majorVersion}/pdb.py $out/bin/pdb${majorVersion}
+        touch $out/lib/${libPrefix}/test/__init__.py
+        ln -s $out/lib/${libPrefix}/pdb.py $out/bin/pdb
+        ln -s $out/lib/${libPrefix}/pdb.py $out/bin/pdb${sourceVersion.major}.${sourceVersion.minor}
         ln -s $out/share/man/man1/{python2.7.1.gz,python.1.gz}
 
         # Python on Nix is not manylinux1 compatible. https://github.com/NixOS/nixpkgs/issues/18484
@@ -249,21 +261,7 @@ in stdenv.mkDerivation ({
         cp libpython2.7.dll.a $out/lib
       '';
 
-    passthru = let
-      pythonPackages = callPackage ../../../../../top-level/python-packages.nix {
-        python = self;
-        overrides = packageOverrides;
-      };
-    in rec {
-      inherit libPrefix sitePackages x11Support hasDistutilsCxxPatch ucsEncoding;
-      executable = libPrefix;
-      buildEnv = callPackage ../../wrapper.nix { python = self; inherit (pythonPackages) requiredPythonModules; };
-      withPackages = import ../../with-packages.nix { inherit buildEnv pythonPackages;};
-      pkgs = pythonPackages;
-      isPy2 = true;
-      isPy27 = true;
-      interpreter = "${self}/bin/${executable}";
-    };
+    inherit passthru;
 
     enableParallelBuilding = true;
 
diff --git a/pkgs/development/interpreters/python/cpython/3.5/default.nix b/pkgs/development/interpreters/python/cpython/3.5/default.nix
deleted file mode 100644
index 19e9f3169c7..00000000000
--- a/pkgs/development/interpreters/python/cpython/3.5/default.nix
+++ /dev/null
@@ -1,212 +0,0 @@
-{ stdenv, fetchurl, fetchpatch
-, bzip2
-, expat
-, libffi
-, gdbm
-, lzma
-, ncurses
-, openssl
-, readline
-, sqlite
-, tcl ? null, tk ? null, tix ? null, libX11 ? null, xproto ? null, x11Support ? false
-, zlib
-, callPackage
-, self
-, CF, configd
-, python-setup-hook
-# For the Python package set
-, packageOverrides ? (self: super: {})
-}:
-
-assert x11Support -> tcl != null
-                  && tk != null
-                  && xproto != null
-                  && libX11 != null;
-
-with stdenv.lib;
-
-let
-  majorVersion = "3.5";
-  minorVersion = "6";
-  minorVersionSuffix = "";
-  version = "${majorVersion}.${minorVersion}${minorVersionSuffix}";
-  libPrefix = "python${majorVersion}";
-  sitePackages = "lib/${libPrefix}/site-packages";
-
-  buildInputs = filter (p: p != null) [
-    zlib bzip2 expat lzma libffi gdbm sqlite readline ncurses openssl ]
-    ++ optionals x11Support [ tcl tk libX11 xproto ]
-    ++ optionals stdenv.isDarwin [ CF configd ];
-
-  hasDistutilsCxxPatch = !(stdenv.cc.isGNU or false);
-
-in stdenv.mkDerivation {
-  name = "python3-${version}";
-  pythonVersion = majorVersion;
-  inherit majorVersion version;
-
-  inherit buildInputs;
-
-  src = fetchurl {
-    url = "https://www.python.org/ftp/python/${majorVersion}.${minorVersion}/Python-${version}.tar.xz";
-    sha256 = "0pqmf51zy2lzhbaj4yya2py2qr653j9152d0rg3p7wi1yl2dwp7m";
-  };
-
-  NIX_LDFLAGS = optionalString stdenv.isLinux "-lgcc_s";
-
-  # Determinism: The interpreter is patched to write null timestamps when compiling python files.
-  # This way python doesn't try to update them when we freeze timestamps in nix store.
-  DETERMINISTIC_BUILD=1;
-  # Determinism: We fix the hashes of str, bytes and datetime objects.
-  PYTHONHASHSEED=0;
-
-  prePatch = optionalString stdenv.isDarwin ''
-    substituteInPlace configure --replace '`/usr/bin/arch`' '"i386"'
-    substituteInPlace configure --replace '-Wl,-stack_size,1000000' ' '
-  '';
-
-  patches = [
-    ./no-ldconfig.patch
-    ./ld_library_path.patch
-  ] ++ optionals stdenv.isDarwin [
-    # Fix for https://bugs.python.org/issue24658
-    (fetchpatch {
-      url = "https://bugs.python.org/file45178/issue24658-3-3.6.diff";
-      sha256 = "1x060hs80nl34mcl2ji2i7l4shxkmxwgq8h8lcmav8rjqqz1nb4a";
-    })
-  ] ++ optionals (x11Support && stdenv.isDarwin) [
-    ./use-correct-tcl-tk-on-darwin.patch
-  ] ++ optionals hasDistutilsCxxPatch [
-    # Fix for http://bugs.python.org/issue1222585
-    # Upstream distutils is calling C compiler to compile C++ code, which
-    # only works for GCC and Apple Clang. This makes distutils to call C++
-    # compiler when needed.
-    (fetchpatch {
-      url = "https://bugs.python.org/file47046/python-3.x-distutils-C++.patch";
-      sha256 = "0dgdn9k2kmw4wh90vdnjcrnn97ylxgx7mbn9l87fwz6j501jqvk8";
-      extraPrefix = "";
-    })
-  ];
-
-  postPatch = ''
-    # Determinism
-    substituteInPlace "Lib/py_compile.py" --replace "source_stats['mtime']" "(1 if 'DETERMINISTIC_BUILD' in os.environ else source_stats['mtime'])"
-    # Determinism. This is done unconditionally
-    substituteInPlace "Lib/importlib/_bootstrap_external.py" --replace "source_mtime = int(st['mtime'])" "source_mtime = 1"
-  '' + optionalString (x11Support && (tix != null)) ''
-    substituteInPlace "Lib/tkinter/tix.py" --replace "os.environ.get('TIX_LIBRARY')" "os.environ.get('TIX_LIBRARY') or '${tix}/lib'"
-  '';
-
-  CPPFLAGS="${concatStringsSep " " (map (p: "-I${getDev p}/include") buildInputs)}";
-  LDFLAGS="${concatStringsSep " " (map (p: "-L${getLib p}/lib") buildInputs)}";
-  LIBS="${optionalString (!stdenv.isDarwin) "-lcrypt"} ${optionalString (ncurses != null) "-lncurses"}";
-
-  configureFlags = [
-    "--enable-shared"
-    "--with-threads"
-    "--without-ensurepip"
-    "--with-system-expat"
-    "--with-system-ffi"
-  ]
-    # Never even try to use lchmod on linux,
-    # don't rely on detecting glibc-isms.
-  ++ optional stdenv.hostPlatform.isLinux "ac_cv_func_lchmod=no";
-
-  preConfigure = ''
-    for i in /usr /sw /opt /pkg; do	# improve purity
-      substituteInPlace ./setup.py --replace $i /no-such-path
-    done
-    ${optionalString stdenv.isDarwin ''
-       export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -msse2"
-       export MACOSX_DEPLOYMENT_TARGET=10.6
-     ''
-     + optionalString stdenv.hostPlatform.isMusl ''
-      export NIX_CFLAGS_COMPILE+=" -DTHREAD_STACK_SIZE=0x100000"
-     ''}
-  '';
-
-  setupHook = python-setup-hook sitePackages;
-
-  postInstall = ''
-    # needed for some packages, especially packages that backport functionality
-    # to 2.x from 3.x
-    for item in $out/lib/python${majorVersion}/test/*; do
-      if [[ "$item" != */test_support.py*
-         && "$item" != */test/support
-         && "$item" != */test/libregrtest
-         && "$item" != */test/regrtest.py* ]]; then
-        rm -rf "$item"
-      else
-        echo $item
-      fi
-    done
-    touch $out/lib/python${majorVersion}/test/__init__.py
-
-    ln -s "$out/include/python${majorVersion}m" "$out/include/python${majorVersion}"
-
-    # Python on Nix is not manylinux1 compatible. https://github.com/NixOS/nixpkgs/issues/18484
-    echo "manylinux1_compatible=False" >> $out/lib/${libPrefix}/_manylinux.py
-
-    # Determinism: Windows installers were not deterministic.
-    # We're also not interested in building Windows installers.
-    find "$out" -name 'wininst*.exe' | xargs -r rm -f
-
-    # Use Python3 as default python
-    ln -s "$out/bin/idle3" "$out/bin/idle"
-    ln -s "$out/bin/pydoc3" "$out/bin/pydoc"
-    ln -s "$out/bin/python3" "$out/bin/python"
-    ln -s "$out/bin/python3-config" "$out/bin/python-config"
-    ln -s "$out/lib/pkgconfig/python3.pc" "$out/lib/pkgconfig/python.pc"
-
-    # Get rid of retained dependencies on -dev packages, and remove
-    # some $TMPDIR references to improve binary reproducibility.
-    # Note that the .pyc file of _sysconfigdata.py should be regenerated!
-    for i in $out/lib/python${majorVersion}/_sysconfigdata.py $out/lib/python${majorVersion}/config-${majorVersion}m/Makefile; do
-      sed -i $i -e "s|-I/nix/store/[^ ']*||g" -e "s|-L/nix/store/[^ ']*||g" -e "s|$TMPDIR|/no-such-path|g"
-    done
-
-    # Determinism: rebuild all bytecode
-    # We exclude lib2to3 because that's Python 2 code which fails
-    # We rebuild three times, once for each optimization level
-    find $out -name "*.py" | $out/bin/python -m compileall -q -f -x "lib2to3" -i -
-    find $out -name "*.py" | $out/bin/python -O -m compileall -q -f -x "lib2to3" -i -
-    find $out -name "*.py" | $out/bin/python -OO -m compileall -q -f -x "lib2to3" -i -
-  '';
-
-  passthru = let
-    pythonPackages = callPackage ../../../../../top-level/python-packages.nix {
-      python = self;
-      overrides = packageOverrides;
-    };
-  in rec {
-    inherit libPrefix sitePackages x11Support hasDistutilsCxxPatch;
-    executable = "${libPrefix}m";
-    buildEnv = callPackage ../../wrapper.nix { python = self; inherit (pythonPackages) requiredPythonModules; };
-    withPackages = import ../../with-packages.nix { inherit buildEnv pythonPackages;};
-    pkgs = pythonPackages;
-    isPy3 = true;
-    isPy35 = true;
-    interpreter = "${self}/bin/${executable}";
-  };
-
-  enableParallelBuilding = true;
-
-  doCheck = false; # expensive, and fails
-
-  meta = {
-    homepage = http://python.org;
-    description = "A high-level dynamically-typed programming language";
-    longDescription = ''
-      Python is a remarkably powerful dynamic programming language that
-      is used in a wide variety of application domains. Some of its key
-      distinguishing features include: clear, readable syntax; strong
-      introspection capabilities; intuitive object orientation; natural
-      expression of procedural code; full modularity, supporting
-      hierarchical packages; exception-based error handling; and very
-      high level dynamic data types.
-    '';
-    license = licenses.psfl;
-    platforms = with platforms; linux ++ darwin;
-    maintainers = with maintainers; [ fridh ];
-  };
-}
diff --git a/pkgs/development/interpreters/python/cpython/3.6/default.nix b/pkgs/development/interpreters/python/cpython/3.6/default.nix
deleted file mode 100644
index a36965a7801..00000000000
--- a/pkgs/development/interpreters/python/cpython/3.6/default.nix
+++ /dev/null
@@ -1,228 +0,0 @@
-{ stdenv, fetchurl, fetchpatch, buildPackages
-, bzip2
-, expat
-, libffi
-, gdbm
-, lzma
-, ncurses
-, openssl
-, readline
-, sqlite
-, tcl ? null, tk ? null, tix ? null, libX11 ? null, xproto ? null, x11Support ? false
-, zlib
-, callPackage
-, self
-, CF, configd
-, python-setup-hook
-# For the Python package set
-, packageOverrides ? (self: super: {})
-}:
-
-assert x11Support -> tcl != null
-                  && tk != null
-                  && xproto != null
-                  && libX11 != null;
-with stdenv.lib;
-
-let
-  majorVersion = "3.6";
-  minorVersion = "8";
-  minorVersionSuffix = "";
-  version = "${majorVersion}.${minorVersion}${minorVersionSuffix}";
-  libPrefix = "python${majorVersion}";
-  sitePackages = "lib/${libPrefix}/site-packages";
-
-  buildInputs = filter (p: p != null) [
-    zlib bzip2 expat lzma libffi gdbm sqlite readline ncurses openssl ]
-    ++ optionals x11Support [ tcl tk libX11 xproto ]
-    ++ optionals stdenv.isDarwin [ CF configd ];
-
-  nativeBuildInputs =
-    optional (stdenv.hostPlatform != stdenv.buildPlatform) buildPackages.python3;
-
-  hasDistutilsCxxPatch = !(stdenv.cc.isGNU or false);
-
-in stdenv.mkDerivation {
-  name = "python3-${version}";
-  pythonVersion = majorVersion;
-  inherit majorVersion version;
-
-  inherit buildInputs nativeBuildInputs;
-
-  src = fetchurl {
-    url = "https://www.python.org/ftp/python/${majorVersion}.${minorVersion}/Python-${version}.tar.xz";
-    sha256 = "14qi6n5gpcjnwy165wi9hkfcmbadc95ny6bxxldknxwmx50n4i1m";
-  };
-
-  NIX_LDFLAGS = optionalString stdenv.isLinux "-lgcc_s";
-
-  # Determinism: The interpreter is patched to write null timestamps when compiling python files.
-  # This way python doesn't try to update them when we freeze timestamps in nix store.
-  DETERMINISTIC_BUILD=1;
-  # Determinism: We fix the hashes of str, bytes and datetime objects.
-  PYTHONHASHSEED=0;
-
-  prePatch = optionalString stdenv.isDarwin ''
-    substituteInPlace configure --replace '`/usr/bin/arch`' '"i386"'
-    substituteInPlace configure --replace '-Wl,-stack_size,1000000' ' '
-  '';
-
-  patches = [
-    ./no-ldconfig.patch
-  ] ++ optionals (x11Support && stdenv.isDarwin) [
-    ./use-correct-tcl-tk-on-darwin.patch
-  ] ++ optionals hasDistutilsCxxPatch [
-    # Fix for http://bugs.python.org/issue1222585
-    # Upstream distutils is calling C compiler to compile C++ code, which
-    # only works for GCC and Apple Clang. This makes distutils to call C++
-    # compiler when needed.
-    (fetchpatch {
-      url = "https://bugs.python.org/file48016/python-3.x-distutils-C++.patch";
-      sha256 = "1h18lnpx539h5lfxyk379dxwr8m2raigcjixkf133l4xy3f4bzi2";
-    })
-  ];
-
-  postPatch = ''
-    # Determinism
-    substituteInPlace "Lib/py_compile.py" --replace "source_stats['mtime']" "(1 if 'DETERMINISTIC_BUILD' in os.environ else source_stats['mtime'])"
-    # Determinism. This is done unconditionally
-    substituteInPlace "Lib/importlib/_bootstrap_external.py" --replace "source_mtime = int(st['mtime'])" "source_mtime = 1"
-  '' + optionalString (x11Support && (tix != null)) ''
-    substituteInPlace "Lib/tkinter/tix.py" --replace "os.environ.get('TIX_LIBRARY')" "os.environ.get('TIX_LIBRARY') or '${tix}/lib'"
-  '';
-
-  CPPFLAGS="${concatStringsSep " " (map (p: "-I${getDev p}/include") buildInputs)}";
-  LDFLAGS="${concatStringsSep " " (map (p: "-L${getLib p}/lib") buildInputs)}";
-  LIBS="${optionalString (!stdenv.isDarwin) "-lcrypt"} ${optionalString (ncurses != null) "-lncurses"}";
-
-  configureFlags = [
-    "--enable-shared"
-    "--with-threads"
-    "--without-ensurepip"
-    "--with-system-expat"
-    "--with-system-ffi"
-  ] ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
-    "ac_cv_buggy_getaddrinfo=no"
-    # Assume little-endian IEEE 754 floating point when cross compiling
-    "ac_cv_little_endian_double=yes"
-    "ac_cv_big_endian_double=no"
-    "ac_cv_mixed_endian_double=no"
-    "ac_cv_x87_double_rounding=yes"
-    "ac_cv_tanh_preserves_zero_sign=yes"
-    # Generally assume that things are present and work
-    "ac_cv_posix_semaphores_enabled=yes"
-    "ac_cv_broken_sem_getvalue=no"
-    "ac_cv_wchar_t_signed=yes"
-    "ac_cv_rshift_extends_sign=yes"
-    "ac_cv_broken_nice=no"
-    "ac_cv_broken_poll=no"
-    "ac_cv_working_tzset=yes"
-    "ac_cv_have_long_long_format=yes"
-    "ac_cv_have_size_t_format=yes"
-    "ac_cv_computed_gotos=yes"
-    "ac_cv_file__dev_ptmx=yes"
-    "ac_cv_file__dev_ptc=yes"
-  ]
-    # Never even try to use lchmod on linux,
-    # don't rely on detecting glibc-isms.
-  ++ optional stdenv.hostPlatform.isLinux "ac_cv_func_lchmod=no";
-
-  preConfigure = ''
-    for i in /usr /sw /opt /pkg; do	# improve purity
-      substituteInPlace ./setup.py --replace $i /no-such-path
-    done
-    ${optionalString stdenv.isDarwin ''
-       export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -msse2"
-       export MACOSX_DEPLOYMENT_TARGET=10.6
-     ''
-     + optionalString stdenv.hostPlatform.isMusl ''
-      export NIX_CFLAGS_COMPILE+=" -DTHREAD_STACK_SIZE=0x100000"
-     ''}
-  '';
-
-  setupHook = python-setup-hook sitePackages;
-
-  postInstall = ''
-    # needed for some packages, especially packages that backport functionality
-    # to 2.x from 3.x
-    for item in $out/lib/python${majorVersion}/test/*; do
-      if [[ "$item" != */test_support.py*
-         && "$item" != */test/support
-         && "$item" != */test/libregrtest
-         && "$item" != */test/regrtest.py* ]]; then
-        rm -rf "$item"
-      else
-        echo $item
-      fi
-    done
-    touch $out/lib/python${majorVersion}/test/__init__.py
-
-    ln -s "$out/include/python${majorVersion}m" "$out/include/python${majorVersion}"
-
-    # Python on Nix is not manylinux1 compatible. https://github.com/NixOS/nixpkgs/issues/18484
-    echo "manylinux1_compatible=False" >> $out/lib/${libPrefix}/_manylinux.py
-
-    # Determinism: Windows installers were not deterministic.
-    # We're also not interested in building Windows installers.
-    find "$out" -name 'wininst*.exe' | xargs -r rm -f
-
-    # Use Python3 as default python
-    ln -s "$out/bin/idle3" "$out/bin/idle"
-    ln -s "$out/bin/pydoc3" "$out/bin/pydoc"
-    ln -s "$out/bin/python3" "$out/bin/python"
-    ln -s "$out/bin/python3-config" "$out/bin/python-config"
-    ln -s "$out/lib/pkgconfig/python3.pc" "$out/lib/pkgconfig/python.pc"
-
-    # Get rid of retained dependencies on -dev packages, and remove
-    # some $TMPDIR references to improve binary reproducibility.
-    # Note that the .pyc file of _sysconfigdata.py should be regenerated!
-    for i in $out/lib/python${majorVersion}/_sysconfigdata*.py $out/lib/python${majorVersion}/config-${majorVersion}m*/Makefile; do
-      sed -i $i -e "s|-I/nix/store/[^ ']*||g" -e "s|-L/nix/store/[^ ']*||g" -e "s|$TMPDIR|/no-such-path|g"
-    done
-  '' + optionalString (stdenv.hostPlatform == stdenv.buildPlatform) ''
-    # Determinism: rebuild all bytecode
-    # We exclude lib2to3 because that's Python 2 code which fails
-    # We rebuild three times, once for each optimization level
-    find $out -name "*.py" | $out/bin/python -m compileall -q -f -x "lib2to3" -i -
-    find $out -name "*.py" | $out/bin/python -O -m compileall -q -f -x "lib2to3" -i -
-    find $out -name "*.py" | $out/bin/python -OO -m compileall -q -f -x "lib2to3" -i -
-  '';
-
-  passthru = let
-    pythonPackages = callPackage ../../../../../top-level/python-packages.nix {
-      python = self;
-      overrides = packageOverrides;
-    };
-  in rec {
-    inherit libPrefix sitePackages x11Support hasDistutilsCxxPatch;
-    executable = "${libPrefix}m";
-    buildEnv = callPackage ../../wrapper.nix { python = self; inherit (pythonPackages) requiredPythonModules; };
-    withPackages = import ../../with-packages.nix { inherit buildEnv pythonPackages;};
-    pkgs = pythonPackages;
-    isPy3 = true;
-    isPy36 = true;
-    is_py3k = true;  # deprecated
-    interpreter = "${self}/bin/${executable}";
-  };
-
-  enableParallelBuilding = true;
-
-  doCheck = false; # expensive, and fails
-
-  meta = {
-    homepage = http://python.org;
-    description = "A high-level dynamically-typed programming language";
-    longDescription = ''
-      Python is a remarkably powerful dynamic programming language that
-      is used in a wide variety of application domains. Some of its key
-      distinguishing features include: clear, readable syntax; strong
-      introspection capabilities; intuitive object orientation; natural
-      expression of procedural code; full modularity, supporting
-      hierarchical packages; exception-based error handling; and very
-      high level dynamic data types.
-    '';
-    license = licenses.psfl;
-    platforms = with platforms; linux ++ darwin;
-    maintainers = with maintainers; [ fridh kragniz ];
-  };
-}
diff --git a/pkgs/development/interpreters/python/cpython/3.7/default.nix b/pkgs/development/interpreters/python/cpython/default.nix
index 61ffa8ec5a4..6e738a598dc 100644
--- a/pkgs/development/interpreters/python/cpython/3.7/default.nix
+++ b/pkgs/development/interpreters/python/cpython/default.nix
@@ -18,6 +18,10 @@
 # For the Python package set
 , packageOverrides ? (self: super: {})
 , buildPackages
+, sourceVersion
+, sha256
+, passthruFun
+, bash
 }:
 
 assert x11Support -> tcl != null
@@ -27,12 +31,25 @@ assert x11Support -> tcl != null
 with stdenv.lib;
 
 let
-  majorVersion = "3.7";
-  minorVersion = "2";
-  minorVersionSuffix = "";
-  version = "${majorVersion}.${minorVersion}${minorVersionSuffix}";
-  libPrefix = "python${majorVersion}";
-  sitePackages = "lib/${libPrefix}/site-packages";
+
+  passthru = passthruFun rec {
+    inherit self sourceVersion packageOverrides;
+    implementation = "cpython";
+    libPrefix = "python${pythonVersion}";
+    executable = libPrefix;
+    pythonVersion = with sourceVersion; "${major}.${minor}";
+    sitePackages = "lib/${libPrefix}/site-packages";
+    inherit pythonForBuild;
+  };
+
+  version = with sourceVersion; "${major}.${minor}.${patch}${suffix}";
+
+  nativeBuildInputs = [
+    nukeReferences
+  ] ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
+    buildPackages.stdenv.cc
+    pythonForBuild
+  ];
 
   buildInputs = filter (p: p != null) [
     zlib bzip2 expat lzma libffi gdbm sqlite readline ncurses openssl ]
@@ -40,44 +57,46 @@ let
     ++ optionals stdenv.isDarwin [ CF configd ];
 
   hasDistutilsCxxPatch = !(stdenv.cc.isGNU or false);
-  pythonForBuild = if stdenv.hostPlatform == stdenv.buildPlatform then
+
+  pythonForBuild = buildPackages.${"python${sourceVersion.major}${sourceVersion.minor}"};
+
+  pythonForBuildInterpreter = if stdenv.hostPlatform == stdenv.buildPlatform then
     "$out/bin/python"
-  else
-    buildPackages.python37.interpreter;
-in stdenv.mkDerivation {
-  name = "python3-${version}";
-  pythonVersion = majorVersion;
-  inherit majorVersion version;
+  else pythonForBuild.interpreter;
 
-  inherit buildInputs;
+in with passthru; stdenv.mkDerivation {
+  pname = "python3";
+  inherit version;
 
-  nativeBuildInputs = [ nukeReferences ] ++
-    optionals (stdenv.hostPlatform != stdenv.buildPlatform)
-    [ buildPackages.stdenv.cc buildPackages.python37 ];
+  inherit buildInputs nativeBuildInputs;
 
   src = fetchurl {
-    url = "https://www.python.org/ftp/python/${majorVersion}.${minorVersion}/Python-${version}.tar.xz";
-    sha256 = "1fzi9d2gibh0wzwidyckzbywsxcsbckgsl05ryxlifxia77fhgyq";
+    url = with sourceVersion; "https://www.python.org/ftp/python/${major}.${minor}.${patch}/Python-${version}.tar.xz";
+    inherit sha256;
   };
 
-  NIX_LDFLAGS = optionalString stdenv.isLinux "-lgcc_s";
-
-  # Determinism: We fix the hashes of str, bytes and datetime objects.
-  PYTHONHASHSEED=0;
-
   prePatch = optionalString stdenv.isDarwin ''
     substituteInPlace configure --replace '`/usr/bin/arch`' '"i386"'
     substituteInPlace configure --replace '-Wl,-stack_size,1000000' ' '
   '';
 
   patches = [
-    ./no-ldconfig.patch
+    # Disable the use of ldconfig in ctypes.util.find_library (since
+    # ldconfig doesn't work on NixOS), and don't use
+    # ctypes.util.find_library during the loading of the uuid module
+    # (since it will do a futile invocation of gcc (!) to find
+    # libuuid, slowing down program startup a lot).
+    (./. + "/${sourceVersion.major}.${sourceVersion.minor}/no-ldconfig.patch")
+  ] ++ optionals isPy35 [
+    # Backports support for LD_LIBRARY_PATH from 3.6
+    ./3.5/ld_library_path.patch
+  ] ++ optionals isPy37 [
     # Fix darwin build https://bugs.python.org/issue34027
     (fetchpatch {
       url = https://bugs.python.org/file47666/darwin-libutil.patch;
       sha256 = "0242gihnw3wfskl4fydp2xanpl8k5q7fj4dp7dbbqf46a4iwdzpa";
     })
-  ] ++ optionals hasDistutilsCxxPatch [
+  ] ++ optionals (isPy3k && hasDistutilsCxxPatch) [
     # Fix for http://bugs.python.org/issue1222585
     # Upstream distutils is calling C compiler to compile C++ code, which
     # only works for GCC and Apple Clang. This makes distutils to call C++
@@ -93,9 +112,12 @@ in stdenv.mkDerivation {
     substituteInPlace "Lib/tkinter/tix.py" --replace "os.environ.get('TIX_LIBRARY')" "os.environ.get('TIX_LIBRARY') or '${tix}/lib'"
   '';
 
-  CPPFLAGS="${concatStringsSep " " (map (p: "-I${getDev p}/include") buildInputs)}";
-  LDFLAGS="${concatStringsSep " " (map (p: "-L${getLib p}/lib") buildInputs)}";
-  LIBS="${optionalString (!stdenv.isDarwin) "-lcrypt"} ${optionalString (ncurses != null) "-lncurses"}";
+  CPPFLAGS = "${concatStringsSep " " (map (p: "-I${getDev p}/include") buildInputs)}";
+  LDFLAGS = "${concatStringsSep " " (map (p: "-L${getLib p}/lib") buildInputs)}";
+  LIBS = "${optionalString (!stdenv.isDarwin) "-lcrypt"} ${optionalString (ncurses != null) "-lncurses"}";
+  NIX_LDFLAGS = optionalString stdenv.isLinux "-lgcc_s";
+  # Determinism: We fix the hashes of str, bytes and datetime objects.
+  PYTHONHASHSEED=0;
 
   configureFlags = [
     "--enable-shared"
@@ -125,16 +147,25 @@ in stdenv.mkDerivation {
     "ac_cv_computed_gotos=yes"
     "ac_cv_file__dev_ptmx=yes"
     "ac_cv_file__dev_ptc=yes"
+  ] ++ optionals stdenv.hostPlatform.isLinux [
+    # Never even try to use lchmod on linux,
+    # don't rely on detecting glibc-isms.
+    "ac_cv_func_lchmod=no"
   ];
 
   preConfigure = ''
     for i in /usr /sw /opt /pkg; do	# improve purity
       substituteInPlace ./setup.py --replace $i /no-such-path
     done
-    ${optionalString stdenv.isDarwin ''
-       export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -msse2"
-       export MACOSX_DEPLOYMENT_TARGET=10.6
-     ''}
+  '' + optionalString stdenv.isDarwin ''
+    export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -msse2"
+    export MACOSX_DEPLOYMENT_TARGET=10.6
+  '' + optionalString (isPy3k && pythonOlder "3.7") ''
+    # Determinism: The interpreter is patched to write null timestamps when compiling python files.
+    # This way python does not try to update them when we freeze timestamps in nix store.
+    export DETERMINISTIC_BUILD=1;
+  '' + optionalString stdenv.hostPlatform.isMusl ''
+    export NIX_CFLAGS_COMPILE+=" -DTHREAD_STACK_SIZE=0x100000"
   '';
 
   setupHook = python-setup-hook sitePackages;
@@ -142,7 +173,7 @@ in stdenv.mkDerivation {
   postInstall = ''
     # needed for some packages, especially packages that backport functionality
     # to 2.x from 3.x
-    for item in $out/lib/python${majorVersion}/test/*; do
+    for item in $out/lib/${libPrefix}/test/*; do
       if [[ "$item" != */test_support.py*
          && "$item" != */test/support
          && "$item" != */test/libregrtest
@@ -152,9 +183,9 @@ in stdenv.mkDerivation {
         echo $item
       fi
     done
-    touch $out/lib/python${majorVersion}/test/__init__.py
+    touch $out/lib/${libPrefix}/test/__init__.py
 
-    ln -s "$out/include/python${majorVersion}m" "$out/include/python${majorVersion}"
+    ln -s "$out/include/${executable}m" "$out/include/${executable}"
 
     # Python on Nix is not manylinux1 compatible. https://github.com/NixOS/nixpkgs/issues/18484
     echo "manylinux1_compatible=False" >> $out/lib/${libPrefix}/_manylinux.py
@@ -173,45 +204,40 @@ in stdenv.mkDerivation {
     # Get rid of retained dependencies on -dev packages, and remove
     # some $TMPDIR references to improve binary reproducibility.
     # Note that the .pyc file of _sysconfigdata.py should be regenerated!
-    for i in $out/lib/python${majorVersion}/_sysconfigdata*.py $out/lib/python${majorVersion}/config-${majorVersion}m*/Makefile; do
-      sed -i $i -e "s|$TMPDIR|/no-such-path|g"
-      nuke-refs $i
+    for i in $out/lib/${libPrefix}/_sysconfigdata*.py $out/lib/${libPrefix}/config-${sourceVersion.major}${sourceVersion.minor}*/Makefile; do
+       sed -i $i -e "s|$TMPDIR|/no-such-path|g"
     done
 
     # Further get rid of references. https://github.com/NixOS/nixpkgs/issues/51668
-    find $out/lib/python*/config-*-* -type f -print -exec nuke-refs '{}' +
-    find $out/lib -name '_sysconfigdata_m*.py*' -print -exec nuke-refs '{}' +
+    find $out/lib/python*/config-* -type f -print -exec nuke-refs '{}' +
+    find $out/lib -name '_sysconfigdata*.py*' -print -exec nuke-refs '{}' +
 
     # Determinism: rebuild all bytecode
     # We exclude lib2to3 because that's Python 2 code which fails
     # We rebuild three times, once for each optimization level
     # Python 3.7 implements PEP 552, introducing support for deterministic bytecode.
     # This is automatically used when `SOURCE_DATE_EPOCH` is set.
-    find $out -name "*.py" | ${pythonForBuild}     -m compileall -q -f -x "lib2to3" -i -
-    find $out -name "*.py" | ${pythonForBuild} -O  -m compileall -q -f -x "lib2to3" -i -
-    find $out -name "*.py" | ${pythonForBuild} -OO -m compileall -q -f -x "lib2to3" -i -
+    find $out -name "*.py" | ${pythonForBuildInterpreter}     -m compileall -q -f -x "lib2to3" -i -
+    find $out -name "*.py" | ${pythonForBuildInterpreter} -O  -m compileall -q -f -x "lib2to3" -i -
+    find $out -name "*.py" | ${pythonForBuildInterpreter} -OO -m compileall -q -f -x "lib2to3" -i -
+  '';
+
+  preFixup = stdenv.lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
+    # Ensure patch-shebangs uses shebangs of host interpreter.
+    export PATH=${stdenv.lib.makeBinPath [ "$out" bash ]}:$PATH
   '';
 
   # Enforce that we don't have references to the OpenSSL -dev package, which we
   # explicitly specify in our configure flags above.
-  disallowedReferences = [ openssl.dev ];
-
-  passthru = let
-    pythonPackages = callPackage ../../../../../top-level/python-packages.nix {
-      python = self;
-      overrides = packageOverrides;
-    };
-  in rec {
-    inherit libPrefix sitePackages x11Support hasDistutilsCxxPatch;
-    executable = "${libPrefix}m";
-    buildEnv = callPackage ../../wrapper.nix { python = self; inherit (pythonPackages) requiredPythonModules; };
-    withPackages = import ../../with-packages.nix { inherit buildEnv pythonPackages;};
-    pkgs = pythonPackages;
-    isPy3 = true;
-    isPy37 = true;
-    is_py3k = true;  # deprecated
-    interpreter = "${self}/bin/${executable}";
-  };
+  disallowedReferences = [
+    openssl.dev
+  ] ++ stdenv.lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
+    # Ensure we don't have references to build-time packages.
+    # These typically end up in shebangs.
+    pythonForBuild buildPackages.bash
+  ];
+
+  inherit passthru;
 
   enableParallelBuilding = true;
 
@@ -229,6 +255,6 @@ in stdenv.mkDerivation {
     '';
     license = licenses.psfl;
     platforms = with platforms; linux ++ darwin;
-    maintainers = with maintainers; [ fridh kragniz ];
+    maintainers = with maintainers; [ fridh ];
   };
 }
diff --git a/pkgs/development/interpreters/python/default.nix b/pkgs/development/interpreters/python/default.nix
new file mode 100644
index 00000000000..bb5c3b3a97f
--- /dev/null
+++ b/pkgs/development/interpreters/python/default.nix
@@ -0,0 +1,154 @@
+{ pkgs, lib }:
+
+with pkgs;
+
+(let
+
+  # Common passthru for all Python interpreters.
+  passthruFun =
+    { implementation
+    , libPrefix
+    , executable
+    , sourceVersion
+    , pythonVersion
+    , packageOverrides
+    , sitePackages
+    , pythonForBuild
+    , self
+    }: let
+      pythonPackages = callPackage ../../../top-level/python-packages.nix {
+        python = self;
+        overrides = packageOverrides;
+      };
+    in rec {
+        isPy27 = pythonVersion == "2.7";
+        isPy33 = pythonVersion == "3.3"; # TODO: remove
+        isPy34 = pythonVersion == "3.4"; # TODO: remove
+        isPy35 = pythonVersion == "3.5";
+        isPy36 = pythonVersion == "3.6";
+        isPy37 = pythonVersion == "3.7";
+        isPy3k = lib.strings.substring 0 1 pythonVersion == "3";
+        isPyPy = interpreter == "pypy";
+
+        buildEnv = callPackage ./wrapper.nix { python = self; inherit (pythonPackages) requiredPythonModules; };
+        withPackages = import ./with-packages.nix { inherit buildEnv pythonPackages;};
+        pkgs = pythonPackages;
+        interpreter = "${self}/bin/${executable}";
+        inherit executable implementation libPrefix pythonVersion sitePackages;
+        inherit sourceVersion;
+        pythonAtLeast = lib.versionAtLeast pythonVersion;
+        pythonOlder = lib.versionOlder pythonVersion;
+        inherit pythonForBuild;
+  };
+
+in {
+
+  python27 = callPackage ./cpython/2.7 {
+    self = python27;
+    sourceVersion = {
+      major = "2";
+      minor = "7";
+      patch = "15";
+      suffix = "";
+    };
+    sha256 = "0x2mvz9dp11wj7p5ccvmk9s0hzjk2fa1m462p395l4r6bfnb3n92";
+    inherit (darwin) CF configd;
+    inherit passthruFun;
+  };
+
+  python35 = callPackage ./cpython {
+    self = python35;
+    sourceVersion = {
+      major = "3";
+      minor = "5";
+      patch = "6";
+      suffix = "";
+    };
+    sha256 = "0pqmf51zy2lzhbaj4yya2py2qr653j9152d0rg3p7wi1yl2dwp7m";
+    inherit (darwin) CF configd;
+    inherit passthruFun;
+  };
+
+  python36 = callPackage ./cpython {
+    self = python36;
+    sourceVersion = {
+      major = "3";
+      minor = "6";
+      patch = "8";
+      suffix = "";
+    };
+    sha256 = "14qi6n5gpcjnwy165wi9hkfcmbadc95ny6bxxldknxwmx50n4i1m";
+    inherit (darwin) CF configd;
+    inherit passthruFun;
+  };
+
+  python37 = callPackage ./cpython {
+    self = python37;
+    sourceVersion = {
+      major = "3";
+      minor = "7";
+      patch = "2";
+      suffix = "";
+    };
+    sha256 = "1fzi9d2gibh0wzwidyckzbywsxcsbckgsl05ryxlifxia77fhgyq";
+    inherit (darwin) CF configd;
+    inherit passthruFun;
+  };
+
+  pypy27 = callPackage ./pypy {
+    self = pypy27;
+    sourceVersion = {
+      major = "6";
+      minor = "0";
+      patch = "0";
+    };
+    sha256 = "1qjwpc8n68sxxlfg36s5vn1h2gdfvvd6lxvr4lzbvfwhzrgqahsw";
+    pythonVersion = "2.7";
+    db = db.override { dbmSupport = true; };
+    python = python27;
+    inherit passthruFun;
+  };
+
+  pypy35 = callPackage ./pypy {
+    self = pypy35;
+    sourceVersion = {
+      major = "6";
+      minor = "0";
+      patch = "0";
+    };
+    sha256 = "0lwq8nn0r5yj01bwmkk5p7xvvrp4s550l8184mkmn74d3gphrlwg";
+    pythonVersion = "3.5";
+    db = db.override { dbmSupport = true; };
+    python = python27;
+    inherit passthruFun;
+  };
+
+  pypy27_prebuilt = callPackage ./pypy/prebuilt.nix {
+    # Not included at top-level
+    self = pythonInterpreters.pypy27_prebuilt;
+    sourceVersion = {
+      major = "6";
+      minor = "0";
+      patch = "0";
+    };
+    sha256 = "0rxgnp3fm18b87ln8bbjr13g2fsf4ka4abkaim6m03y9lwmr9gvc"; # linux64
+    pythonVersion = "2.7";
+    inherit passthruFun;
+    ncurses = ncurses5;
+  };
+
+  pypy35_prebuilt = callPackage ./pypy/prebuilt.nix {
+  # Not included at top-level
+    self = pythonInterpreters.pypy35_prebuilt;
+    sourceVersion = {
+      major = "6";
+      minor = "0";
+      patch = "0";
+    };
+    sha256 = "0j3h08s7wpglghasmym3baycpif5jshvmk9rpav4pwwy5clzmzsc"; # linux64
+    pythonVersion = "3.5";
+    inherit passthruFun;
+    ncurses = ncurses5;
+  };
+
+})
\ No newline at end of file
diff --git a/pkgs/development/interpreters/python/mk-python-derivation.nix b/pkgs/development/interpreters/python/mk-python-derivation.nix
index b9a6835908f..7718bdfde5d 100644
--- a/pkgs/development/interpreters/python/mk-python-derivation.nix
+++ b/pkgs/development/interpreters/python/mk-python-derivation.nix
@@ -77,7 +77,7 @@ let self = toPythonModule (python.stdenv.mkDerivation (builtins.removeAttrs attr
 
   buildInputs = [ wrapPython ]
     ++ lib.optional (lib.hasSuffix "zip" (attrs.src.name or "")) unzip
-    ++ lib.optional catchConflicts setuptools # If we no longer propagate setuptools
+#     ++ lib.optional catchConflicts setuptools # If we no longer propagate setuptools
     ++ buildInputs
     ++ pythonPath;
 
@@ -100,9 +100,12 @@ let self = toPythonModule (python.stdenv.mkDerivation (builtins.removeAttrs attr
     # Check if we have two packages with the same name in the closure and fail.
     # If this happens, something went wrong with the dependencies specs.
     # Intentionally kept in a subdirectory, see catch_conflicts/README.md.
-    ${python.interpreter} ${./catch_conflicts}/catch_conflicts.py
+    ${python.pythonForBuild.interpreter} ${./catch_conflicts}/catch_conflicts.py
   '' + attrs.postFixup or '''';
 
+  # Python packages built through cross-compilation are always for the host platform.
+  disallowedReferences = lib.optionals (python.stdenv.hostPlatform != python.stdenv.buildPlatform) [ python.pythonForBuild ];
+
   meta = {
     # default to python's platforms
     platforms = python.meta.platforms;
diff --git a/pkgs/development/interpreters/python/pypy/2.7/default.nix b/pkgs/development/interpreters/python/pypy/2.7/default.nix
deleted file mode 100644
index 6f7fa962296..00000000000
--- a/pkgs/development/interpreters/python/pypy/2.7/default.nix
+++ /dev/null
@@ -1,136 +0,0 @@
-{ stdenv, substituteAll, fetchurl
-, zlib ? null, zlibSupport ? true, bzip2, pkgconfig, libffi
-, sqlite, openssl, ncurses, python, expat, tcl, tk, tix, xlibsWrapper, libX11
-, makeWrapper, callPackage, self, gdbm, db
-, python-setup-hook
-# For the Python package set
-, packageOverrides ? (self: super: {})
-}:
-
-assert zlibSupport -> zlib != null;
-
-let
-  version = "6.0.0";
-  pythonVersion = "2.7";
-  libPrefix = "pypy${pythonVersion}";
-  sitePackages = "site-packages";
-
-  pythonForPypy = python.withPackages (ppkgs: [ ppkgs.pycparser ]);
-
-in stdenv.mkDerivation rec {
-  name = "pypy-${version}";
-  inherit version pythonVersion;
-
-  src = fetchurl {
-    url = "https://bitbucket.org/pypy/pypy/get/release-pypy${pythonVersion}-v${version}.tar.bz2";
-    sha256 = "1qjwpc8n68sxxlfg36s5vn1h2gdfvvd6lxvr4lzbvfwhzrgqahsw";
-  };
-
-  nativeBuildInputs = [ pkgconfig makeWrapper ];
-  buildInputs = [
-    bzip2 openssl pythonForPypy libffi ncurses expat sqlite tk tcl xlibsWrapper libX11 gdbm db
-  ] ++ stdenv.lib.optional (stdenv ? cc && stdenv.cc.libc != null) stdenv.cc.libc
-    ++ stdenv.lib.optional zlibSupport zlib;
-
-  hardeningDisable = stdenv.lib.optional stdenv.isi686 "pic";
-
-  C_INCLUDE_PATH = stdenv.lib.makeSearchPathOutput "dev" "include" buildInputs;
-  LIBRARY_PATH = stdenv.lib.makeLibraryPath buildInputs;
-  LD_LIBRARY_PATH = stdenv.lib.makeLibraryPath (stdenv.lib.filter (x : x.outPath != stdenv.cc.libc.outPath or "") buildInputs);
-
-  patches = [
-    (substituteAll {
-      src = ./tk_tcl_paths.patch;
-      inherit tk tcl;
-      tk_dev = tk.dev;
-      tcl_dev = tcl;
-      tk_libprefix = tk.libPrefix;
-      tcl_libprefix = tcl.libPrefix;
-    })
-  ];
-
-  postPatch = ''
-    substituteInPlace "lib-python/2.7/lib-tk/Tix.py" --replace "os.environ.get('TIX_LIBRARY')" "os.environ.get('TIX_LIBRARY') or '${tix}/lib'"
-
-    # hint pypy to find nix ncurses
-    substituteInPlace pypy/module/_minimal_curses/fficurses.py \
-      --replace "/usr/include/ncurses/curses.h" "${ncurses.dev}/include/curses.h" \
-      --replace "ncurses/curses.h" "${ncurses.dev}/include/curses.h" \
-      --replace "ncurses/term.h" "${ncurses.dev}/include/term.h" \
-      --replace "libraries=['curses']" "libraries=['ncurses']"
-
-    sed -i "s@libraries=\['sqlite3'\]\$@libraries=['sqlite3'], include_dirs=['${sqlite.dev}/include'], library_dirs=['${sqlite.out}/lib']@" lib_pypy/_sqlite3_build.py
-  '';
-
-  buildPhase = ''
-    ${pythonForPypy.interpreter} rpython/bin/rpython \
-      --make-jobs="$NIX_BUILD_CORES" \
-      -Ojit \
-      --batch pypy/goal/targetpypystandalone.py
-  '';
-
-  setupHook = python-setup-hook sitePackages;
-
-  doCheck = true;
-  checkPhase = ''
-    export TERMINFO="${ncurses.out}/share/terminfo/";
-    export TERM="xterm";
-    export HOME="$TMPDIR";
-    # disable shutils because it assumes gid 0 exists
-    # disable socket because it has two actual network tests that fail
-    # disable test_urllib2net, test_urllib2_localnet, and test_urllibnet because they require networking (example.com)
-    ./pypy-c ./pypy/test_all.py --pypy=./pypy-c -k 'not ( test_urllib2net or test_urllibnet or test_urllib2_localnet or test_socket or test_shutil )' lib-python
-  '';
-
-  installPhase = ''
-    mkdir -p $out/{bin,include,lib,pypy-c}
-
-    cp -R {include,lib_pypy,lib-python,pypy-c} $out/pypy-c
-    cp libpypy-c.so $out/lib/
-    ln -s $out/pypy-c/pypy-c $out/bin/pypy
-    chmod +x $out/bin/pypy
-
-    # other packages expect to find stuff according to libPrefix
-    ln -s $out/pypy-c/include $out/include/${libPrefix}
-    ln -s $out/pypy-c/lib-python/${pythonVersion} $out/lib/${libPrefix}
-
-    # We must wrap the original, not the symlink.
-    # PyPy uses argv[0] to find its standard library, and while it knows
-    # how to follow symlinks, it doesn't know about wrappers. So, it
-    # will think the wrapper is the original. As long as the wrapper has
-    # the same path as the original, this is OK.
-    wrapProgram "$out/pypy-c/pypy-c" \
-      --set LD_LIBRARY_PATH "${LD_LIBRARY_PATH}:$out/lib" \
-      --set LIBRARY_PATH "${LIBRARY_PATH}:$out/lib"
-
-    # verify cffi modules
-    $out/bin/pypy -c "import Tkinter;import sqlite3;import curses"
-
-    # Python on Nix is not manylinux1 compatible. https://github.com/NixOS/nixpkgs/issues/18484
-    echo "manylinux1_compatible=False" >> $out/lib/${libPrefix}/_manylinux.py
-  '';
-
-  passthru = let
-    pythonPackages = callPackage ../../../../../top-level/python-packages.nix {python=self; overrides=packageOverrides;};
-  in rec {
-    inherit zlibSupport libPrefix sitePackages;
-    executable = "pypy";
-    isPypy = true;
-    isPy2 = true;
-    isPy27 = true;
-    buildEnv = callPackage ../../wrapper.nix { python = self; inherit (pythonPackages) requiredPythonModules; };
-    interpreter = "${self}/bin/${executable}";
-    withPackages = import ../../with-packages.nix { inherit buildEnv pythonPackages;};
-    pkgs = pythonPackages;
-  };
-
-  enableParallelBuilding = true;  # almost no parallelization without STM
-
-  meta = with stdenv.lib; {
-    homepage = http://pypy.org/;
-    description = "Fast, compliant alternative implementation of the Python language (2.7.13)";
-    license = licenses.mit;
-    platforms = [ "i686-linux" "x86_64-linux" ];
-    maintainers = with maintainers; [ ];
-  };
-}
diff --git a/pkgs/development/interpreters/python/pypy/3/tk_tcl_paths.patch b/pkgs/development/interpreters/python/pypy/3/tk_tcl_paths.patch
deleted file mode 100644
index 92bbfc557b3..00000000000
--- a/pkgs/development/interpreters/python/pypy/3/tk_tcl_paths.patch
+++ /dev/null
@@ -1,17 +0,0 @@
---- pypy-pypy-84a2f3e6a7f8.org/lib_pypy/_tkinter/tklib_build.py	2017-10-03 11:49:20.000000000 +0100
-+++ pypy-pypy-84a2f3e6a7f8/lib_pypy/_tkinter/tklib_build.py	2017-11-21 13:20:51.398607530 +0000
-@@ -24,11 +24,11 @@
- else:
-     # On some Linux distributions, the tcl and tk libraries are
-     # stored in /usr/include, so we must check this case also
--    libdirs = []
-+    libdirs = ["@tcl@/lib", "@tk@/lib"]
-     found = False
-     for _ver in ['', '8.6', '8.5']:
--        incdirs = ['/usr/include/tcl' + _ver]
--        linklibs = ['tcl' + _ver, 'tk' + _ver]
-+        incdirs = ['@tcl_dev@/include', '@tk_dev@/include']
-+        linklibs = ['@tcl_libprefix@', '@tk_libprefix@']
-         if os.path.isdir(incdirs[0]):
-             found = True
-             break
diff --git a/pkgs/development/interpreters/python/pypy/3/default.nix b/pkgs/development/interpreters/python/pypy/default.nix
index 23e239d925b..a7c3d6740c1 100644
--- a/pkgs/development/interpreters/python/pypy/3/default.nix
+++ b/pkgs/development/interpreters/python/pypy/default.nix
@@ -5,38 +5,54 @@
 , python-setup-hook
 # For the Python package set
 , packageOverrides ? (self: super: {})
+, sourceVersion
+, pythonVersion
+, sha256
+, passthruFun
 }:
 
 assert zlibSupport -> zlib != null;
 
-let
-  version = "6.0.0";
-  pythonVersion = "3.5";
-  libPrefix = "pypy${pythonVersion}";
-  sitePackages = "site-packages";
+with stdenv.lib;
 
+let
+  isPy3k = substring 0 1 pythonVersion == "3";
+  passthru = passthruFun rec {
+    inherit self sourceVersion pythonVersion packageOverrides;
+    implementation = "pypy";
+    libPrefix = "pypy${pythonVersion}";
+    executable = "pypy${if isPy3k then "3" else ""}";
+    pythonForBuild = self; # No cross-compiling for now.
+    sitePackages = "site-packages";
+  };
+  pname = passthru.executable;
+  version = with sourceVersion; "${major}.${minor}.${patch}";
   pythonForPypy = python.withPackages (ppkgs: [ ppkgs.pycparser ]);
 
-in stdenv.mkDerivation rec {
-  name = "pypy3-${version}";
-  inherit version pythonVersion;
+in with passthru; stdenv.mkDerivation rec {
+  inherit pname version;
 
   src = fetchurl {
     url = "https://bitbucket.org/pypy/pypy/get/release-pypy${pythonVersion}-v${version}.tar.bz2";
-    sha256 = "0lwq8nn0r5yj01bwmkk5p7xvvrp4s550l8184mkmn74d3gphrlwg";
+    inherit sha256;
   };
 
   nativeBuildInputs = [ pkgconfig makeWrapper ];
   buildInputs = [
-    bzip2 openssl pythonForPypy libffi ncurses expat sqlite tk tcl xlibsWrapper libX11 gdbm db lzma
-  ] ++ stdenv.lib.optional (stdenv ? cc && stdenv.cc.libc != null) stdenv.cc.libc
-    ++ stdenv.lib.optional zlibSupport zlib;
+    bzip2 openssl pythonForPypy libffi ncurses expat sqlite tk tcl xlibsWrapper libX11 gdbm db
+  ]  ++ optionals isPy3k [
+    lzma
+  ] ++ optionals (stdenv ? cc && stdenv.cc.libc != null) [
+    stdenv.cc.libc
+  ] ++ optionals zlibSupport [
+    zlib
+  ];
 
-  hardeningDisable = stdenv.lib.optional stdenv.isi686 "pic";
+  hardeningDisable = optional stdenv.isi686 "pic";
 
-  C_INCLUDE_PATH = stdenv.lib.makeSearchPathOutput "dev" "include" buildInputs;
-  LIBRARY_PATH = stdenv.lib.makeLibraryPath buildInputs;
-  LD_LIBRARY_PATH = stdenv.lib.makeLibraryPath (stdenv.lib.filter (x : x.outPath != stdenv.cc.libc.outPath or "") buildInputs);
+  C_INCLUDE_PATH = makeSearchPathOutput "dev" "include" buildInputs;
+  LIBRARY_PATH = makeLibraryPath buildInputs;
+  LD_LIBRARY_PATH = makeLibraryPath (filter (x : x.outPath != stdenv.cc.libc.outPath or "") buildInputs);
 
   patches = [
     (substituteAll {
@@ -50,7 +66,7 @@ in stdenv.mkDerivation rec {
   ];
 
   postPatch = ''
-    substituteInPlace "lib-python/3/tkinter/tix.py" --replace "os.environ.get('TIX_LIBRARY')" "os.environ.get('TIX_LIBRARY') or '${tix}/lib'"
+    substituteInPlace "lib-python/${if isPy3k then "3/tkinter/tix.py" else "2.7/lib-tk/Tix.py"}" --replace "os.environ.get('TIX_LIBRARY')" "os.environ.get('TIX_LIBRARY') or '${tix}/lib'"
 
     # hint pypy to find nix ncurses
     substituteInPlace pypy/module/_minimal_curses/fficurses.py \
@@ -72,60 +88,63 @@ in stdenv.mkDerivation rec {
   setupHook = python-setup-hook sitePackages;
 
   doCheck = true;
-  checkPhase = ''
+  checkPhase = let
+    disabledTests = [
+      # disable shutils because it assumes gid 0 exists
+      "test_shutil"
+      # disable socket because it has two actual network tests that fail
+      "test_socket"
+    ] ++ optionals (!isPy3k) [
+      # disable test_urllib2net, test_urllib2_localnet, and test_urllibnet because they require networking (example.com)
+      "test_urllib2net"
+      "test_urllibnet"
+      "test_urllib2_localnet"
+    ] ++ optionals isPy3k [
+      # disable asyncio due to https://github.com/NixOS/nix/issues/1238
+      "test_asyncio"
+      # disable os due to https://github.com/NixOS/nixpkgs/issues/10496
+      "test_os"
+      # disable pathlib due to https://bitbucket.org/pypy/pypy/pull-requests/594
+      "test_pathlib"
+      # disable tarfile because it assumes gid 0 exists
+      "test_tarfile"
+    ];
+  in ''
     export TERMINFO="${ncurses.out}/share/terminfo/";
     export TERM="xterm";
     export HOME="$TMPDIR";
-    # disable asyncio due to https://github.com/NixOS/nix/issues/1238
-    # disable os due to https://github.com/NixOS/nixpkgs/issues/10496
-    # disable pathlib due to https://bitbucket.org/pypy/pypy/pull-requests/594
-    # disable shutils because it assumes gid 0 exists
-    # disable socket because it has two actual network tests that fail
-    # disable tarfile because it assumes gid 0 exists
-    ${pythonForPypy.interpreter} ./pypy/test_all.py --pypy=./pypy3-c -k 'not ( test_asyncio or test_os or test_pathlib or test_shutil or test_socket or test_tarfile )' lib-python
+
+    ${pythonForPypy.interpreter} ./pypy/test_all.py --pypy=./${executable}-c -k 'not (${concatStringsSep " or " disabledTests})' lib-python
   '';
 
   installPhase = ''
-    mkdir -p $out/{bin,include,lib,pypy3-c}
+    mkdir -p $out/{bin,include,lib,${executable}-c}
 
-    cp -R {include,lib_pypy,lib-python,pypy3-c} $out/pypy3-c
-    cp libpypy3-c.so $out/lib/
-    ln -s $out/pypy3-c/pypy3-c $out/bin/pypy3
+    cp -R {include,lib_pypy,lib-python,${executable}-c} $out/${executable}-c
+    cp lib${executable}-c.so $out/lib/
+    ln -s $out/${executable}-c/${executable}-c $out/bin/${executable}
 
     # other packages expect to find stuff according to libPrefix
-    ln -s $out/pypy3-c/include $out/include/${libPrefix}
-    ln -s $out/pypy3-c/lib-python/3 $out/lib/${libPrefix}
+    ln -s $out/${executable}/include $out/include/${libPrefix}
+    ln -s $out/${executable}-c/lib-python/${if isPy3k then "3" else pythonVersion} $out/lib/${libPrefix}
 
     # We must wrap the original, not the symlink.
     # PyPy uses argv[0] to find its standard library, and while it knows
     # how to follow symlinks, it doesn't know about wrappers. So, it
     # will think the wrapper is the original. As long as the wrapper has
     # the same path as the original, this is OK.
-    wrapProgram "$out/pypy3-c/pypy3-c" \
+    wrapProgram "$out/${executable}-c/${executable}-c" \
       --set LD_LIBRARY_PATH "${LD_LIBRARY_PATH}:$out/lib" \
       --set LIBRARY_PATH "${LIBRARY_PATH}:$out/lib"
 
     # verify cffi modules
-    $out/bin/pypy3 -c "import tkinter;import sqlite3;import curses;import lzma"
+    $out/bin/${executable} -c ${if isPy3k then "'import tkinter;import sqlite3;import curses;import lzma'" else "'import Tkinter;import sqlite3;import curses'"}
 
     # Python on Nix is not manylinux1 compatible. https://github.com/NixOS/nixpkgs/issues/18484
     echo "manylinux1_compatible=False" >> $out/lib/${libPrefix}/_manylinux.py
   '';
 
-  passthru = let
-    pythonPackages = callPackage ../../../../../top-level/python-packages.nix {python=self; overrides=packageOverrides;};
-  in rec {
-    inherit zlibSupport libPrefix sitePackages;
-    executable = "pypy3";
-    isPypy = true;
-    isPy3 = true;
-    isPy35 = true;
-    buildEnv = callPackage ../../wrapper.nix { python = self; inherit (pythonPackages) requiredPythonModules; };
-    interpreter = "${self}/bin/${executable}";
-    withPackages = import ../../with-packages.nix { inherit buildEnv pythonPackages;};
-    pkgs = pythonPackages;
-  };
-
+  inherit passthru;
   enableParallelBuilding = true;  # almost no parallelization without STM
 
   meta = with stdenv.lib; {
diff --git a/pkgs/development/interpreters/python/pypy/prebuilt.nix b/pkgs/development/interpreters/python/pypy/prebuilt.nix
new file mode 100644
index 00000000000..cf23a47e5db
--- /dev/null
+++ b/pkgs/development/interpreters/python/pypy/prebuilt.nix
@@ -0,0 +1,123 @@
+{ stdenv
+, fetchurl
+, python-setup-hook
+, self
+, which
+# Dependencies
+, bzip2
+, zlib
+, openssl
+, expat
+, libffi
+, ncurses
+, tcl
+, tk
+# For the Python package set
+, packageOverrides ? (self: super: {})
+, sourceVersion
+, pythonVersion
+, sha256
+, passthruFun
+}:
+
+# This version of PyPy is primarily added to speed-up translation of
+# our PyPy source build when developing that expression.
+
+with stdenv.lib;
+
+let
+  isPy3k = majorVersion == "3";
+  passthru = passthruFun rec {
+    inherit self sourceVersion pythonVersion packageOverrides;
+    implementation = "pypy";
+    libPrefix = "pypy${pythonVersion}";
+    executable = "pypy${if isPy3k then "3" else ""}";
+    pythonForBuild = self; # Not possible to cross-compile with.
+    sitePackages = "site-packages";
+  };
+  pname = "${passthru.executable}_prebuilt";
+  version = with sourceVersion; "${major}.${minor}.${patch}";
+
+  majorVersion = substring 0 1 pythonVersion;
+
+  setupHook = python-setup-hook sitePackages;
+
+  deps = [
+    bzip2
+    zlib
+    openssl
+    expat
+    libffi
+    ncurses
+    tcl
+    tk
+  ];
+
+in with passthru; stdenv.mkDerivation {
+  inherit pname version;
+
+  src = fetchurl {
+    url= "https://bitbucket.org/pypy/pypy/downloads/pypy${majorVersion}-v${version}-linux64.tar.bz2";
+    inherit sha256;
+  };
+
+  buildInputs = [ which ];
+
+  installPhase = ''
+    mkdir -p $out/lib
+    echo "Moving files to $out"
+    mv -t $out bin include lib-python lib_pypy site-packages
+
+    mv $out/bin/libpypy*-c.so $out/lib/
+
+    rm $out/bin/*.debug
+
+    echo "Patching binaries"
+    interpreter=$(patchelf --print-interpreter $(readlink -f $(which patchelf)))
+    patchelf --set-interpreter $interpreter \
+             --set-rpath $out/lib \
+             $out/bin/pypy*
+
+    pushd $out
+    find {lib,lib_pypy*} -name "*.so" -exec patchelf --replace-needed "libbz2.so.1.0" "libbz2.so.1" {} \;
+    find {lib,lib_pypy*} -name "*.so" -exec patchelf --set-rpath ${stdenv.lib.makeLibraryPath deps} {} \;
+
+    echo "Removing bytecode"
+    find . -name "__pycache__" -type d -depth -exec rm -rf {} \;
+    popd
+  '';
+
+  doInstallCheck = true;
+
+  # Check whether importing of (extension) modules functions
+  installCheckPhase = let
+    modules = [
+      "ssl"
+      "sys"
+      "curses"
+    ] ++ optionals (!isPy3k) [
+      "Tkinter"
+    ] ++ optionals isPy3k [
+      "tkinter"
+    ];
+    imports = concatMapStringsSep "; " (x: "import ${x}") modules;
+  in ''
+    echo "Testing whether we can import modules"
+    $out/bin/${executable} -c '${imports}'
+  '';
+
+  setupHook = python-setup-hook sitePackages;
+
+  donPatchElf = true;
+  dontStrip = true;
+
+  inherit passthru;
+
+  meta = with stdenv.lib; {
+    homepage = http://pypy.org/;
+    description = "Fast, compliant alternative implementation of the Python language (3.5.3)";
+    license = licenses.mit;
+    platforms = [ "x86_64-linux" ];
+  };
+
+}
\ No newline at end of file
diff --git a/pkgs/development/interpreters/python/pypy/2.7/tk_tcl_paths.patch b/pkgs/development/interpreters/python/pypy/tk_tcl_paths.patch
index 92bbfc557b3..92bbfc557b3 100644
--- a/pkgs/development/interpreters/python/pypy/2.7/tk_tcl_paths.patch
+++ b/pkgs/development/interpreters/python/pypy/tk_tcl_paths.patch
diff --git a/pkgs/development/interpreters/python/wrap-python.nix b/pkgs/development/interpreters/python/wrap-python.nix
index 4ff0a62d7fb..6a19a215241 100644
--- a/pkgs/development/interpreters/python/wrap-python.nix
+++ b/pkgs/development/interpreters/python/wrap-python.nix
@@ -9,7 +9,8 @@ makeSetupHook {
       deps = makeWrapper;
       substitutions.sitePackages = python.sitePackages;
       substitutions.executable = python.interpreter;
-      substitutions.python = python;
+      substitutions.python = python.pythonForBuild;
+      substitutions.pythonHost = python;
       substitutions.magicalSedExpression = let
         # Looks weird? Of course, it's between single quoted shell strings.
         # NOTE: Order DOES matter here, so single character quotes need to be
diff --git a/pkgs/development/interpreters/python/wrap.sh b/pkgs/development/interpreters/python/wrap.sh
index 6fa8c316a17..b2d65422db4 100644
--- a/pkgs/development/interpreters/python/wrap.sh
+++ b/pkgs/development/interpreters/python/wrap.sh
@@ -16,8 +16,8 @@ buildPythonPath() {
     declare -A pythonPathsSeen=()
     program_PYTHONPATH=
     program_PATH=
-    pythonPathsSeen["@python@"]=1
-    addToSearchPath program_PATH @python@/bin
+    pythonPathsSeen["@pythonHost@"]=1
+    addToSearchPath program_PATH @pythonHost@/bin
     for path in $pythonPath; do
         _addToPythonPath $path
     done
@@ -53,7 +53,13 @@ wrapPythonProgramsIn() {
             # Strip suffix, like "3" or "2.7m" -- we don't have any choice on which
             # Python to use besides one with this hook anyway.
             if head -n1 "$f" | grep -q '#!.*/env.*\(python\|pypy\)'; then
-                sed -i "$f" -e "1 s^.*/env[ ]*\(python\|pypy\)[^ ]*^#! @executable@^"
+                sed -i "$f" -e "1 s^.*/env[ ]*\(python\|pypy\)[^ ]*^#!@executable@^"
+            fi
+
+            if head -n1 "$f" | grep -q '#!.*'; then
+                # Cross-compilation hack: ensure shebangs are for the host
+                echo "Rewriting $(head -n 1 $f) to #!@pythonHost@"
+                sed -i "$f" -e "1 s^#!@python@^#!@pythonHost@^"
             fi
 
             # catch /python and /.python-wrapped
diff --git a/pkgs/development/libraries/physics/geant4/g4py/default.nix b/pkgs/development/libraries/physics/geant4/g4py/default.nix
index 551d61af3ad..f28f0fd6420 100644
--- a/pkgs/development/libraries/physics/geant4/g4py/default.nix
+++ b/pkgs/development/libraries/physics/geant4/g4py/default.nix
@@ -28,7 +28,7 @@ stdenv.mkDerivation rec {
   preConfigure = ''
     # Fix for boost 1.67+
     substituteInPlace CMakeLists.txt \
-    --replace "find_package(Boost)" "find_package(Boost 1.40 REQUIRED COMPONENTS python${builtins.replaceStrings ["."] [""] python.majorVersion})"
+    --replace "find_package(Boost)" "find_package(Boost 1.40 REQUIRED COMPONENTS python${builtins.replaceStrings ["."] [""] python.pythonVersion})"
     for f in `find . -name CMakeLists.txt`; do
       substituteInPlace "$f" \
         --replace "boost_python" "\''${Boost_LIBRARIES}"
diff --git a/pkgs/development/python-modules/cypari2/default.nix b/pkgs/development/python-modules/cypari2/default.nix
index a77e98dae4c..09326ad1a0b 100644
--- a/pkgs/development/python-modules/cypari2/default.nix
+++ b/pkgs/development/python-modules/cypari2/default.nix
@@ -1,5 +1,4 @@
 { stdenv
-, bootstrapped-pip
 , buildPythonPackage
 , python
 , fetchPypi
@@ -24,11 +23,11 @@ buildPythonPackage rec {
   # That is because while the default install phase succeeds to build the package,
   # it fails to generate the file "auto_paridecl.pxd".
   installPhase = ''
-    mkdir -p "$out/lib/${python.libPrefix}/site-packages"
-    export PYTHONPATH="$out/lib/${python.libPrefix}/site-packages:$PYTHONPATH"
+    mkdir -p "$out/lib/${python.sitePackages}"
+    export PYTHONPATH="$out/lib/${python.sitePackages}:$PYTHONPATH"
 
     # install "." instead of "*.whl"
-    ${bootstrapped-pip}/bin/pip install --no-index --prefix=$out --no-cache --build=tmpdir .
+    ${python.pythonForBuild.pkgs.bootstrapped-pip}/bin/pip install --no-index --prefix=$out --no-cache --build=tmpdir .
   '';
 
   buildInputs = [
diff --git a/pkgs/development/python-modules/pyyaml/default.nix b/pkgs/development/python-modules/pyyaml/default.nix
index e66ca0df5b9..b4732e34c4e 100644
--- a/pkgs/development/python-modules/pyyaml/default.nix
+++ b/pkgs/development/python-modules/pyyaml/default.nix
@@ -1,4 +1,4 @@
-{ lib, buildPythonPackage, fetchPypi, libyaml }:
+{ lib, buildPythonPackage, fetchPypi, libyaml, buildPackages }:
 
 buildPythonPackage rec {
   pname = "PyYAML";
@@ -9,6 +9,8 @@ buildPythonPackage rec {
     sha256 = "3ef3092145e9b70e3ddd2c7ad59bdd0252a94dfe3949721633e41344de00a6bf";
   };
 
+  nativeBuildInputs = [ buildPackages.stdenv.cc ];
+
   propagatedBuildInputs = [ libyaml ];
 
   meta = with lib; {
diff --git a/pkgs/development/python-modules/setuptools/default.nix b/pkgs/development/python-modules/setuptools/default.nix
index 09f848d456b..2663d6667e5 100644
--- a/pkgs/development/python-modules/setuptools/default.nix
+++ b/pkgs/development/python-modules/setuptools/default.nix
@@ -17,19 +17,24 @@ stdenv.mkDerivation rec {
     sha256 = "86bb4d8e1b0fabad1f4642b64c335b673e53e7a381de03c9a89fe678152c4c64";
   };
 
-  nativeBuildInputs = [ unzip wrapPython ];
-  buildInputs = [ python ];
+  nativeBuildInputs = [ unzip wrapPython python.pythonForBuild ];
   doCheck = false;  # requires pytest
   installPhase = ''
       dst=$out/${python.sitePackages}
       mkdir -p $dst
       export PYTHONPATH="$dst:$PYTHONPATH"
-      ${python.interpreter} setup.py install --prefix=$out
+      ${python.pythonForBuild.interpreter} setup.py install --prefix=$out
       wrapPythonPrograms
   '';
 
   pythonPath = [];
 
+  dontPatchShebangs = true;
+
+  # Python packages built through cross-compilation are always for the host platform.
+  disallowedReferences = stdenv.lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ python.pythonForBuild ];
+
+
   meta = with stdenv.lib; {
     description = "Utilities to facilitate the installation of Python packages";
     homepage = https://pypi.python.org/pypi/setuptools;
diff --git a/pkgs/development/python-modules/tensorflow/bin.nix b/pkgs/development/python-modules/tensorflow/bin.nix
index b925b74e03b..90f8c9e6e30 100644
--- a/pkgs/development/python-modules/tensorflow/bin.nix
+++ b/pkgs/development/python-modules/tensorflow/bin.nix
@@ -45,7 +45,7 @@ in buildPythonPackage rec {
   format = "wheel";
 
   src = let
-    pyVerNoDot = lib.strings.stringAsChars (x: if x == "." then "" else x) "${python.majorVersion}";
+    pyVerNoDot = lib.strings.stringAsChars (x: if x == "." then "" else x) "${python.pythonVersion}";
     pyver = if stdenv.isDarwin then builtins.substring 0 1 pyVerNoDot else pyVerNoDot;
     platform = if stdenv.isDarwin then "mac" else "linux";
     unit = if cudaSupport then "gpu" else "cpu";
diff --git a/pkgs/tools/misc/calamares/default.nix b/pkgs/tools/misc/calamares/default.nix
index c799b08bd44..edc6a2e4643 100644
--- a/pkgs/tools/misc/calamares/default.nix
+++ b/pkgs/tools/misc/calamares/default.nix
@@ -24,8 +24,8 @@ stdenv.mkDerivation rec {
   enableParallelBuilding = false;
 
   cmakeFlags = [
-    "-DPYTHON_LIBRARY=${python}/lib/libpython${python.majorVersion}m.so"
-    "-DPYTHON_INCLUDE_DIR=${python}/include/python${python.majorVersion}m"
+    "-DPYTHON_LIBRARY=${python}/lib/lib${python.libPrefix}.so"
+    "-DPYTHON_INCLUDE_DIR=${python}/include/${python.libPrefix}"
     "-DCMAKE_VERBOSE_MAKEFILE=True"
     "-DCMAKE_BUILD_TYPE=Release"
     "-DWITH_PYTHONQT:BOOL=ON"
diff --git a/pkgs/tools/networking/unbound/python.nix b/pkgs/tools/networking/unbound/python.nix
index 67e6f2e9c43..c20169d3913 100644
--- a/pkgs/tools/networking/unbound/python.nix
+++ b/pkgs/tools/networking/unbound/python.nix
@@ -19,7 +19,7 @@ in stdenv.mkDerivation rec {
     --replace "\$(LIBTOOL) --mode=install cp _unbound.la" "cp _unbound.la"
     '';
 
-  preConfigure = "export PYTHON_VERSION=${python.majorVersion}";
+  preConfigure = "export PYTHON_VERSION=${python.pythonVersion}";
 
   configureFlags = [
     "--with-ssl=${openssl.dev}"
@@ -46,13 +46,13 @@ in stdenv.mkDerivation rec {
 
   # All we want is the Unbound Python module
   postInstall = ''
-    # Generate the built in root anchor and root key and store these in a logical place 
+    # Generate the built in root anchor and root key and store these in a logical place
     # to be used by tools depending only on the Python module
     $out/bin/unbound-anchor -l | head -1 > $out/etc/${pname}/root.anchor
     $out/bin/unbound-anchor -l | tail --lines=+2 - > $out/etc/${pname}/root.key
     # We don't need anything else
     rm -fR $out/bin $out/share $out/include $out/etc/unbound
-    patchelf --replace-needed libunbound.so.2 $out/${python.sitePackages}/libunbound.so.2 $out/${python.sitePackages}/_unbound.so 
+    patchelf --replace-needed libunbound.so.2 $out/${python.sitePackages}/libunbound.so.2 $out/${python.sitePackages}/_unbound.so
     '';
 
   meta = with stdenv.lib; {
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 3e7a991621c..142173d4725 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -7937,6 +7937,7 @@ in
   python3 = python37;
   pypy = pypy2;
   pypy2 = pypy27;
+  pypy3 = pypy35;
 
   # Python interpreter that is build with all modules, including tkinter.
   # These are for compatibility and should not be used inside Nixpkgs.
@@ -7953,33 +7954,8 @@ in
   python2Packages = python2.pkgs;
   python3Packages = python3.pkgs;
 
-  python27 = callPackage ../development/interpreters/python/cpython/2.7 {
-    self = python27;
-    inherit (darwin) CF configd;
-  };
-  python35 = callPackage ../development/interpreters/python/cpython/3.5 {
-    inherit (darwin) CF configd;
-    self = python35;
-  };
-  python36 = callPackage ../development/interpreters/python/cpython/3.6 {
-    inherit (darwin) CF configd;
-    self = python36;
-  };
-  python37 = callPackage ../development/interpreters/python/cpython/3.7 {
-    inherit (darwin) CF configd;
-    self = python37;
-  };
-
-  pypy27 = callPackage ../development/interpreters/python/pypy/2.7 {
-    self = pypy27;
-    python = python27.override{x11Support=true;};
-    db = db.override { dbmSupport = true; };
-  };
-  pypy3 = callPackage ../development/interpreters/python/pypy/3 {
-    self = pypy3;
-    python = python27;
-    db = db.override { dbmSupport = true; };
-  };
+  pythonInterpreters = callPackage ./../development/interpreters/python {};
+  inherit (pythonInterpreters) python27 python35 python36 python37 pypy27 pypy35;
 
   # Python package sets.
   python27Packages = lib.hiPrioSet (recurseIntoAttrs python27.pkgs);
diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix
index 8403b398ccd..d3aa62faadd 100644
--- a/pkgs/top-level/python-packages.nix
+++ b/pkgs/top-level/python-packages.nix
@@ -18,16 +18,7 @@ let
   packages = ( self:
 
 let
-  pythonAtLeast = versionAtLeast python.pythonVersion;
-  pythonOlder = versionOlder python.pythonVersion;
-  isPy27 = python.pythonVersion == "2.7";
-  isPy33 = python.pythonVersion == "3.3";
-  isPy34 = python.pythonVersion == "3.4";
-  isPy35 = python.pythonVersion == "3.5";
-  isPy36 = python.pythonVersion == "3.6";
-  isPy37 = python.pythonVersion == "3.7";
-  isPyPy = strings.substring 0 4 python.executable == "pypy";
-  isPy3k = strings.substring 0 1 python.pythonVersion == "3";
+  inherit (python.passthru) isPy27 isPy33 isPy34 isPy35 isPy36 isPy37 isPy3k isPyPy pythonAtLeast pythonOlder;
 
   callPackage = pkgs.newScope self;
 
@@ -52,7 +43,6 @@ let
       else ff;
 
   buildPythonPackage = makeOverridablePythonPackage ( makeOverridable (callPackage ../development/interpreters/python/build-python-package.nix {
-    inherit bootstrapped-pip;
     flit = self.flit;
     # We want Python libraries to be named like e.g. "python3.6-${name}"
     inherit namePrefix;
@@ -60,7 +50,6 @@ let
   }));
 
   buildPythonApplication = makeOverridablePythonPackage ( makeOverridable (callPackage ../development/interpreters/python/build-python-package.nix {
-    inherit bootstrapped-pip;
     flit = self.flit;
     namePrefix = "";
     toPythonModule = x: x; # Application does not provide modules.
@@ -130,7 +119,8 @@ let
 
 in {
 
-  inherit python bootstrapped-pip pythonAtLeast pythonOlder isPy27 isPy33 isPy34 isPy35 isPy36 isPy37 isPyPy isPy3k buildPythonPackage buildPythonApplication;
+  inherit (python.passthru) isPy27 isPy33 isPy34 isPy35 isPy36 isPy37 isPy3k isPyPy pythonAtLeast pythonOlder;
+  inherit python bootstrapped-pip buildPythonPackage buildPythonApplication;
   inherit fetchPypi callPackage;
   inherit hasPythonModule requiredPythonModules makePythonPath disabledIf;
   inherit toPythonModule toPythonApplication;