about summary refs log tree commit diff
path: root/pkgs/development/python2-modules
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/development/python2-modules')
-rw-r--r--pkgs/development/python2-modules/Pygments/default.nix37
-rw-r--r--pkgs/development/python2-modules/TurboCheetah/default.nix26
-rw-r--r--pkgs/development/python2-modules/bootstrapped-pip/default.nix66
-rw-r--r--pkgs/development/python2-modules/boto3/default.nix50
-rw-r--r--pkgs/development/python2-modules/botocore/default.nix48
-rw-r--r--pkgs/development/python2-modules/certifi/default.nix34
-rw-r--r--pkgs/development/python2-modules/chardet/default.nix29
-rw-r--r--pkgs/development/python2-modules/cheetah/default.nix33
-rw-r--r--pkgs/development/python2-modules/click/default.nix28
-rw-r--r--pkgs/development/python2-modules/configparser/default.nix26
-rw-r--r--pkgs/development/python2-modules/construct/default.nix39
-rw-r--r--pkgs/development/python2-modules/contextlib2/default.nix23
-rw-r--r--pkgs/development/python2-modules/cryptography-vectors/default.nix23
-rw-r--r--pkgs/development/python2-modules/cryptography/default.nix81
-rw-r--r--pkgs/development/python2-modules/decorator/default.nix21
-rw-r--r--pkgs/development/python2-modules/enum/default.nix26
-rw-r--r--pkgs/development/python2-modules/filelock/default.nix22
-rw-r--r--pkgs/development/python2-modules/flask/default.nix28
-rw-r--r--pkgs/development/python2-modules/freezegun/default.nix29
-rw-r--r--pkgs/development/python2-modules/futures/default.nix27
-rw-r--r--pkgs/development/python2-modules/google-apputils/default.nix41
-rw-r--r--pkgs/development/python2-modules/httpretty/default.nix52
-rw-r--r--pkgs/development/python2-modules/hypothesis/default.nix45
-rw-r--r--pkgs/development/python2-modules/idna/default.nix23
-rw-r--r--pkgs/development/python2-modules/importlib-metadata/default.nix37
-rw-r--r--pkgs/development/python2-modules/ipaddr/default.nix23
-rw-r--r--pkgs/development/python2-modules/itsdangerous/default.nix21
-rw-r--r--pkgs/development/python2-modules/jinja2/default.nix42
-rw-r--r--pkgs/development/python2-modules/libcloud/default.nix39
-rw-r--r--pkgs/development/python2-modules/lpod/default.nix31
-rw-r--r--pkgs/development/python2-modules/marisa/default.nix29
-rw-r--r--pkgs/development/python2-modules/markdown/default.nix33
-rw-r--r--pkgs/development/python2-modules/markupsafe/default.nix22
-rw-r--r--pkgs/development/python2-modules/mock/default.nix44
-rw-r--r--pkgs/development/python2-modules/more-itertools/default.nix31
-rw-r--r--pkgs/development/python2-modules/mutagen/default.nix34
-rw-r--r--pkgs/development/python2-modules/numpy/default.nix99
-rw-r--r--pkgs/development/python2-modules/numpy/numpy-distutils-C++.patch30
-rw-r--r--pkgs/development/python2-modules/packaging/default.nix39
-rw-r--r--pkgs/development/python2-modules/pillow/default.nix47
-rw-r--r--pkgs/development/python2-modules/pillow/generic.nix77
-rw-r--r--pkgs/development/python2-modules/pip/default.nix41
-rw-r--r--pkgs/development/python2-modules/pluggy/default.nix34
-rw-r--r--pkgs/development/python2-modules/prettytable/default.nix37
-rw-r--r--pkgs/development/python2-modules/protobuf/default.nix59
-rw-r--r--pkgs/development/python2-modules/pycairo/default.nix52
-rw-r--r--pkgs/development/python2-modules/pygobject/default.nix33
-rw-r--r--pkgs/development/python2-modules/pygtk/default.nix74
-rw-r--r--pkgs/development/python2-modules/pyjwt/default.nix44
-rw-r--r--pkgs/development/python2-modules/pyroma/default.nix26
-rw-r--r--pkgs/development/python2-modules/pysqlite/default.nix57
-rw-r--r--pkgs/development/python2-modules/pytest-runner/default.nix30
-rw-r--r--pkgs/development/python2-modules/pytest-xdist/default.nix36
-rw-r--r--pkgs/development/python2-modules/pytest/default.nix68
-rw-r--r--pkgs/development/python2-modules/pyyaml/default.nix38
-rw-r--r--pkgs/development/python2-modules/qpid-python/default.nix26
-rw-r--r--pkgs/development/python2-modules/s3transfer/default.nix52
-rw-r--r--pkgs/development/python2-modules/scandir/default.nix20
-rw-r--r--pkgs/development/python2-modules/setuptools-scm/default.nix24
-rw-r--r--pkgs/development/python2-modules/setuptools/default.nix80
-rw-r--r--pkgs/development/python2-modules/setuptools/tag-date.patch12
-rw-r--r--pkgs/development/python2-modules/sphinx/default.nix82
-rw-r--r--pkgs/development/python2-modules/sphinx/python2-lexer.patch22
-rw-r--r--pkgs/development/python2-modules/sphinxcontrib-websupport/default.nix25
-rw-r--r--pkgs/development/python2-modules/typing/default.nix33
-rw-r--r--pkgs/development/python2-modules/urllib3/default.nix81
-rw-r--r--pkgs/development/python2-modules/vcrpy/default.nix48
-rw-r--r--pkgs/development/python2-modules/werkzeug/default.nix60
-rw-r--r--pkgs/development/python2-modules/wsproto/default.nix25
-rw-r--r--pkgs/development/python2-modules/wxPython/default.nix91
-rw-r--r--pkgs/development/python2-modules/zipp/default.nix37
71 files changed, 2882 insertions, 0 deletions
diff --git a/pkgs/development/python2-modules/Pygments/default.nix b/pkgs/development/python2-modules/Pygments/default.nix
new file mode 100644
index 000000000000..aa59c370d2e7
--- /dev/null
+++ b/pkgs/development/python2-modules/Pygments/default.nix
@@ -0,0 +1,37 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, fetchpatch
+, docutils
+}:
+
+buildPythonPackage rec {
+  pname = "Pygments";
+  version = "2.5.2";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe";
+  };
+
+  patches = [
+    (fetchpatch {
+      name = "CVE-2021-27291.patch";
+      url = "https://github.com/pygments/pygments/commit/2e7e8c4a7b318f4032493773732754e418279a14.patch";
+      sha256 = "0ap7jgkmvkkzijabsgnfrwl376cjsxa4jmzvqysrkwpjq3q4rxpa";
+      excludes = ["CHANGES"];
+    })
+  ];
+
+  propagatedBuildInputs = [ docutils ];
+
+  # Circular dependency with sphinx
+  doCheck = false;
+
+  meta = {
+    homepage = "https://pygments.org/";
+    description = "A generic syntax highlighter";
+    license = lib.licenses.bsd2;
+    maintainers = with lib.maintainers; [ ];
+  };
+}
diff --git a/pkgs/development/python2-modules/TurboCheetah/default.nix b/pkgs/development/python2-modules/TurboCheetah/default.nix
new file mode 100644
index 000000000000..717b2b5f2780
--- /dev/null
+++ b/pkgs/development/python2-modules/TurboCheetah/default.nix
@@ -0,0 +1,26 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, cheetah
+, nose
+}:
+
+buildPythonPackage rec {
+  pname = "TurboCheetah";
+  version = "1.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "9e4c7ecb0d061bfb58281363ee1b09337083f013a8b4d0355326a5d8668f450c";
+  };
+
+  propagatedBuildInputs = [ cheetah ];
+
+  checkInputs = [ nose ];
+
+  meta = {
+    description = "TurboGears plugin to support use of Cheetah templates";
+    homepage = "http://docs.turbogears.org/TurboCheetah";
+    license = lib.licenses.mit;
+  };
+}
diff --git a/pkgs/development/python2-modules/bootstrapped-pip/default.nix b/pkgs/development/python2-modules/bootstrapped-pip/default.nix
new file mode 100644
index 000000000000..2fc8b8b8d4b7
--- /dev/null
+++ b/pkgs/development/python2-modules/bootstrapped-pip/default.nix
@@ -0,0 +1,66 @@
+{ lib, stdenv, python, makeWrapper, unzip
+, pipInstallHook
+, setuptoolsBuildHook
+, wheel, pip, setuptools
+}:
+
+stdenv.mkDerivation rec {
+  pname = "pip";
+  inherit (pip) version;
+  name = "${python.libPrefix}-bootstrapped-${pname}-${version}";
+
+  srcs = [ wheel.src pip.src setuptools.src ];
+  sourceRoot = ".";
+
+  dontUseSetuptoolsBuild = true;
+  dontUsePipInstall = true;
+
+  # Should be propagatedNativeBuildInputs
+  propagatedBuildInputs = [
+    # Override to remove dependencies to prevent infinite recursion.
+    (pipInstallHook.override{pip=null;})
+    (setuptoolsBuildHook.override{setuptools=null; wheel=null;})
+  ];
+
+  postPatch = ''
+    mkdir -p $out/bin
+  '';
+
+  nativeBuildInputs = [ makeWrapper unzip ];
+  buildInputs = [ python ];
+
+  dontBuild = true;
+
+  installPhase = lib.optionalString (!stdenv.hostPlatform.isWindows) ''
+    export SETUPTOOLS_INSTALL_WINDOWS_SPECIFIC_FILES=0
+  '' + ''
+    # Give folders a known name
+    mv pip* pip
+    mv setuptools* setuptools
+    mv wheel* wheel
+    # Set up PYTHONPATH. The above folders need to be on PYTHONPATH
+    # $out is where we are installing to and takes precedence
+    export PYTHONPATH="$out/${python.sitePackages}:$(pwd)/pip/src:$(pwd)/setuptools:$(pwd)/setuptools/pkg_resources:$(pwd)/wheel:$PYTHONPATH"
+
+    echo "Building setuptools wheel..."
+    pushd setuptools
+    ${python.pythonForBuild.interpreter} -m pip install --no-build-isolation --no-index --prefix=$out  --ignore-installed --no-dependencies --no-cache .
+    popd
+
+    echo "Building wheel wheel..."
+    pushd wheel
+    ${python.pythonForBuild.interpreter} -m pip install --no-build-isolation --no-index --prefix=$out  --ignore-installed --no-dependencies --no-cache .
+    popd
+
+    echo "Building pip wheel..."
+    pushd pip
+    ${python.pythonForBuild.interpreter} -m pip install --no-build-isolation --no-index --prefix=$out  --ignore-installed --no-dependencies --no-cache .
+    popd
+  '';
+
+  meta = {
+    description = "Version of pip used for bootstrapping";
+    license = lib.unique (pip.meta.license ++ setuptools.meta.license ++ wheel.meta.license);
+    homepage = pip.meta.homepage;
+  };
+}
diff --git a/pkgs/development/python2-modules/boto3/default.nix b/pkgs/development/python2-modules/boto3/default.nix
new file mode 100644
index 000000000000..c8b8210f6503
--- /dev/null
+++ b/pkgs/development/python2-modules/boto3/default.nix
@@ -0,0 +1,50 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, botocore
+, jmespath
+, s3transfer
+, futures ? null
+, docutils
+, nose
+, mock
+, isPy3k
+}:
+
+buildPythonPackage rec {
+  pname = "boto3";
+  version = "1.17.97"; # N.B: if you change this, change botocore and awscli to a matching version
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "0ab5afc51461c30f27aebef944211d16f47697b98ff8d2e2f6e49e59584853bb";
+  };
+
+  propagatedBuildInputs = [ botocore jmespath s3transfer ] ++ lib.optionals (!isPy3k) [ futures ];
+  checkInputs = [ docutils nose mock ];
+
+  checkPhase = ''
+    runHook preCheck
+    # This method is not in mock. It might have appeared in some versions.
+    sed -i 's/action.assert_called_once()/self.assertEqual(action.call_count, 1)/' \
+      tests/unit/resources/test_factory.py
+    nosetests -d tests/unit --verbose
+    runHook postCheck
+  '';
+
+  # Network access
+  doCheck = false;
+
+  pythonImportsCheck = [ "boto3" ];
+
+  meta = {
+    homepage = "https://github.com/boto/boto3";
+    license = lib.licenses.asl20;
+    description = "AWS SDK for Python";
+    longDescription = ''
+      Boto3 is the Amazon Web Services (AWS) Software Development Kit (SDK) for
+      Python, which allows Python developers to write software that makes use of
+      services like Amazon S3 and Amazon EC2.
+    '';
+  };
+}
diff --git a/pkgs/development/python2-modules/botocore/default.nix b/pkgs/development/python2-modules/botocore/default.nix
new file mode 100644
index 000000000000..d05c2decf497
--- /dev/null
+++ b/pkgs/development/python2-modules/botocore/default.nix
@@ -0,0 +1,48 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, python-dateutil
+, jmespath
+, docutils
+, ordereddict
+, simplejson
+, mock
+, nose
+, urllib3
+}:
+
+buildPythonPackage rec {
+  pname = "botocore";
+  version = "1.20.97"; # N.B: if you change this, change boto3 and awscli to a matching version
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "f7e119cf3e0f4a36100f0e983583afa91a84fb27c479a1716820aee4f2e190ab";
+  };
+
+  propagatedBuildInputs = [
+    python-dateutil
+    jmespath
+    docutils
+    ordereddict
+    simplejson
+    urllib3
+  ];
+
+  checkInputs = [ mock nose ];
+
+  checkPhase = ''
+    nosetests -v
+  '';
+
+  # Network access
+  doCheck = false;
+
+  pythonImportsCheck = [ "botocore" ];
+
+  meta = with lib; {
+    homepage = "https://github.com/boto/botocore";
+    license = licenses.asl20;
+    description = "A low-level interface to a growing number of Amazon Web Services";
+  };
+}
diff --git a/pkgs/development/python2-modules/certifi/default.nix b/pkgs/development/python2-modules/certifi/default.nix
new file mode 100644
index 000000000000..529d5b1fb996
--- /dev/null
+++ b/pkgs/development/python2-modules/certifi/default.nix
@@ -0,0 +1,34 @@
+{ lib
+, fetchPypi
+, buildPythonPackage
+, python3
+}:
+
+let
+  inherit (python3.pkgs) certifi;
+
+in buildPythonPackage rec {
+  pname = "certifi";
+  version = "2019.11.28";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f";
+  };
+
+  postPatch = ''
+    cp ${certifi.src}/certifi/cacert.pem certifi/cacert.pem
+  '';
+
+  pythonImportsCheck = [ "certifi" ];
+
+  # no tests implemented
+  doCheck = false;
+
+  meta = with lib; {
+    homepage = "https://github.com/certifi/python-certifi";
+    description = "Python package for providing Mozilla's CA Bundle";
+    license = licenses.isc;
+    maintainers = with maintainers; [ ]; # NixOps team
+  };
+}
diff --git a/pkgs/development/python2-modules/chardet/default.nix b/pkgs/development/python2-modules/chardet/default.nix
new file mode 100644
index 000000000000..5f6fe0a672a7
--- /dev/null
+++ b/pkgs/development/python2-modules/chardet/default.nix
@@ -0,0 +1,29 @@
+{ lib, buildPythonPackage, fetchPypi, fetchpatch
+, pytest, pytest-runner, hypothesis }:
+
+buildPythonPackage rec {
+  pname = "chardet";
+  version = "3.0.4";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "1bpalpia6r5x1kknbk11p1fzph56fmmnp405ds8icksd3knr5aw4";
+  };
+
+  patches = [
+    # Add pytest 4 support. See: https://github.com/chardet/chardet/pull/174
+    (fetchpatch {
+      url = "https://github.com/chardet/chardet/commit/0561ddcedcd12ea1f98b7ddedb93686ed8a5ffa4.patch";
+      sha256 = "1y1xhjf32rdhq9sfz58pghwv794f3w2f2qcn8p6hp4pc8jsdrn2q";
+    })
+  ];
+
+  checkInputs = [ pytest pytest-runner hypothesis ];
+
+  meta = with lib; {
+    homepage = "https://github.com/chardet/chardet";
+    description = "Universal encoding detector";
+    license = licenses.lgpl2;
+    maintainers = with maintainers; [ domenkozar ];
+  };
+}
diff --git a/pkgs/development/python2-modules/cheetah/default.nix b/pkgs/development/python2-modules/cheetah/default.nix
new file mode 100644
index 000000000000..1cee46fa7252
--- /dev/null
+++ b/pkgs/development/python2-modules/cheetah/default.nix
@@ -0,0 +1,33 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, markdown
+, isPy3k
+, TurboCheetah
+}:
+
+buildPythonPackage rec {
+  pname = "cheetah";
+  version = "2.4.4";
+
+  disabled = isPy3k;
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "be308229f0c1e5e5af4f27d7ee06d90bb19e6af3059794e5fd536a6f29a9b550";
+  };
+
+  propagatedBuildInputs = [ markdown ];
+
+  doCheck = false; # Circular dependency
+
+  checkInputs = [
+    TurboCheetah
+  ];
+
+  meta = {
+    homepage = "http://www.cheetahtemplate.org/";
+    description = "A template engine and code generation tool";
+    license = lib.licenses.mit;
+  };
+}
diff --git a/pkgs/development/python2-modules/click/default.nix b/pkgs/development/python2-modules/click/default.nix
new file mode 100644
index 000000000000..fcbd4d0981af
--- /dev/null
+++ b/pkgs/development/python2-modules/click/default.nix
@@ -0,0 +1,28 @@
+{ lib, buildPythonPackage, fetchPypi, locale, pytestCheckHook }:
+
+buildPythonPackage rec {
+  pname = "click";
+  version = "7.1.2";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a";
+  };
+
+  postPatch = ''
+    substituteInPlace src/click/_unicodefun.py \
+      --replace "'locale'" "'${locale}/bin/locale'"
+  '';
+
+  checkInputs = [ pytestCheckHook ];
+
+  meta = with lib; {
+    homepage = "https://click.palletsprojects.com/";
+    description = "Create beautiful command line interfaces in Python";
+    longDescription = ''
+      A Python package for creating beautiful command line interfaces in a
+      composable way, with as little code as necessary.
+    '';
+    license = licenses.bsd3;
+  };
+}
diff --git a/pkgs/development/python2-modules/configparser/default.nix b/pkgs/development/python2-modules/configparser/default.nix
new file mode 100644
index 000000000000..0f3b6e0b4912
--- /dev/null
+++ b/pkgs/development/python2-modules/configparser/default.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, buildPythonPackage, fetchPypi, setuptools-scm }:
+
+buildPythonPackage rec {
+  pname = "configparser";
+  version = "4.0.2";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "c7d282687a5308319bf3d2e7706e575c635b0a470342641c93bea0ea3b5331df";
+  };
+
+  # No tests available
+  doCheck = false;
+
+  nativeBuildInputs = [ setuptools-scm ];
+
+  preConfigure = ''
+    export LC_ALL=${if stdenv.isDarwin then "en_US" else "C"}.UTF-8
+  '';
+
+  meta = with lib; {
+    description = "Updated configparser from Python 3.7 for Python 2.6+.";
+    license = licenses.mit;
+    homepage = "https://github.com/jaraco/configparser";
+  };
+}
diff --git a/pkgs/development/python2-modules/construct/default.nix b/pkgs/development/python2-modules/construct/default.nix
new file mode 100644
index 000000000000..5bbbd1501453
--- /dev/null
+++ b/pkgs/development/python2-modules/construct/default.nix
@@ -0,0 +1,39 @@
+{ lib, stdenv, buildPythonPackage, fetchFromGitHub
+, pytestCheckHook, pytest-benchmark, enum34, numpy, arrow, ruamel-yaml
+}:
+
+buildPythonPackage rec {
+  pname   = "construct";
+  version = "2.10.54";
+
+  # no tests in PyPI tarball
+  src = fetchFromGitHub {
+    owner  = pname;
+    repo   = pname;
+    rev    = "v${version}";
+    sha256 = "1mqspsn6bf3ibvih1zna2glkg8iw7vy5zg9gzg0d1m8zcndk2c48";
+  };
+
+  checkInputs = [ pytestCheckHook enum34 numpy ];
+
+  # these have dependencies that are broken on Python 2
+  disabledTestPaths = [
+    "tests/gallery/test_gallery.py"
+    "tests/test_benchmarks.py"
+    "tests/test_compiler.py"
+  ];
+
+  disabledTests = [
+    "test_benchmarks"
+    "test_timestamp"
+  ] ++ lib.optionals stdenv.isDarwin [
+    "test_multiprocessing"
+  ];
+
+  meta = with lib; {
+    description = "Powerful declarative parser (and builder) for binary data";
+    homepage = "https://construct.readthedocs.org/";
+    license = licenses.mit;
+    maintainers = with maintainers; [ dotlambda ];
+  };
+}
diff --git a/pkgs/development/python2-modules/contextlib2/default.nix b/pkgs/development/python2-modules/contextlib2/default.nix
new file mode 100644
index 000000000000..38d9fb696e28
--- /dev/null
+++ b/pkgs/development/python2-modules/contextlib2/default.nix
@@ -0,0 +1,23 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, unittest2
+}:
+
+buildPythonPackage rec {
+  pname = "contextlib2";
+  version = "0.6.0.post1";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "01f490098c18b19d2bd5bb5dc445b2054d2fa97f09a4280ba2c5f3c394c8162e";
+  };
+
+  checkInputs = [ unittest2 ];
+
+  meta = {
+    description = "Backports and enhancements for the contextlib module";
+    homepage = "https://contextlib2.readthedocs.org/";
+    license = lib.licenses.psfl;
+  };
+}
diff --git a/pkgs/development/python2-modules/cryptography-vectors/default.nix b/pkgs/development/python2-modules/cryptography-vectors/default.nix
new file mode 100644
index 000000000000..f9b7c525237a
--- /dev/null
+++ b/pkgs/development/python2-modules/cryptography-vectors/default.nix
@@ -0,0 +1,23 @@
+{ buildPythonPackage, fetchPypi, lib, cryptography }:
+
+buildPythonPackage rec {
+  pname = "cryptography_vectors";
+  # The test vectors must have the same version as the cryptography package:
+  version = cryptography.version;
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "1yhaps0f3h2yjb6lmz953z1l1d84y9swk4k3gj9nqyk4vbx5m7cc";
+  };
+
+  # No tests included
+  doCheck = false;
+
+  meta = with lib; {
+    description = "Test vectors for the cryptography package";
+    homepage = "https://cryptography.io/en/latest/development/test-vectors/";
+    # Source: https://github.com/pyca/cryptography/tree/master/vectors;
+    license = with licenses; [ asl20 bsd3 ];
+    maintainers = with maintainers; [ primeos ];
+  };
+}
diff --git a/pkgs/development/python2-modules/cryptography/default.nix b/pkgs/development/python2-modules/cryptography/default.nix
new file mode 100644
index 000000000000..357bb35dacf7
--- /dev/null
+++ b/pkgs/development/python2-modules/cryptography/default.nix
@@ -0,0 +1,81 @@
+{ lib, stdenv
+, buildPythonPackage
+, fetchPypi
+, isPy27
+, ipaddress
+, openssl
+, cryptography_vectors
+, darwin
+, packaging
+, six
+, isPyPy
+, cffi
+, pytest
+, pretend
+, iso8601
+, pytz
+, hypothesis
+, enum34
+}:
+
+buildPythonPackage rec {
+  pname = "cryptography";
+  version = "3.3.2"; # Also update the hash in vectors-3.3.nix
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "1vcvw4lkw1spiq322pm1256kail8nck6bbgpdxx3pqa905wd6q2s";
+  };
+
+  patches = [ ./cryptography-py27-warning.patch ];
+
+  outputs = [ "out" "dev" ];
+
+  nativeBuildInputs = lib.optionals (!isPyPy) [
+    cffi
+  ];
+
+  buildInputs = [ openssl ]
+             ++ lib.optional stdenv.isDarwin darwin.apple_sdk.frameworks.Security;
+  propagatedBuildInputs = [
+    packaging
+    six
+  ] ++ lib.optionals (!isPyPy) [
+    cffi
+  ] ++ lib.optionals isPy27 [
+    ipaddress enum34
+  ];
+
+  checkInputs = [
+    cryptography_vectors
+    hypothesis
+    iso8601
+    pretend
+    pytest
+    pytz
+  ];
+
+  checkPhase = ''
+    py.test --disable-pytest-warnings tests
+  '';
+
+  # IOKit's dependencies are inconsistent between OSX versions, so this is the best we
+  # can do until nix 1.11's release
+  __impureHostDeps = [ "/usr/lib" ];
+
+  meta = with lib; {
+    description = "A package which provides cryptographic recipes and primitives";
+    longDescription = ''
+      Cryptography includes both high level recipes and low level interfaces to
+      common cryptographic algorithms such as symmetric ciphers, message
+      digests, and key derivation functions.
+      Our goal is for it to be your "cryptographic standard library". It
+      supports Python 2.7, Python 3.5+, and PyPy 5.4+.
+    '';
+    homepage = "https://github.com/pyca/cryptography";
+    changelog = "https://cryptography.io/en/latest/changelog/#v"
+      + replaceStrings [ "." ] [ "-" ] version;
+    license = with licenses; [ asl20 bsd3 psfl ];
+    maintainers = with maintainers; [ primeos ];
+  };
+}
diff --git a/pkgs/development/python2-modules/decorator/default.nix b/pkgs/development/python2-modules/decorator/default.nix
new file mode 100644
index 000000000000..8e8fd28f0b54
--- /dev/null
+++ b/pkgs/development/python2-modules/decorator/default.nix
@@ -0,0 +1,21 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+}:
+
+buildPythonPackage rec {
+  pname = "decorator";
+  version = "4.4.2";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "1rxzhk5zwiggk45hl53zydvy70lk654kg0nc1p54090p402jz9p3";
+  };
+
+  meta = with lib; {
+    homepage = "https://pypi.python.org/pypi/decorator";
+    description = "Better living through Python with decorators";
+    license = lib.licenses.mit;
+    maintainers = [ maintainers.costrouc ];
+  };
+}
diff --git a/pkgs/development/python2-modules/enum/default.nix b/pkgs/development/python2-modules/enum/default.nix
new file mode 100644
index 000000000000..db827601d5de
--- /dev/null
+++ b/pkgs/development/python2-modules/enum/default.nix
@@ -0,0 +1,26 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, isPy3k
+, isPyPy
+}:
+
+buildPythonPackage rec {
+  pname = "enum";
+  version = "0.4.7";
+  disabled = isPy3k;
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "001iq0yqs9f5bslvl793bhkcs71k5km9kv8yrj5h0lfsgrcg6z4c";
+  };
+
+  doCheck = !isPyPy;
+
+  meta = with lib; {
+    homepage = "https://pypi.python.org/pypi/enum/";
+    description = "Robust enumerated type support in Python";
+    license = licenses.gpl2;
+  };
+
+}
diff --git a/pkgs/development/python2-modules/filelock/default.nix b/pkgs/development/python2-modules/filelock/default.nix
new file mode 100644
index 000000000000..401fdf582ffb
--- /dev/null
+++ b/pkgs/development/python2-modules/filelock/default.nix
@@ -0,0 +1,22 @@
+{ lib, buildPythonPackage, fetchPypi, setuptools-scm }:
+
+buildPythonPackage rec {
+  pname = "filelock";
+  version = "3.2.1";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "1qry67zv2pmz8px6wdfbjqv75nmryy2ac7asqgs6q6db2722kpcw";
+  };
+
+  nativeBuildInputs = [
+    setuptools-scm
+  ];
+
+  meta = with lib; {
+    homepage = "https://github.com/benediktschmitt/py-filelock";
+    description = "A platform independent file lock for Python";
+    license = licenses.unlicense;
+    maintainers = with maintainers; [ henkkalkwater ];
+  };
+}
diff --git a/pkgs/development/python2-modules/flask/default.nix b/pkgs/development/python2-modules/flask/default.nix
new file mode 100644
index 000000000000..27f436c3c53c
--- /dev/null
+++ b/pkgs/development/python2-modules/flask/default.nix
@@ -0,0 +1,28 @@
+{ lib, buildPythonPackage, fetchPypi
+, itsdangerous, click, werkzeug, jinja2, pytest }:
+
+buildPythonPackage rec {
+  version = "1.1.2";
+  pname = "Flask";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060";
+  };
+
+  checkInputs = [ pytest ];
+  propagatedBuildInputs = [ itsdangerous click werkzeug jinja2 ];
+
+  checkPhase = ''
+    py.test
+  '';
+
+  # Tests require extra dependencies
+  doCheck = false;
+
+  meta = with lib; {
+    homepage = "http://flask.pocoo.org/";
+    description = "A microframework based on Werkzeug, Jinja 2, and good intentions";
+    license = licenses.bsd3;
+  };
+}
diff --git a/pkgs/development/python2-modules/freezegun/default.nix b/pkgs/development/python2-modules/freezegun/default.nix
new file mode 100644
index 000000000000..7f77616f2a4e
--- /dev/null
+++ b/pkgs/development/python2-modules/freezegun/default.nix
@@ -0,0 +1,29 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, python-dateutil
+, six
+, mock
+, nose
+, pytest
+}:
+
+buildPythonPackage rec {
+  pname = "freezegun";
+  version = "0.3.15";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "e2062f2c7f95cc276a834c22f1a17179467176b624cc6f936e8bc3be5535ad1b";
+  };
+
+  propagatedBuildInputs = [ python-dateutil six ];
+  checkInputs = [ mock nose pytest ];
+
+  meta = with lib; {
+    description = "FreezeGun: Let your Python tests travel through time";
+    homepage = "https://github.com/spulec/freezegun";
+    license = licenses.asl20;
+  };
+
+}
diff --git a/pkgs/development/python2-modules/futures/default.nix b/pkgs/development/python2-modules/futures/default.nix
new file mode 100644
index 000000000000..bc19a31927af
--- /dev/null
+++ b/pkgs/development/python2-modules/futures/default.nix
@@ -0,0 +1,27 @@
+{ lib, buildPythonPackage, fetchPypi, isPy3k, python, stdenv }:
+
+buildPythonPackage rec {
+  pname = "futures";
+  version = "3.3.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "7e033af76a5e35f58e56da7a91e687706faf4e7bdfb2cbc3f2cca6b9bcda9794";
+  };
+
+  # This module is for backporting functionality to Python 2.x, it's builtin in py3k
+  disabled = isPy3k;
+
+  checkPhase = ''
+    ${python.interpreter} test_futures.py
+  '';
+
+  doCheck = !stdenv.isDarwin;
+
+  meta = with lib; {
+    description = "Backport of the concurrent.futures package from Python 3.2";
+    homepage = "https://github.com/agronholm/pythonfutures";
+    license = licenses.bsd2;
+    maintainers = with maintainers; [  ];
+  };
+}
diff --git a/pkgs/development/python2-modules/google-apputils/default.nix b/pkgs/development/python2-modules/google-apputils/default.nix
new file mode 100644
index 000000000000..225adf348d1a
--- /dev/null
+++ b/pkgs/development/python2-modules/google-apputils/default.nix
@@ -0,0 +1,41 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, isPy3k
+, pytz
+, gflags
+, python-dateutil
+, mox
+, python
+}:
+
+buildPythonPackage rec {
+  pname = "google-apputils";
+  version = "0.4.2";
+  disabled = isPy3k;
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "0afw0gxmh0yw5g7xsmw49gs8bbp0zyhbh6fr1b0h48f3a439v5a7";
+  };
+
+  preConfigure = ''
+    sed -i '/ez_setup/d' setup.py
+  '';
+
+  propagatedBuildInputs = [ pytz gflags python-dateutil mox ];
+
+  checkPhase = ''
+    ${python.executable} setup.py google_test
+  '';
+
+  # ERROR:root:Trying to access flag test_tmpdir before flags were parsed.
+  doCheck = false;
+
+  meta = with lib; {
+    description = "Google Application Utilities for Python";
+    homepage = "https://github.com/google/google-apputils";
+    license = licenses.asl20;
+    maintainers = with maintainers; [ SuperSandro2000 ];
+  };
+}
diff --git a/pkgs/development/python2-modules/httpretty/default.nix b/pkgs/development/python2-modules/httpretty/default.nix
new file mode 100644
index 000000000000..92ed5c6616e0
--- /dev/null
+++ b/pkgs/development/python2-modules/httpretty/default.nix
@@ -0,0 +1,52 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, tornado
+, requests
+, httplib2
+, sure
+, nose
+, nose-exclude
+, coverage
+, rednose
+, nose-randomly
+, six
+, mock
+}:
+
+buildPythonPackage rec {
+  pname = "httpretty";
+  version = "0.9.7";
+
+  # drop this for version > 0.9.7
+  # Flaky tests: https://github.com/gabrielfalcao/HTTPretty/pull/394
+  doCheck = lib.versionAtLeast version "0.9.8";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "66216f26b9d2c52e81808f3e674a6fb65d4bf719721394a1a9be926177e55fbe";
+  };
+
+  propagatedBuildInputs = [ six ];
+
+  checkInputs = [ nose sure coverage mock rednose
+    # Following not declared in setup.py
+    nose-randomly requests tornado httplib2 nose-exclude
+  ];
+
+  __darwinAllowLocalNetworking = true;
+
+  # Those flaky tests are failing intermittently on all platforms
+  NOSE_EXCLUDE = lib.concatStringsSep "," [
+    "tests.functional.test_httplib2.test_callback_response"
+    "tests.functional.test_requests.test_streaming_responses"
+    "tests.functional.test_httplib2.test_callback_response"
+    "tests.functional.test_requests.test_httpretty_should_allow_adding_and_overwritting_by_kwargs_u2"
+  ];
+
+  meta = with lib; {
+    homepage = "https://httpretty.readthedocs.org/";
+    description = "HTTP client request mocking tool";
+    license = licenses.mit;
+  };
+}
diff --git a/pkgs/development/python2-modules/hypothesis/default.nix b/pkgs/development/python2-modules/hypothesis/default.nix
new file mode 100644
index 000000000000..47bc8860bc54
--- /dev/null
+++ b/pkgs/development/python2-modules/hypothesis/default.nix
@@ -0,0 +1,45 @@
+{ lib, buildPythonPackage, fetchFromGitHub
+, isPy3k, attrs, coverage, enum34, pexpect
+, doCheck ? true, pytest, pytest-xdist, flaky, mock
+, sortedcontainers
+}:
+buildPythonPackage rec {
+  # https://hypothesis.readthedocs.org/en/latest/packaging.html
+
+  # Hypothesis has optional dependencies on the following libraries
+  # pytz fake_factory django numpy pytest
+  # If you need these, you can just add them to your environment.
+
+  version = "4.57.1";
+  pname = "hypothesis";
+
+  # Use github tarballs that includes tests
+  src = fetchFromGitHub {
+    owner = "HypothesisWorks";
+    repo = "hypothesis-python";
+    rev = "hypothesis-python-${version}";
+    sha256 = "1qcpcrk6892hzyjsdr581pw6i4fj9035nv89mcjrcrzcmycdlfds";
+  };
+
+  postUnpack = "sourceRoot=$sourceRoot/hypothesis-python";
+
+  propagatedBuildInputs = [
+    attrs
+    coverage
+    sortedcontainers
+  ] ++ lib.optional (!isPy3k) enum34;
+
+  checkInputs = [ pytest pytest-xdist flaky mock pexpect ];
+  inherit doCheck;
+
+  checkPhase = ''
+    rm tox.ini # This file changes how py.test runs and breaks it
+    py.test tests/cover
+  '';
+
+  meta = with lib; {
+    description = "A Python library for property based testing";
+    homepage = "https://github.com/HypothesisWorks/hypothesis";
+    license = licenses.mpl20;
+  };
+}
diff --git a/pkgs/development/python2-modules/idna/default.nix b/pkgs/development/python2-modules/idna/default.nix
new file mode 100644
index 000000000000..9a1c1dc271f1
--- /dev/null
+++ b/pkgs/development/python2-modules/idna/default.nix
@@ -0,0 +1,23 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, pytestCheckHook
+}:
+
+buildPythonPackage rec {
+  pname = "idna";
+  version = "2.10";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6";
+  };
+
+  checkInputs = [ pytestCheckHook ];
+
+  meta = {
+    homepage = "https://github.com/kjd/idna/";
+    description = "Internationalized Domain Names in Applications (IDNA)";
+    license = lib.licenses.bsd3;
+  };
+}
diff --git a/pkgs/development/python2-modules/importlib-metadata/default.nix b/pkgs/development/python2-modules/importlib-metadata/default.nix
new file mode 100644
index 000000000000..f50b2c07c1da
--- /dev/null
+++ b/pkgs/development/python2-modules/importlib-metadata/default.nix
@@ -0,0 +1,37 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, setuptools-scm
+, zipp
+, pathlib2
+, contextlib2
+, configparser
+, isPy3k
+}:
+
+buildPythonPackage rec {
+  pname = "importlib-metadata";
+  version = "2.1.1";
+
+  src = fetchPypi {
+    pname = "importlib_metadata";
+    inherit version;
+    sha256 = "1pdmsmwagimn0lsl4x7sg3skcr2fvzqpv2pjd1rh7yrm5gzrxpmq";
+  };
+
+  nativeBuildInputs = [ setuptools-scm ];
+
+  propagatedBuildInputs = [ zipp ]
+    ++ lib.optionals (!isPy3k) [ pathlib2 contextlib2 configparser ];
+
+  # Cyclic dependencies
+  doCheck = false;
+
+  pythonImportsCheck = [ "importlib_metadata" ];
+
+  meta = with lib; {
+    description = "Read metadata from Python packages";
+    homepage = "https://importlib-metadata.readthedocs.io/";
+    license = licenses.asl20;
+  };
+}
diff --git a/pkgs/development/python2-modules/ipaddr/default.nix b/pkgs/development/python2-modules/ipaddr/default.nix
new file mode 100644
index 000000000000..b29ee9179287
--- /dev/null
+++ b/pkgs/development/python2-modules/ipaddr/default.nix
@@ -0,0 +1,23 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, isPy3k
+}:
+
+buildPythonPackage rec {
+  pname = "ipaddr";
+  version = "2.2.0";
+  disabled = isPy3k;
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "1ml8r8z3f0mnn381qs1snbffa920i9ycp6mm2am1d3aqczkdz4j0";
+  };
+
+  meta = with lib; {
+    description = "Google's IP address manipulation library";
+    homepage = "https://github.com/google/ipaddr-py";
+    license = licenses.asl20;
+  };
+
+}
diff --git a/pkgs/development/python2-modules/itsdangerous/default.nix b/pkgs/development/python2-modules/itsdangerous/default.nix
new file mode 100644
index 000000000000..d1669a1ed5bf
--- /dev/null
+++ b/pkgs/development/python2-modules/itsdangerous/default.nix
@@ -0,0 +1,21 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+}:
+
+buildPythonPackage rec {
+  pname = "itsdangerous";
+  version = "1.1.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19";
+  };
+
+  meta = with lib; {
+    description = "Helpers to pass trusted data to untrusted environments and back";
+    homepage = "https://pypi.python.org/pypi/itsdangerous/";
+    license = licenses.bsd0;
+  };
+
+}
diff --git a/pkgs/development/python2-modules/jinja2/default.nix b/pkgs/development/python2-modules/jinja2/default.nix
new file mode 100644
index 000000000000..02127a50df74
--- /dev/null
+++ b/pkgs/development/python2-modules/jinja2/default.nix
@@ -0,0 +1,42 @@
+{ lib, stdenv
+, buildPythonPackage
+, isPy3k
+, fetchPypi
+, pytest
+, markupsafe
+, setuptools
+}:
+
+buildPythonPackage rec {
+  pname = "Jinja2";
+  version = "2.11.3";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6";
+  };
+
+  checkInputs = [ pytest ];
+  propagatedBuildInputs = [ markupsafe setuptools ];
+
+  # Multiple tests run out of stack space on 32bit systems with python2.
+  # See https://github.com/pallets/jinja/issues/1158
+  # warnings are no longer being filtered correctly for python2
+  doCheck = !stdenv.is32bit && isPy3k;
+
+  checkPhase = ''
+    pytest -v tests -W ignore::DeprecationWarning
+  '';
+
+  meta = with lib; {
+    homepage = "http://jinja.pocoo.org/";
+    description = "Stand-alone template engine";
+    license = licenses.bsd3;
+    longDescription = ''
+      Jinja2 is a template engine written in pure Python. It provides a
+      Django inspired non-XML syntax but supports inline expressions and
+      an optional sandboxed environment.
+    '';
+    maintainers = with maintainers; [ pierron sjourdois ];
+  };
+}
diff --git a/pkgs/development/python2-modules/libcloud/default.nix b/pkgs/development/python2-modules/libcloud/default.nix
new file mode 100644
index 000000000000..504e7753a978
--- /dev/null
+++ b/pkgs/development/python2-modules/libcloud/default.nix
@@ -0,0 +1,39 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, isPy27
+, mock
+, pycrypto
+, requests
+, pytest-runner
+, pytest
+, requests-mock
+, typing
+, backports_ssl_match_hostname
+}:
+
+buildPythonPackage rec {
+  pname = "apache-libcloud";
+  version = "2.8.3";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "70096690b24a7832cc5abdfda1954b49fddc1c09a348a1e6caa781ac867ed4c6";
+  };
+
+  checkInputs = [ mock pytest pytest-runner requests-mock ];
+  propagatedBuildInputs = [ pycrypto requests ]
+    ++ lib.optionals isPy27 [ typing backports_ssl_match_hostname ];
+
+  preConfigure = "cp libcloud/test/secrets.py-dist libcloud/test/secrets.py";
+
+  # requires a certificates file
+  doCheck = false;
+
+  meta = with lib; {
+    description = "A unified interface to many cloud providers";
+    homepage = "https://libcloud.apache.org/";
+    license = licenses.asl20;
+  };
+
+}
diff --git a/pkgs/development/python2-modules/lpod/default.nix b/pkgs/development/python2-modules/lpod/default.nix
new file mode 100644
index 000000000000..9c719d234f89
--- /dev/null
+++ b/pkgs/development/python2-modules/lpod/default.nix
@@ -0,0 +1,31 @@
+{ lib
+, buildPythonPackage
+, fetchFromGitHub
+, lxml
+, docutils
+, pillow
+, isPy3k
+}:
+
+buildPythonPackage {
+  version = "1.1.7";
+  pname = "python-lpod";
+  # lpod library currently does not support Python 3.x
+  disabled = isPy3k;
+
+  propagatedBuildInputs = [ lxml docutils pillow ];
+
+  src = fetchFromGitHub {
+    owner = "lpod";
+    repo = "lpod-python";
+    rev = "dee32120ee582ff337b0c52a95a9a87cca71fd67";
+    sha256 = "1mikvzp27wxkzpr2lii4wg1hhx8h610agckqynvsrdc8v3nw9ciw";
+  };
+
+  meta = with lib; {
+    homepage = "https://github.com/lpod/lpod-python/";
+    description = "Library implementing the ISO/IEC 26300 OpenDocument Format standard (ODF) ";
+    license = licenses.gpl3;
+  };
+
+}
diff --git a/pkgs/development/python2-modules/marisa/default.nix b/pkgs/development/python2-modules/marisa/default.nix
new file mode 100644
index 000000000000..93a4ccb959f7
--- /dev/null
+++ b/pkgs/development/python2-modules/marisa/default.nix
@@ -0,0 +1,29 @@
+{ lib, buildPythonPackage, fetchFromGitHub, marisa, swig
+, isPy3k
+}:
+
+buildPythonPackage rec {
+  pname = "marisa";
+  version = "1.3.40";
+
+  disabled = isPy3k;
+
+  src = fetchFromGitHub {
+    owner = "s-yata";
+    repo  = "marisa-trie";
+    rev   = "8dba9850b89d7828ebf33b8ab84df2b54d31260b";
+    sha256 = "0pkp9fggk53lxlicfwrskgx33qplc4v6njbavlnz4x4z63zd4933";
+  };
+
+  nativeBuildInputs = [ swig marisa ];
+  buildInputs = [ marisa ];
+
+  sourceRoot = "${src.name}/bindings/python";
+
+  meta = with lib; {
+    description = "Python binding for marisa package (do not confuse with marisa-trie python bindings)";
+    homepage    = "https://github.com/s-yata/marisa-trie";
+    license     = with licenses; [ bsd2 lgpl2 ];
+    maintainers = with maintainers; [ vanzef ];
+  };
+}
diff --git a/pkgs/development/python2-modules/markdown/default.nix b/pkgs/development/python2-modules/markdown/default.nix
new file mode 100644
index 000000000000..13ed2f1744a2
--- /dev/null
+++ b/pkgs/development/python2-modules/markdown/default.nix
@@ -0,0 +1,33 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, setuptools
+, nose
+, pyyaml
+, pythonOlder
+, importlib-metadata
+}:
+
+buildPythonPackage rec {
+  pname = "Markdown";
+  version = "3.1.1";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "2e50876bcdd74517e7b71f3e7a76102050edec255b3983403f1a63e7c8a41e7a";
+  };
+
+  propagatedBuildInputs = [
+    setuptools
+  ] ++ lib.optionals (pythonOlder "3.8") [
+    importlib-metadata
+  ];
+
+  checkInputs = [ nose pyyaml ];
+
+  meta = {
+    description = "A Python implementation of John Gruber's Markdown with Extension support";
+    homepage = "https://github.com/Python-Markdown/markdown";
+    license = lib.licenses.bsd3;
+  };
+}
diff --git a/pkgs/development/python2-modules/markupsafe/default.nix b/pkgs/development/python2-modules/markupsafe/default.nix
new file mode 100644
index 000000000000..ae0878c7a972
--- /dev/null
+++ b/pkgs/development/python2-modules/markupsafe/default.nix
@@ -0,0 +1,22 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+}:
+
+buildPythonPackage rec {
+  pname = "MarkupSafe";
+  version = "1.1.1";
+
+ src = fetchPypi {
+    inherit pname version;
+    sha256 = "29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b";
+  };
+
+  meta = with lib; {
+    description = "Implements a XML/HTML/XHTML Markup safe string";
+    homepage = "http://dev.pocoo.org";
+    license = licenses.bsd3;
+    maintainers = with maintainers; [ domenkozar ];
+  };
+
+}
diff --git a/pkgs/development/python2-modules/mock/default.nix b/pkgs/development/python2-modules/mock/default.nix
new file mode 100644
index 000000000000..190297b41a2d
--- /dev/null
+++ b/pkgs/development/python2-modules/mock/default.nix
@@ -0,0 +1,44 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, isPy27
+, funcsigs
+, six
+, pbr
+, python
+, pytest
+}:
+
+buildPythonPackage rec {
+  pname = "mock";
+  version = "3.0.5";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "83657d894c90d5681d62155c82bda9c1187827525880eda8ff5df4ec813437c3";
+  };
+
+  propagatedBuildInputs = [ six pbr ] ++ lib.optionals isPy27 [ funcsigs ];
+
+  # On PyPy for Python 2.7 in particular, Mock's tests have a known failure.
+  # Mock upstream has a decoration to disable the failing test and make
+  # everything pass, but it is not yet released. The commit:
+  # https://github.com/testing-cabal/mock/commit/73bfd51b7185#diff-354f30a63fb0907d4ad57269548329e3L12
+  #doCheck = !(python.isPyPy && python.isPy27);
+  doCheck = false; # Infinite recursion pytest
+
+  checkPhase = ''
+    ${python.interpreter} -m unittest discover
+  '';
+
+  checkInputs = [
+    pytest
+  ];
+
+  meta = with lib; {
+    description = "Mock objects for Python";
+    homepage = "http://python-mock.sourceforge.net/";
+    license = licenses.bsd2;
+  };
+
+}
diff --git a/pkgs/development/python2-modules/more-itertools/default.nix b/pkgs/development/python2-modules/more-itertools/default.nix
new file mode 100644
index 000000000000..f9a6ac732e2e
--- /dev/null
+++ b/pkgs/development/python2-modules/more-itertools/default.nix
@@ -0,0 +1,31 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, nose
+, six
+, stdenv
+}:
+
+
+buildPythonPackage rec {
+  pname = "more-itertools";
+  version = "5.0.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4";
+  };
+
+  checkInputs = [ nose ];
+  propagatedBuildInputs = [ six ];
+
+  # iterable = range(10 ** 10)  # Is efficiently reversible
+  # OverflowError: Python int too large to convert to C long
+  doCheck = !stdenv.hostPlatform.is32bit;
+
+  meta = {
+    homepage = "https://more-itertools.readthedocs.org";
+    description = "Expansion of the itertools module";
+    license = lib.licenses.mit;
+  };
+}
diff --git a/pkgs/development/python2-modules/mutagen/default.nix b/pkgs/development/python2-modules/mutagen/default.nix
new file mode 100644
index 000000000000..7f2e9f452b4d
--- /dev/null
+++ b/pkgs/development/python2-modules/mutagen/default.nix
@@ -0,0 +1,34 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, hypothesis
+, pycodestyle
+, pyflakes
+, pytest
+, setuptools
+, pkgs
+}:
+
+buildPythonPackage rec {
+  pname = "mutagen";
+  version = "1.43.1";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "d873baeb7815311d3420aab0a1d83f050f628228cbc2d6045a14a16460411bc9";
+  };
+
+  propagatedBuildInputs = [ setuptools ];
+  checkInputs = [
+    pkgs.faad2 pkgs.flac pkgs.vorbis-tools pkgs.liboggz
+    pkgs.glibcLocales pycodestyle pyflakes pytest hypothesis
+  ];
+  LC_ALL = "en_US.UTF-8";
+
+  meta = with lib; {
+    description = "Python multimedia tagging library";
+    homepage = "https://mutagen.readthedocs.io";
+    license = licenses.lgpl2Plus;
+    platforms = platforms.all;
+  };
+}
diff --git a/pkgs/development/python2-modules/numpy/default.nix b/pkgs/development/python2-modules/numpy/default.nix
new file mode 100644
index 000000000000..b1d71bd66f36
--- /dev/null
+++ b/pkgs/development/python2-modules/numpy/default.nix
@@ -0,0 +1,99 @@
+{ lib
+, fetchPypi
+, python
+, buildPythonPackage
+, gfortran
+, pytest
+, blas
+, lapack
+, writeTextFile
+, isPyPy
+, cython
+, setuptoolsBuildHook
+ }:
+
+assert (!blas.isILP64) && (!lapack.isILP64);
+
+let
+  cfg = writeTextFile {
+    name = "site.cfg";
+    text = (lib.generators.toINI {} {
+      ${blas.implementation} = {
+        include_dirs = "${lib.getDev blas}/include:${lib.getDev lapack}/include";
+        library_dirs = "${blas}/lib:${lapack}/lib";
+        runtime_library_dirs = "${blas}/lib:${lapack}/lib";
+        libraries = "lapack,lapacke,blas,cblas";
+      };
+      lapack = {
+        include_dirs = "${lib.getDev lapack}/include";
+        library_dirs = "${lapack}/lib";
+        runtime_library_dirs = "${lapack}/lib";
+      };
+      blas = {
+        include_dirs = "${lib.getDev blas}/include";
+        library_dirs = "${blas}/lib";
+        runtime_library_dirs = "${blas}/lib";
+      };
+    });
+  };
+in buildPythonPackage rec {
+  pname = "numpy";
+  version = "1.16.6";
+  format = "pyproject.toml";
+
+  src = fetchPypi {
+    inherit pname version;
+    extension = "zip";
+    sha256 = "e5cf3fdf13401885e8eea8170624ec96225e2174eb0c611c6f26dd33b489e3ff";
+  };
+
+  nativeBuildInputs = [ gfortran pytest cython setuptoolsBuildHook ];
+  buildInputs = [ blas lapack ];
+
+  patches = lib.optionals python.hasDistutilsCxxPatch [
+    # We patch cpython/distutils to fix https://bugs.python.org/issue1222585
+    # Patching of numpy.distutils is needed to prevent it from undoing the
+    # patch to distutils.
+    ./numpy-distutils-C++.patch
+  ];
+
+  preConfigure = ''
+    sed -i 's/-faltivec//' numpy/distutils/system_info.py
+    export NPY_NUM_BUILD_JOBS=$NIX_BUILD_CORES
+    export OMP_NUM_THREADS=$((NIX_BUILD_CORES > 64 ? 64 : NIX_BUILD_CORES))
+  '';
+
+  preBuild = ''
+    ln -s ${cfg} site.cfg
+  '';
+
+  enableParallelBuilding = true;
+
+  doCheck = !isPyPy; # numpy 1.16+ hits a bug in pypy's ctypes, using either numpy or pypy HEAD fixes this (https://github.com/numpy/numpy/issues/13807)
+
+  checkPhase = ''
+    runHook preCheck
+    pushd dist
+    ${python.interpreter} -c 'import numpy; numpy.test("fast", verbose=10)'
+    popd
+    runHook postCheck
+  '';
+
+  passthru = {
+    # just for backwards compatibility
+    blas = blas.provider;
+    blasImplementation = blas.implementation;
+    inherit cfg;
+  };
+
+  # Disable test
+  # - test_large_file_support: takes a long time and can cause the machine to run out of disk space
+  NOSE_EXCLUDE="test_large_file_support";
+
+  meta = {
+    description = "Scientific tools for Python";
+    homepage = "https://numpy.org/";
+    license = lib.licenses.bsd3;
+    maintainers = with lib.maintainers; [ fridh ];
+  };
+}
diff --git a/pkgs/development/python2-modules/numpy/numpy-distutils-C++.patch b/pkgs/development/python2-modules/numpy/numpy-distutils-C++.patch
new file mode 100644
index 000000000000..b2626ea26e5b
--- /dev/null
+++ b/pkgs/development/python2-modules/numpy/numpy-distutils-C++.patch
@@ -0,0 +1,30 @@
+diff --git a/numpy/distutils/unixccompiler.py b/numpy/distutils/unixccompiler.py
+--- a/numpy/distutils/unixccompiler.py
++++ b/numpy/distutils/unixccompiler.py
+@@ -44,8 +44,6 @@ def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts
+         if opt not in llink_s:
+             self.linker_so = llink_s.split() + opt.split()
+ 
+-    display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src)
+-
+     # gcc style automatic dependencies, outputs a makefile (-MF) that lists
+     # all headers needed by a c file as a side effect of compilation (-MMD)
+     if getattr(self, '_auto_depends', False):
+@@ -54,8 +52,15 @@ def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts
+         deps = []
+ 
+     try:
+-        self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + deps +
+-                   extra_postargs, display = display)
++        if self.detect_language(src) == 'c++':
++            display = '%s: %s' % (os.path.basename(self.compiler_so_cxx[0]), src)
++            self.spawn(self.compiler_so_cxx + cc_args + [src, '-o', obj] + deps +
++                       extra_postargs, display = display)
++        else:
++            display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src)
++            self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + deps +
++                       extra_postargs, display = display)
++
+     except DistutilsExecError:
+         msg = str(get_exception())
+         raise CompileError(msg)
diff --git a/pkgs/development/python2-modules/packaging/default.nix b/pkgs/development/python2-modules/packaging/default.nix
new file mode 100644
index 000000000000..0f9e61859a16
--- /dev/null
+++ b/pkgs/development/python2-modules/packaging/default.nix
@@ -0,0 +1,39 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, pyparsing
+, six
+, pytestCheckHook
+, pretend
+}:
+
+# We keep 20.4 because it uses setuptools instead of flit-core
+# which requires Python 3 to build a universal wheel.
+
+buildPythonPackage rec {
+  pname = "packaging";
+  version = "20.4";
+  format = "setuptools";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8";
+  };
+
+  propagatedBuildInputs = [ pyparsing six ];
+
+  checkInputs = [
+    pytestCheckHook
+    pretend
+  ];
+
+  # Prevent circular dependency
+  doCheck = false;
+
+  meta = with lib; {
+    description = "Core utilities for Python packages";
+    homepage = "https://github.com/pypa/packaging";
+    license = [ licenses.bsd2 licenses.asl20 ];
+    maintainers = with maintainers; [ bennofs ];
+  };
+}
diff --git a/pkgs/development/python2-modules/pillow/default.nix b/pkgs/development/python2-modules/pillow/default.nix
new file mode 100644
index 000000000000..61242c894a89
--- /dev/null
+++ b/pkgs/development/python2-modules/pillow/default.nix
@@ -0,0 +1,47 @@
+{ lib, stdenv, buildPythonPackage, fetchPypi, isPyPy, isPy3k
+, olefile, freetype, libjpeg, zlib, libtiff, libwebp, tcl, lcms2, tk, libX11
+, openjpeg, libimagequant, pyroma, numpy, pytestCheckHook
+}@args:
+
+import ./generic.nix (rec {
+  pname = "Pillow";
+  version = "6.2.2";
+
+  disabled = !isPy3k;
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "0l5rv8jkdrb5q846v60v03mcq64yrhklidjkgwv6s1pda71g17yv";
+  };
+
+  meta = with lib; {
+    homepage = "https://python-pillow.org/";
+    description = "The friendly PIL fork (Python Imaging Library)";
+    longDescription = ''
+      The Python Imaging Library (PIL) adds image processing
+      capabilities to your Python interpreter.  This library
+      supports many file formats, and provides powerful image
+      processing and graphics capabilities.
+    '';
+    license = "http://www.pythonware.com/products/pil/license.htm";
+    maintainers = with maintainers; [ goibhniu prikhi SuperSandro2000 ];
+    knownVulnerabilities = [
+      "CVE-2020-10177"
+      "CVE-2020-10378"
+      "CVE-2020-10379"
+      "CVE-2020-10994"
+      "CVE-2020-11538"
+      "CVE-2020-35653"
+      "CVE-2020-35654"
+      "CVE-2020-35655"
+      "CVE-2021-25289"
+      "CVE-2021-25290"
+      "CVE-2021-25291"
+      "CVE-2021-25292"
+      "CVE-2021-25293"
+      "CVE-2021-27921"
+      "CVE-2021-27922"
+      "CVE-2021-27923"
+    ];
+  };
+} // args )
diff --git a/pkgs/development/python2-modules/pillow/generic.nix b/pkgs/development/python2-modules/pillow/generic.nix
new file mode 100644
index 000000000000..3e33f1a8aa0f
--- /dev/null
+++ b/pkgs/development/python2-modules/pillow/generic.nix
@@ -0,0 +1,77 @@
+{ pname
+, version
+, disabled
+, src
+, meta
+, ...
+}@args:
+
+with args;
+
+buildPythonPackage rec {
+  inherit pname version src meta;
+
+  # Disable imagefont tests, because they don't work well with infinality:
+  # https://github.com/python-pillow/Pillow/issues/1259
+  postPatch = ''
+    rm Tests/test_imagefont.py
+  '';
+
+  # Disable darwin tests which require executables: `iconutil` and `screencapture`
+  disabledTests = lib.optionals stdenv.isDarwin [
+    "test_grab"
+    "test_grabclipboard"
+    "test_save"
+
+    # pillow-simd
+    "test_roundtrip"
+    "test_basic"
+  ] ++ lib.optionals (lib.versions.major version == "6") [
+    # RuntimeError: Error setting from dictionary
+    "test_custom_metadata"
+  ];
+
+  propagatedBuildInputs = [ olefile ]
+    ++ lib.optionals (lib.versionAtLeast version "8.2.0") [ defusedxml ];
+
+  checkInputs = [ pytestCheckHook pyroma numpy ];
+
+  buildInputs = [ freetype libjpeg openjpeg libimagequant zlib libtiff libwebp tcl lcms2 ]
+    ++ lib.optionals (lib.versionAtLeast version "7.1.0") [ libxcb ]
+    ++ lib.optionals (isPyPy) [ tk libX11 ];
+
+  # NOTE: we use LCMS_ROOT as WEBP root since there is not other setting for webp.
+  # NOTE: The Pillow install script will, by default, add paths like /usr/lib
+  # and /usr/include to the search paths. This can break things when building
+  # on a non-NixOS system that has some libraries installed that are not
+  # installed in Nix (for example, Arch Linux has jpeg2000 but Nix doesn't
+  # build Pillow with this support). We patch the `disable_platform_guessing`
+  # setting here, instead of passing the `--disable-platform-guessing`
+  # command-line option, since the command-line option doesn't work when we run
+  # tests.
+  preConfigure = let
+    libinclude' = pkg: ''"${pkg.out}/lib", "${pkg.out}/include"'';
+    libinclude = pkg: ''"${pkg.out}/lib", "${pkg.dev}/include"'';
+  in ''
+    sed -i "setup.py" \
+        -e 's|^FREETYPE_ROOT =.*$|FREETYPE_ROOT = ${libinclude freetype}|g ;
+            s|^JPEG_ROOT =.*$|JPEG_ROOT = ${libinclude libjpeg}|g ;
+            s|^JPEG2K_ROOT =.*$|JPEG2K_ROOT = ${libinclude openjpeg}|g ;
+            s|^IMAGEQUANT_ROOT =.*$|IMAGEQUANT_ROOT = ${libinclude' libimagequant}|g ;
+            s|^ZLIB_ROOT =.*$|ZLIB_ROOT = ${libinclude zlib}|g ;
+            s|^LCMS_ROOT =.*$|LCMS_ROOT = ${libinclude lcms2}|g ;
+            s|^TIFF_ROOT =.*$|TIFF_ROOT = ${libinclude libtiff}|g ;
+            s|^TCL_ROOT=.*$|TCL_ROOT = ${libinclude' tcl}|g ;
+            s|self\.disable_platform_guessing = None|self.disable_platform_guessing = True|g ;'
+    export LDFLAGS="$LDFLAGS -L${libwebp}/lib"
+    export CFLAGS="$CFLAGS -I${libwebp}/include"
+  '' + lib.optionalString (lib.versionAtLeast version "7.1.0") ''
+    export LDFLAGS="$LDFLAGS -L${libxcb}/lib"
+    export CFLAGS="$CFLAGS -I${libxcb.dev}/include"
+  '' + lib.optionalString stdenv.isDarwin ''
+    # Remove impurities
+    substituteInPlace setup.py \
+      --replace '"/Library/Frameworks",' "" \
+      --replace '"/System/Library/Frameworks"' ""
+  '';
+}
diff --git a/pkgs/development/python2-modules/pip/default.nix b/pkgs/development/python2-modules/pip/default.nix
new file mode 100644
index 000000000000..e3666d6a7961
--- /dev/null
+++ b/pkgs/development/python2-modules/pip/default.nix
@@ -0,0 +1,41 @@
+{ lib
+, buildPythonPackage
+, bootstrapped-pip
+, fetchFromGitHub
+, mock
+, scripttest
+, virtualenv
+, pretend
+, pytest
+}:
+
+buildPythonPackage rec {
+  pname = "pip";
+  version = "20.3.4";
+  format = "other";
+
+  src = fetchFromGitHub {
+    owner = "pypa";
+    repo = pname;
+    rev = version;
+    sha256 = "0hkhs9yc1cjdj1gn9wkycd3sy65c05q8k8rhqgsm5jbpksfssiwn";
+    name = "${pname}-${version}-source";
+  };
+
+  nativeBuildInputs = [ bootstrapped-pip ];
+
+  # pip detects that we already have bootstrapped_pip "installed", so we need
+  # to force it a little.
+  pipInstallFlags = [ "--ignore-installed" ];
+
+  checkInputs = [ mock scripttest virtualenv pretend pytest ];
+  # Pip wants pytest, but tests are not distributed
+  doCheck = false;
+
+  meta = {
+    description = "The PyPA recommended tool for installing Python packages";
+    license = with lib.licenses; [ mit ];
+    homepage = "https://pip.pypa.io/";
+    priority = 10;
+  };
+}
diff --git a/pkgs/development/python2-modules/pluggy/default.nix b/pkgs/development/python2-modules/pluggy/default.nix
new file mode 100644
index 000000000000..30fa2e1945b2
--- /dev/null
+++ b/pkgs/development/python2-modules/pluggy/default.nix
@@ -0,0 +1,34 @@
+{ buildPythonPackage
+, lib
+, fetchPypi
+, setuptools-scm
+, importlib-metadata
+}:
+
+buildPythonPackage rec {
+  pname = "pluggy";
+  version = "0.13.1";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0";
+  };
+
+  checkPhase = ''
+    py.test
+  '';
+
+  # To prevent infinite recursion with pytest
+  doCheck = false;
+
+  nativeBuildInputs = [ setuptools-scm ];
+
+  propagatedBuildInputs = [ importlib-metadata ];
+
+  meta = {
+    description = "Plugin and hook calling mechanisms for Python";
+    homepage = "https://github.com/pytest-dev/pluggy";
+    license = lib.licenses.mit;
+    maintainers = with lib.maintainers; [ ];
+  };
+}
diff --git a/pkgs/development/python2-modules/prettytable/default.nix b/pkgs/development/python2-modules/prettytable/default.nix
new file mode 100644
index 000000000000..8191e9b5f579
--- /dev/null
+++ b/pkgs/development/python2-modules/prettytable/default.nix
@@ -0,0 +1,37 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, glibcLocales
+, setuptools-scm
+, wcwidth
+}:
+
+buildPythonPackage rec {
+  pname = "prettytable";
+  version = "1.0.1";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "0wcpp1nkicrswb353yn6xd2x535cpif62nw5rgz33c1wj0wzbdvb";
+  };
+
+  nativeBuildInputs = [ setuptools-scm ];
+  buildInputs = [ glibcLocales ];
+
+  propagatedBuildInputs = [ wcwidth ];
+
+  preCheck = ''
+    export LANG="en_US.UTF-8"
+  '';
+
+  # no test no longer available in pypi package
+  doCheck = false;
+  pythonImportsCheck = [ "prettytable" ];
+
+  meta = with lib; {
+    description = "Simple Python library for easily displaying tabular data in a visually appealing ASCII table format";
+    homepage = "http://code.google.com/p/prettytable/";
+    license = licenses.bsd3;
+  };
+
+}
diff --git a/pkgs/development/python2-modules/protobuf/default.nix b/pkgs/development/python2-modules/protobuf/default.nix
new file mode 100644
index 000000000000..30e9fbf9ea75
--- /dev/null
+++ b/pkgs/development/python2-modules/protobuf/default.nix
@@ -0,0 +1,59 @@
+{ buildPackages
+, lib
+, fetchpatch
+, python
+, buildPythonPackage
+, isPy37
+, protobuf
+, google-apputils ? null
+, six
+, pyext
+, isPy27
+, disabled
+, doCheck ? true
+}:
+
+buildPythonPackage {
+  inherit (protobuf) pname src version;
+  inherit disabled;
+  doCheck = doCheck && !isPy27; # setuptools>=41.4 no longer collects correctly on python2
+
+  propagatedBuildInputs = [ six ] ++ lib.optionals isPy27 [ google-apputils ];
+  propagatedNativeBuildInputs = [ buildPackages.protobuf ]; # For protoc.
+  nativeBuildInputs = [ pyext ] ++ lib.optionals isPy27 [ google-apputils ];
+  buildInputs = [ protobuf ];
+
+  patches = lib.optional (isPy37 && (lib.versionOlder protobuf.version "3.6.1.2"))
+    # Python 3.7 compatibility (not needed for protobuf >= 3.6.1.2)
+    (fetchpatch {
+      url = "https://github.com/protocolbuffers/protobuf/commit/0a59054c30e4f0ba10f10acfc1d7f3814c63e1a7.patch";
+      sha256 = "09hw22y3423v8bbmc9xm07znwdxfbya6rp78d4zqw6fisdvjkqf1";
+      stripLen = 1;
+    })
+  ;
+
+  prePatch = ''
+    while [ ! -d python ]; do
+      cd *
+    done
+    cd python
+  '';
+
+  setupPyGlobalFlags = lib.optional (lib.versionAtLeast protobuf.version "2.6.0")
+    "--cpp_implementation";
+
+  pythonImportsCheck = [
+    "google.protobuf"
+  ] ++ lib.optionals (lib.versionAtLeast protobuf.version "2.6.0") [
+    "google.protobuf.internal._api_implementation" # Verify that --cpp_implementation worked
+  ];
+
+  meta = with lib; {
+    description = "Protocol Buffers are Google's data interchange format";
+    homepage = "https://developers.google.com/protocol-buffers/";
+    license = licenses.bsd3;
+    maintainers = with maintainers; [ knedlsepp ];
+  };
+
+  passthru.protobuf = protobuf;
+}
diff --git a/pkgs/development/python2-modules/pycairo/default.nix b/pkgs/development/python2-modules/pycairo/default.nix
new file mode 100644
index 000000000000..9da4da1479c0
--- /dev/null
+++ b/pkgs/development/python2-modules/pycairo/default.nix
@@ -0,0 +1,52 @@
+{ lib
+, fetchFromGitHub
+, meson
+, ninja
+, buildPythonPackage
+, pytestCheckHook
+, pkg-config
+, cairo
+, python
+}:
+
+buildPythonPackage rec {
+  pname = "pycairo";
+  version = "1.18.2";
+
+  format = "other";
+
+  src = fetchFromGitHub {
+    owner = "pygobject";
+    repo = "pycairo";
+    rev = "v${version}";
+    sha256 = "142145a2whvlk92jijrbf3i2bqrzmspwpysj0bfypw0krzi0aa6j";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+  ];
+
+  buildInputs = [
+    cairo
+  ];
+
+  checkInputs = [
+    pytestCheckHook
+  ];
+
+  mesonFlags = [
+    # This is only used for figuring out what version of Python is in
+    # use, and related stuff like figuring out what the install prefix
+    # should be, but it does need to be able to execute Python code.
+    "-Dpython=${python.pythonForBuild.interpreter}"
+  ];
+
+  meta = with lib; {
+    description = "Python 2 bindings for cairo";
+    homepage = "https://pycairo.readthedocs.io/";
+    license = with licenses; [ lgpl21Only mpl11 ];
+    platforms = lib.platforms.linux ++ lib.platforms.darwin;
+  };
+}
diff --git a/pkgs/development/python2-modules/pygobject/default.nix b/pkgs/development/python2-modules/pygobject/default.nix
new file mode 100644
index 000000000000..ce9410eaf8b5
--- /dev/null
+++ b/pkgs/development/python2-modules/pygobject/default.nix
@@ -0,0 +1,33 @@
+{ lib, stdenv, fetchurl, buildPythonPackage, pkg-config, glib, gobject-introspection,
+pycairo, cairo, which, ncurses, meson, ninja, isPy3k, gnome }:
+
+buildPythonPackage rec {
+  pname = "pygobject";
+  version = "3.36.1";
+
+  format = "other";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "0b9CgC0c7BE7Wtqg579/N0W0RSHcIWNYjSdtXNYdcY8=";
+  };
+
+  outputs = [ "out" "dev" ];
+
+  mesonFlags = [
+    "-Dpython=python${if isPy3k then "3" else "2" }"
+  ];
+
+  nativeBuildInputs = [ pkg-config meson ninja gobject-introspection ];
+  buildInputs = [ glib gobject-introspection ]
+                 ++ lib.optionals stdenv.isDarwin [ which ncurses ];
+  propagatedBuildInputs = [ pycairo cairo ];
+
+  meta = with lib; {
+    homepage = "https://pygobject.readthedocs.io/";
+    description = "Python bindings for Glib";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ orivej ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/development/python2-modules/pygtk/default.nix b/pkgs/development/python2-modules/pygtk/default.nix
new file mode 100644
index 000000000000..938b55630c06
--- /dev/null
+++ b/pkgs/development/python2-modules/pygtk/default.nix
@@ -0,0 +1,74 @@
+{ lib, stdenv, fetchurl, fetchpatch, python, pkg-config, gtk2, pygobject2, pycairo, pango
+, buildPythonPackage, libglade ? null, isPy3k }:
+
+buildPythonPackage rec {
+  pname = "pygtk";
+  version = "2.24.0";
+
+  disabled = isPy3k;
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${pname}-${version}.tar.bz2";
+    sha256 = "04k942gn8vl95kwf0qskkv6npclfm31d78ljkrkgyqxxcni1w76d";
+  };
+
+  patches = [
+    # https://bugzilla.gnome.org/show_bug.cgi?id=660216 - fixes some memory leaks
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/Archive/pygtk/commit/eca72baa5616fbe4dbebea43c7e5940847dc5ab8.diff";
+      sha256 = "031px4w5cshcx1sns430sdbr2i007b9zyb2carb3z65nzr77dpdd";
+    })
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/Archive/pygtk/commit/4aaa48eb80c6802aec6d03e5695d2a0ff20e0fc2.patch";
+      sha256 = "0z8cg7nr3qki8gg8alasdzzyxcihfjlxn518glq5ajglk3q5pzsn";
+    })
+  ];
+
+  nativeBuildInputs = [ pkg-config ];
+  buildInputs = [
+    pango
+  ] ++ lib.optional (libglade != null) libglade;
+
+  propagatedBuildInputs = [ gtk2 pygobject2 pycairo ];
+
+  configurePhase = "configurePhase";
+
+  buildPhase = "buildPhase";
+
+  NIX_CFLAGS_COMPILE = lib.optionalString stdenv.isDarwin "-ObjC";
+
+  installPhase = "installPhase";
+
+  checkPhase = lib.optionalString (libglade == null)
+    ''
+      sed -i -e "s/glade = importModule('gtk.glade', buildDir)//" \
+             tests/common.py
+      sed -i -e "s/, glade$//" \
+             -e "s/.*testGlade.*//" \
+             -e "s/.*(glade.*//" \
+             tests/test_api.py
+    '' + ''
+      sed -i -e "s/sys.path.insert(0, os.path.join(buildDir, 'gtk'))//" \
+             -e "s/sys.path.insert(0, buildDir)//" \
+             tests/common.py
+      make check
+    '';
+  # XXX: TypeError: Unsupported type: <class 'gtk._gtk.WindowType'>
+  # The check phase was not executed in the previous
+  # non-buildPythonPackage setup - not sure why not.
+  doCheck = false;
+
+  postInstall = ''
+    rm $out/bin/pygtk-codegen-2.0
+    ln -s ${pygobject2}/bin/pygobject-codegen-2.0  $out/bin/pygtk-codegen-2.0
+    ln -s ${pygobject2}/lib/${python.libPrefix}/site-packages/pygobject-${pygobject2.version}.pth \
+                  $out/lib/${python.libPrefix}/site-packages/${pname}-${version}.pth
+  '';
+
+  meta = with lib; {
+    description = "GTK 2 Python bindings";
+    homepage = "https://gitlab.gnome.org/Archive/pygtk";
+    platforms = platforms.all;
+    license = with licenses; [ lgpl21Plus ];
+  };
+}
diff --git a/pkgs/development/python2-modules/pyjwt/default.nix b/pkgs/development/python2-modules/pyjwt/default.nix
new file mode 100644
index 000000000000..9978302d1cc4
--- /dev/null
+++ b/pkgs/development/python2-modules/pyjwt/default.nix
@@ -0,0 +1,44 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, cryptography
+, ecdsa
+, pytestCheckHook
+, pythonOlder
+}:
+
+buildPythonPackage rec {
+  pname = "pyjwt";
+  version = "1.7.1";
+
+  src = fetchPypi {
+    pname = "PyJWT";
+    inherit version;
+    sha256 = "8d59a976fb773f3e6a39c85636357c4f0e242707394cadadd9814f5cbaa20e96";
+  };
+
+  postPatch = ''
+    sed -i '/^addopts/d' setup.cfg
+  '';
+
+  propagatedBuildInputs = [
+    cryptography
+    ecdsa
+  ];
+
+  checkInputs = [
+    pytestCheckHook
+  ];
+
+  disabledTests = [
+    "test_ec_verify_should_return_false_if_signature_invalid"
+  ];
+
+  pythonImportsCheck = [ "jwt" ];
+
+  meta = with lib; {
+    description = "JSON Web Token implementation in Python";
+    homepage = "https://github.com/jpadilla/pyjwt";
+    license = licenses.mit;
+  };
+}
diff --git a/pkgs/development/python2-modules/pyroma/default.nix b/pkgs/development/python2-modules/pyroma/default.nix
new file mode 100644
index 000000000000..9fee5ec56c0e
--- /dev/null
+++ b/pkgs/development/python2-modules/pyroma/default.nix
@@ -0,0 +1,26 @@
+{ lib, buildPythonPackage, fetchPypi
+, docutils, pygments, setuptools
+}:
+
+buildPythonPackage rec {
+  pname = "pyroma";
+  version = "2.6.1";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "2527423e3a24ccd56951f3ce1b0ebbcc4fa0518c82fca882e696c78726ab9c2f";
+  };
+
+  postPatch = ''
+    substituteInPlace setup.py \
+      --replace "pygments < 2.6" "pygments"
+  '';
+
+  propagatedBuildInputs = [ docutils pygments setuptools ];
+
+  meta = with lib; {
+    description = "Test your project's packaging friendliness";
+    homepage = "https://github.com/regebro/pyroma";
+    license = licenses.mit;
+  };
+}
diff --git a/pkgs/development/python2-modules/pysqlite/default.nix b/pkgs/development/python2-modules/pysqlite/default.nix
new file mode 100644
index 000000000000..09cc312223ad
--- /dev/null
+++ b/pkgs/development/python2-modules/pysqlite/default.nix
@@ -0,0 +1,57 @@
+{ lib, stdenv
+, buildPythonPackage
+, fetchPypi
+, isPy3k
+, pkgs
+}:
+
+buildPythonPackage rec {
+  pname = "pysqlite";
+  version = "2.8.3";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "17d3335863e8cf8392eea71add33dab3f96d060666fe68ab7382469d307f4490";
+  };
+
+  # Need to use the builtin sqlite3 on Python 3
+  disabled = isPy3k;
+
+  # Since the `.egg' file is zipped, the `NEEDED' of the `.so' files
+  # it contains is not taken into account.  Thus, we must explicitly make
+  # it a propagated input.
+  propagatedBuildInputs = [ pkgs.sqlite ];
+
+  patchPhase = ''
+    substituteInPlace "setup.cfg"                                     \
+            --replace "/usr/local/include" "${pkgs.sqlite.dev}/include"   \
+            --replace "/usr/local/lib" "${pkgs.sqlite.out}/lib"
+    ${lib.optionalString (!stdenv.isDarwin) ''export LDSHARED="$CC -pthread -shared"''}
+  '';
+
+  meta = with lib; {
+    homepage = "https://pysqlite.org/";
+    description = "Python bindings for the SQLite embedded relational database engine";
+    longDescription = ''
+      pysqlite is a DB-API 2.0-compliant database interface for SQLite.
+
+      SQLite is a relational database management system contained in
+      a relatively small C library.  It is a public domain project
+      created by D. Richard Hipp.  Unlike the usual client-server
+      paradigm, the SQLite engine is not a standalone process with
+      which the program communicates, but is linked in and thus
+      becomes an integral part of the program.  The library
+      implements most of SQL-92 standard, including transactions,
+      triggers and most of complex queries.
+
+      pysqlite makes this powerful embedded SQL engine available to
+      Python programmers.  It stays compatible with the Python
+      database API specification 2.0 as much as possible, but also
+      exposes most of SQLite's native API, so that it is for example
+      possible to create user-defined SQL functions and aggregates
+      in Python.
+    '';
+    license = licenses.bsd3;
+  };
+
+}
diff --git a/pkgs/development/python2-modules/pytest-runner/default.nix b/pkgs/development/python2-modules/pytest-runner/default.nix
new file mode 100644
index 000000000000..bea83146c37d
--- /dev/null
+++ b/pkgs/development/python2-modules/pytest-runner/default.nix
@@ -0,0 +1,30 @@
+{ lib, buildPythonPackage, fetchPypi, setuptools-scm, pytest }:
+
+buildPythonPackage rec {
+  pname = "pytest-runner";
+  version = "5.2";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "96c7e73ead7b93e388c5d614770d2bae6526efd997757d3543fe17b557a0942b";
+  };
+
+  nativeBuildInputs = [ setuptools-scm pytest ];
+
+  postPatch = ''
+    rm pytest.ini
+  '';
+
+  checkPhase = ''
+    py.test tests
+  '';
+
+  # Fixture not found
+  doCheck = false;
+
+  meta = with lib; {
+    description = "Invoke py.test as distutils command with dependency resolution";
+    homepage = "https://github.com/pytest-dev/pytest-runner";
+    license = licenses.mit;
+  };
+}
diff --git a/pkgs/development/python2-modules/pytest-xdist/default.nix b/pkgs/development/python2-modules/pytest-xdist/default.nix
new file mode 100644
index 000000000000..466d86f50f78
--- /dev/null
+++ b/pkgs/development/python2-modules/pytest-xdist/default.nix
@@ -0,0 +1,36 @@
+{ lib, fetchPypi, buildPythonPackage, execnet, pytest
+, setuptools-scm, pytest-forked, filelock, psutil, six, isPy3k }:
+
+buildPythonPackage rec {
+  pname = "pytest-xdist";
+  version = "1.34.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "1vh4ps32lp5ignch5adbl3pgchvigdfmrl6qpmhxih54wa1qw3il";
+  };
+
+  nativeBuildInputs = [ setuptools-scm pytest ];
+  checkInputs = [ pytest filelock ];
+  propagatedBuildInputs = [ execnet pytest-forked psutil six ];
+
+  # Encountered a memory leak
+  # https://github.com/pytest-dev/pytest-xdist/issues/462
+  doCheck = !isPy3k;
+
+  checkPhase = ''
+    # Excluded tests access file system
+    py.test testing -k "not test_distribution_rsyncdirs_example \
+                    and not test_rsync_popen_with_path \
+                    and not test_popen_rsync_subdir \
+                    and not test_init_rsync_roots \
+                    and not test_rsyncignore"
+  '';
+
+  meta = with lib; {
+    description = "py.test xdist plugin for distributed testing and loop-on-failing modes";
+    homepage = "https://github.com/pytest-dev/pytest-xdist";
+    license = licenses.mit;
+    maintainers = with maintainers; [ dotlambda ];
+  };
+}
diff --git a/pkgs/development/python2-modules/pytest/default.nix b/pkgs/development/python2-modules/pytest/default.nix
new file mode 100644
index 000000000000..0a0ae571ba01
--- /dev/null
+++ b/pkgs/development/python2-modules/pytest/default.nix
@@ -0,0 +1,68 @@
+{ lib, buildPythonPackage, pythonOlder, fetchPypi, attrs, hypothesis, py
+, setuptools-scm, setuptools, six, pluggy, funcsigs, isPy3k, more-itertools
+, atomicwrites, mock, writeText, pathlib2, wcwidth, packaging, isPyPy
+}:
+buildPythonPackage rec {
+  version = "4.6.11";
+  pname = "pytest";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "50fa82392f2120cc3ec2ca0a75ee615be4c479e66669789771f1758332be4353";
+  };
+
+  postPatch = ''
+    substituteInPlace setup.py \
+      --replace "pluggy>=0.12,<1.0" "pluggy>=0.12,<2.0"
+  '';
+
+  checkInputs = [ hypothesis mock ];
+  buildInputs = [ setuptools-scm ];
+  propagatedBuildInputs = [ attrs py setuptools six pluggy more-itertools atomicwrites wcwidth packaging ]
+    ++ lib.optionals (!isPy3k) [ funcsigs ]
+    ++ lib.optionals (pythonOlder "3.6") [ pathlib2 ];
+
+  doCheck = !isPyPy; # https://github.com/pytest-dev/pytest/issues/3460
+  checkPhase = ''
+    runHook preCheck
+
+    # don't test bash builtins
+    rm testing/test_argcomplete.py
+
+    # determinism - this test writes non deterministic bytecode
+    rm -rf testing/test_assertrewrite.py
+
+    PYTHONDONTWRITEBYTECODE=1 $out/bin/py.test -x testing/ -k "not test_collect_pyargs_with_testpaths"
+    runHook postCheck
+  '';
+
+  # Remove .pytest_cache when using py.test in a Nix build
+  setupHook = writeText "pytest-hook" ''
+    pytestcachePhase() {
+        find $out -name .pytest_cache -type d -exec rm -rf {} +
+    }
+
+    preDistPhases+=" pytestcachePhase"
+
+    # pytest generates it's own bytecode files to improve assertion messages.
+    # These files similar to cpython's bytecode files but are never laoded
+    # by python interpreter directly. We remove them for a few reasons:
+    # - files are non-deterministic: https://github.com/NixOS/nixpkgs/issues/139292
+    #   (file headers are generatedt by pytest directly and contain timestamps)
+    # - files are not needed after tests are finished
+    pytestRemoveBytecodePhase () {
+        # suffix is defined at:
+        #    https://github.com/pytest-dev/pytest/blob/4.6.11/src/_pytest/assertion/rewrite.py#L32-L47
+        find $out -name "*-PYTEST.py[co]" -delete
+    }
+    preDistPhases+=" pytestRemoveBytecodePhase"
+  '';
+
+  meta = with lib; {
+    homepage = "https://docs.pytest.org";
+    description = "Framework for writing tests";
+    maintainers = with maintainers; [ domenkozar lovek323 madjar lsix ];
+    license = licenses.mit;
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/development/python2-modules/pyyaml/default.nix b/pkgs/development/python2-modules/pyyaml/default.nix
new file mode 100644
index 000000000000..3edfae90e668
--- /dev/null
+++ b/pkgs/development/python2-modules/pyyaml/default.nix
@@ -0,0 +1,38 @@
+{ lib
+, buildPythonPackage
+, fetchFromGitHub
+, cython
+, libyaml
+, isPy27
+, python
+}:
+
+buildPythonPackage rec {
+  pname = "PyYAML";
+  version = "5.4.1.1";
+
+  src = fetchFromGitHub {
+    owner = "yaml";
+    repo = "pyyaml";
+    rev = version;
+    sha256 = "1v386gzdvsjg0mgix6v03rd0cgs9dl81qvn3m547849jm8r41dx8";
+  };
+
+  nativeBuildInputs = [ cython ];
+
+  buildInputs = [ libyaml ];
+
+  checkPhase = ''
+    runHook preCheck
+    PYTHONPATH=""tests/lib":$PYTHONPATH" ${python.interpreter} -m test_all
+    runHook postCheck
+  '';
+
+  pythonImportsCheck = [ "yaml" ];
+
+  meta = with lib; {
+    description = "The next generation YAML parser and emitter for Python";
+    homepage = "https://github.com/yaml/pyyaml";
+    license = licenses.mit;
+  };
+}
diff --git a/pkgs/development/python2-modules/qpid-python/default.nix b/pkgs/development/python2-modules/qpid-python/default.nix
new file mode 100644
index 000000000000..e22b3215e81f
--- /dev/null
+++ b/pkgs/development/python2-modules/qpid-python/default.nix
@@ -0,0 +1,26 @@
+{ lib
+, buildPythonPackage
+, fetchurl
+, isPy3k
+}:
+
+buildPythonPackage rec {
+  pname = "qpid-python";
+  version = "0.32";
+  disabled = isPy3k;
+
+  src = fetchurl {
+    url = "http://www.us.apache.org/dist/qpid/${version}/${pname}-${version}.tar.gz";
+    sha256 = "09hdfjgk8z4s3dr8ym2r6xn97j1f9mkb2743pr6zd0bnj01vhsv4";
+  };
+
+  # needs a broker running and then ./qpid-python-test
+  doCheck = false;
+
+  meta = with lib; {
+    homepage = "https://qpid.apache.org/";
+    description = "Python client implementation and AMQP conformance tests for Apache Qpid";
+    license = licenses.asl20;
+  };
+
+}
diff --git a/pkgs/development/python2-modules/s3transfer/default.nix b/pkgs/development/python2-modules/s3transfer/default.nix
new file mode 100644
index 000000000000..8cfd324f00a5
--- /dev/null
+++ b/pkgs/development/python2-modules/s3transfer/default.nix
@@ -0,0 +1,52 @@
+{ lib
+, fetchPypi
+, pythonOlder
+, buildPythonPackage
+, docutils
+, mock
+, nose
+, coverage
+, wheel
+, unittest2
+, botocore
+, futures ? null
+}:
+
+buildPythonPackage rec {
+  pname = "s3transfer";
+  version = "0.4.2";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "sha256-ywIvSxZVHt67sxo3fT8JYA262nNj2MXbeXbn9Hcy4bI=";
+  };
+
+  propagatedBuildInputs =
+    [
+      botocore
+    ] ++ lib.optional (pythonOlder "3") futures;
+
+  buildInputs = [
+    docutils
+    mock
+    nose
+    coverage
+    wheel
+    unittest2
+  ];
+
+  checkPhase = ''
+    pushd s3transfer/tests
+    nosetests -v unit/ functional/
+    popd
+  '';
+
+  # version on pypi has no tests/ dir
+  doCheck = false;
+
+  meta = with lib; {
+    homepage = "https://github.com/boto/s3transfer";
+    license = licenses.asl20;
+    description = "A library for managing Amazon S3 transfers";
+  };
+}
diff --git a/pkgs/development/python2-modules/scandir/default.nix b/pkgs/development/python2-modules/scandir/default.nix
new file mode 100644
index 000000000000..f92b1f5a6ed7
--- /dev/null
+++ b/pkgs/development/python2-modules/scandir/default.nix
@@ -0,0 +1,20 @@
+{ lib, python, buildPythonPackage, fetchPypi }:
+
+buildPythonPackage rec {
+  pname = "scandir";
+  version = "1.10.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 ="1bkqwmf056pkchf05ywbnf659wqlp6lljcdb0y88wr9f0vv32ijd";
+  };
+
+  checkPhase = "${python.interpreter} test/run_tests.py";
+
+  meta = with lib; {
+    description = "A better directory iterator and faster os.walk()";
+    homepage = "https://github.com/benhoyt/scandir";
+    license = licenses.gpl3;
+    maintainers = with maintainers; [ abbradar ];
+  };
+}
diff --git a/pkgs/development/python2-modules/setuptools-scm/default.nix b/pkgs/development/python2-modules/setuptools-scm/default.nix
new file mode 100644
index 000000000000..4cf6f16fedfb
--- /dev/null
+++ b/pkgs/development/python2-modules/setuptools-scm/default.nix
@@ -0,0 +1,24 @@
+{ lib, buildPythonPackage, fetchPypi, toml }:
+
+buildPythonPackage rec {
+  pname = "setuptools_scm";
+  version = "5.0.2";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "sha256-g6DO3TRJ45RjB4EaTHudicS1/UZKL7XuzNCluxWK5cg=";
+  };
+
+  propagatedBuildInputs = [ toml ];
+
+  # Requires pytest, circular dependency
+  doCheck = false;
+  pythonImportsCheck = [ "setuptools_scm" ];
+
+  meta = with lib; {
+    homepage = "https://github.com/pypa/setuptools_scm/";
+    description = "Handles managing your python package versions in scm metadata";
+    license = licenses.mit;
+    maintainers = with maintainers; [ SuperSandro2000 ];
+  };
+}
diff --git a/pkgs/development/python2-modules/setuptools/default.nix b/pkgs/development/python2-modules/setuptools/default.nix
new file mode 100644
index 000000000000..ca70a1061512
--- /dev/null
+++ b/pkgs/development/python2-modules/setuptools/default.nix
@@ -0,0 +1,80 @@
+{ stdenv
+, buildPythonPackage
+, fetchFromGitHub
+, python
+, bootstrapped-pip
+, lib
+, pipInstallHook
+, setuptoolsBuildHook
+}:
+
+let
+  pname = "setuptools";
+  version = "44.0.0";
+
+  # Create an sdist of setuptools
+  sdist = stdenv.mkDerivation rec {
+    name = "${pname}-${version}-sdist.tar.gz";
+
+    src = fetchFromGitHub {
+      owner = "pypa";
+      repo = pname;
+      rev = "v${version}";
+      sha256 = "0z3q0qinyp1rmnxkw3y5f6nbsxhqlfq5k7skfrqa6ymb3zr009y1";
+      name = "${pname}-${version}-source";
+    };
+
+    patches = [
+      ./tag-date.patch
+    ];
+
+    buildPhase = ''
+      ${python.pythonForBuild.interpreter} bootstrap.py
+      ${python.pythonForBuild.interpreter} setup.py sdist --formats=gztar
+
+      # Here we untar the sdist and retar it in order to control the timestamps
+      # of all the files included
+      tar -xzf dist/${pname}-${version}.post0.tar.gz -C dist/
+      tar -czf dist/${name} -C dist/ --mtime="@$SOURCE_DATE_EPOCH" ${pname}-${version}.post0
+    '';
+
+    installPhase = ''
+      echo "Moving sdist..."
+      mv dist/${name} $out
+    '';
+  };
+in buildPythonPackage rec {
+  inherit pname version;
+  # Because of bootstrapping we don't use the setuptoolsBuildHook that comes with format="setuptools" directly.
+  # Instead, we override it to remove setuptools to avoid a circular dependency.
+  # The same is done for pip and the pipInstallHook.
+  format = "other";
+
+  src = sdist;
+
+  nativeBuildInputs = [
+    bootstrapped-pip
+    (pipInstallHook.override{pip=null;})
+    (setuptoolsBuildHook.override{setuptools=null; wheel=null;})
+  ];
+
+  preBuild = lib.optionalString (!stdenv.hostPlatform.isWindows) ''
+    export SETUPTOOLS_INSTALL_WINDOWS_SPECIFIC_FILES=0
+  '';
+
+  pipInstallFlags = [ "--ignore-installed" ];
+
+  # Adds setuptools to nativeBuildInputs causing infinite recursion.
+  catchConflicts = false;
+
+  # Requires pytest, causing infinite recursion.
+  doCheck = false;
+
+  meta = with lib; {
+    description = "Utilities to facilitate the installation of Python packages";
+    homepage = "https://pypi.python.org/pypi/setuptools";
+    license = with licenses; [ psfl zpl20 ];
+    platforms = python.meta.platforms;
+    priority = 10;
+  };
+}
diff --git a/pkgs/development/python2-modules/setuptools/tag-date.patch b/pkgs/development/python2-modules/setuptools/tag-date.patch
new file mode 100644
index 000000000000..441177a5d17e
--- /dev/null
+++ b/pkgs/development/python2-modules/setuptools/tag-date.patch
@@ -0,0 +1,12 @@
+diff --git a/setup.cfg b/setup.cfg
+index f23714b6..8aaeb330 100644
+--- a/setup.cfg
++++ b/setup.cfg
+@@ -1,6 +1,6 @@
+ [egg_info]
+ tag_build = .post
+-tag_date = 1
++tag_date = 0
+
+ [aliases]
+ clean_egg_info = egg_info -Db ''
diff --git a/pkgs/development/python2-modules/sphinx/default.nix b/pkgs/development/python2-modules/sphinx/default.nix
new file mode 100644
index 000000000000..0424b9b4c39b
--- /dev/null
+++ b/pkgs/development/python2-modules/sphinx/default.nix
@@ -0,0 +1,82 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, pytest
+, simplejson
+, mock
+, glibcLocales
+, html5lib
+, pythonOlder
+, enum34
+, python
+, docutils
+, jinja2
+, pygments
+, alabaster
+, Babel
+, snowballstemmer
+, six
+, sqlalchemy
+, whoosh
+, imagesize
+, requests
+, typing
+, sphinxcontrib-websupport
+, setuptools
+}:
+
+buildPythonPackage rec {
+  pname = "sphinx";
+  version = "1.8.5";
+  src = fetchPypi {
+    pname = "Sphinx";
+    inherit version;
+    sha256 = "c7658aab75c920288a8cf6f09f244c6cfdae30d82d803ac1634d9f223a80ca08";
+  };
+  LC_ALL = "en_US.UTF-8";
+
+  checkInputs = [ pytest ];
+  buildInputs = [ simplejson mock glibcLocales html5lib ] ++ lib.optional (pythonOlder "3.4") enum34;
+  # Disable two tests that require network access.
+  checkPhase = ''
+    cd tests; ${python.interpreter} run.py --ignore py35 -k 'not test_defaults and not test_anchors_ignored'
+  '';
+  propagatedBuildInputs = [
+    docutils
+    jinja2
+    pygments
+    alabaster
+    Babel
+    setuptools
+    snowballstemmer
+    six
+    sphinxcontrib-websupport
+    sqlalchemy
+    whoosh
+    imagesize
+    requests
+  ] ++ lib.optional (pythonOlder "3.5") typing;
+
+  # Lots of tests. Needs network as well at some point.
+  doCheck = false;
+
+  patches = [
+    # Since pygments 2.5, PythonLexer refers to python3. If we want to use
+    # python2, we need to explicitly specify Python2Lexer.
+    # Not upstreamed since there doesn't seem to be any upstream maintenance
+    # branch for 1.8 (and this patch doesn't make any sense for 2.x).
+    ./python2-lexer.patch
+  ];
+  # https://github.com/NixOS/nixpkgs/issues/22501
+  # Do not run `python sphinx-build arguments` but `sphinx-build arguments`.
+  postPatch = ''
+    substituteInPlace sphinx/make_mode.py --replace "sys.executable, " ""
+  '';
+
+  meta = {
+    description = "A tool that makes it easy to create intelligent and beautiful documentation for Python projects";
+    homepage = "http://sphinx.pocoo.org/";
+    license = lib.licenses.bsd3;
+    maintainers = with lib.maintainers; [ ];
+  };
+}
diff --git a/pkgs/development/python2-modules/sphinx/python2-lexer.patch b/pkgs/development/python2-modules/sphinx/python2-lexer.patch
new file mode 100644
index 000000000000..cf4a243315a2
--- /dev/null
+++ b/pkgs/development/python2-modules/sphinx/python2-lexer.patch
@@ -0,0 +1,22 @@
+diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
+index ac2bd1b06..63ca52de2 100644
+--- a/sphinx/highlighting.py
++++ b/sphinx/highlighting.py
+@@ -16,7 +16,7 @@ from pygments.filters import ErrorToken
+ from pygments.formatters import HtmlFormatter, LatexFormatter
+ from pygments.lexer import Lexer  # NOQA
+ from pygments.lexers import get_lexer_by_name, guess_lexer
+-from pygments.lexers import PythonLexer, Python3Lexer, PythonConsoleLexer, \
++from pygments.lexers import Python2Lexer, Python3Lexer, PythonConsoleLexer, \
+     CLexer, TextLexer, RstLexer
+ from pygments.styles import get_style_by_name
+ from pygments.util import ClassNotFound
+@@ -40,7 +40,7 @@ logger = logging.getLogger(__name__)
+ 
+ lexers = dict(
+     none = TextLexer(stripnl=False),
+-    python = PythonLexer(stripnl=False),
++    python = Python2Lexer(stripnl=False),
+     python3 = Python3Lexer(stripnl=False),
+     pycon = PythonConsoleLexer(stripnl=False),
+     pycon3 = PythonConsoleLexer(python3=True, stripnl=False),
diff --git a/pkgs/development/python2-modules/sphinxcontrib-websupport/default.nix b/pkgs/development/python2-modules/sphinxcontrib-websupport/default.nix
new file mode 100644
index 000000000000..b1bdf6a0dff6
--- /dev/null
+++ b/pkgs/development/python2-modules/sphinxcontrib-websupport/default.nix
@@ -0,0 +1,25 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, six
+}:
+
+buildPythonPackage rec {
+  pname = "sphinxcontrib-websupport";
+  version = "1.1.2";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "1501befb0fdf1d1c29a800fdbf4ef5dc5369377300ddbdd16d2cd40e54c6eefc";
+  };
+
+  propagatedBuildInputs = [ six ];
+
+  doCheck = false;
+
+  meta = {
+    description = "Sphinx API for Web Apps";
+    homepage = "http://sphinx-doc.org/";
+    license = lib.licenses.bsd2;
+  };
+}
diff --git a/pkgs/development/python2-modules/typing/default.nix b/pkgs/development/python2-modules/typing/default.nix
new file mode 100644
index 000000000000..b3dcea203231
--- /dev/null
+++ b/pkgs/development/python2-modules/typing/default.nix
@@ -0,0 +1,33 @@
+{ lib, buildPythonPackage, fetchPypi, pythonOlder, isPy3k, isPyPy, python
+, pythonAtLeast }:
+
+let
+  testDir = if isPy3k then "src" else "python2";
+
+in buildPythonPackage rec {
+  pname = "typing";
+  version = "3.10.0.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "13b4ad211f54ddbf93e5901a9967b1e07720c1d1b78d596ac6a439641aa1b130";
+  };
+
+  disabled = pythonAtLeast "3.5";
+
+  # Error for Python3.6: ImportError: cannot import name 'ann_module'
+  # See https://github.com/python/typing/pull/280
+  # Also, don't bother on PyPy: AssertionError: TypeError not raised
+  doCheck = pythonOlder "3.6" && !isPyPy;
+
+  checkPhase = ''
+    cd ${testDir}
+    ${python.interpreter} -m unittest discover
+  '';
+
+  meta = with lib; {
+    description = "Backport of typing module to Python versions older than 3.5";
+    homepage = "https://docs.python.org/3/library/typing.html";
+    license = licenses.psfl;
+  };
+}
diff --git a/pkgs/development/python2-modules/urllib3/default.nix b/pkgs/development/python2-modules/urllib3/default.nix
new file mode 100644
index 000000000000..a52e68eac5e3
--- /dev/null
+++ b/pkgs/development/python2-modules/urllib3/default.nix
@@ -0,0 +1,81 @@
+{ lib
+, brotli
+, buildPythonPackage
+, certifi
+, cryptography
+, python-dateutil
+, fetchpatch
+, fetchPypi
+, idna
+, mock
+, pyopenssl
+, pysocks
+, pytest-freezegun
+, pytest-timeout
+, pytestCheckHook
+, tornado
+, trustme
+}:
+
+buildPythonPackage rec {
+  pname = "urllib3";
+  version = "1.26.2";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08";
+  };
+
+  patches = [
+    (fetchpatch {
+      name = "CVE-2021-28363.patch";
+      url = "https://github.com/urllib3/urllib3/commit/8d65ea1ecf6e2cdc27d42124e587c1b83a3118b0.patch";
+      sha256 = "1lqhrd11p03iv14bp89rh67ynf000swmwsfvr3jpfdycdqr3ka9q";
+    })
+  ];
+
+  propagatedBuildInputs = [
+    brotli
+    certifi
+    cryptography
+    idna
+    pyopenssl
+    pysocks
+  ];
+
+  checkInputs = [
+    python-dateutil
+    mock
+    pytest-freezegun
+    pytest-timeout
+    pytestCheckHook
+    tornado
+    trustme
+  ];
+
+  # Tests in urllib3 are mostly timeout-based instead of event-based and
+  # are therefore inherently flaky. On your own machine, the tests will
+  # typically build fine, but on a loaded cluster such as Hydra random
+  # timeouts will occur.
+  #
+  # The urllib3 test suite has two different timeouts in their test suite
+  # (see `test/__init__.py`):
+  # - SHORT_TIMEOUT
+  # - LONG_TIMEOUT
+  # When CI is in the env, LONG_TIMEOUT will be significantly increased.
+  # Still, failures can occur and for that reason tests are disabled.
+  doCheck = false;
+
+  preCheck = ''
+    export CI # Increases LONG_TIMEOUT
+  '';
+
+  pythonImportsCheck = [ "urllib3" ];
+
+  meta = with lib; {
+    description = "Powerful, sanity-friendly HTTP client for Python";
+    homepage = "https://github.com/shazow/urllib3";
+    license = licenses.mit;
+    maintainers = with maintainers; [ fab ];
+  };
+}
diff --git a/pkgs/development/python2-modules/vcrpy/default.nix b/pkgs/development/python2-modules/vcrpy/default.nix
new file mode 100644
index 000000000000..ddd4015aad1e
--- /dev/null
+++ b/pkgs/development/python2-modules/vcrpy/default.nix
@@ -0,0 +1,48 @@
+{ buildPythonPackage
+, lib
+, six
+, fetchPypi
+, pyyaml
+, mock
+, contextlib2
+, wrapt
+, pytest
+, pytest-httpbin
+, yarl
+, pythonOlder
+, pythonAtLeast
+}:
+
+buildPythonPackage rec {
+  pname = "vcrpy";
+  version = "3.0.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "21168d5ae14263a833d4b71acfd8278d8841114f24be1b4ab4a5719d0c7f07bc";
+  };
+
+  checkInputs = [
+    pytest
+    pytest-httpbin
+  ];
+
+  propagatedBuildInputs = [
+    pyyaml
+    wrapt
+    six
+  ]
+  ++ lib.optionals (pythonOlder "3.3") [ contextlib2 mock ]
+  ++ lib.optionals (pythonAtLeast "3.4") [ yarl ];
+
+  checkPhase = ''
+    py.test --ignore=tests/integration -k "not TestVCRConnection"
+  '';
+
+  meta = with lib; {
+    description = "Automatically mock your HTTP interactions to simplify and speed up testing";
+    homepage = "https://github.com/kevin1024/vcrpy";
+    license = licenses.mit;
+  };
+}
+
diff --git a/pkgs/development/python2-modules/werkzeug/default.nix b/pkgs/development/python2-modules/werkzeug/default.nix
new file mode 100644
index 000000000000..c03cc6935d2f
--- /dev/null
+++ b/pkgs/development/python2-modules/werkzeug/default.nix
@@ -0,0 +1,60 @@
+{ lib, stdenv, buildPythonPackage, fetchPypi
+, itsdangerous, hypothesis
+, pytestCheckHook, requests
+, pytest-timeout
+ }:
+
+buildPythonPackage rec {
+  pname = "Werkzeug";
+  version = "1.0.1";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c";
+  };
+
+  propagatedBuildInputs = [ itsdangerous ];
+  checkInputs = [ pytestCheckHook requests hypothesis pytest-timeout ];
+
+  postPatch = ''
+    # ResourceWarning causes tests to fail
+    rm tests/test_routing.py
+  '';
+
+  disabledTests = [
+    "test_save_to_pathlib_dst"
+    "test_cookie_maxsize"
+    "test_cookie_samesite_attribute"
+    "test_cookie_samesite_invalid"
+    "test_range_parsing"
+    "test_content_range_parsing"
+    "test_http_date_lt_1000"
+    "test_best_match_works"
+    "test_date_to_unix"
+    "test_easteregg"
+
+    # Seems to be a problematic test-case:
+    #
+    # > warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))
+    # E pytest.PytestUnraisableExceptionWarning: Exception ignored in: <_io.FileIO [closed]>
+    # E
+    # E Traceback (most recent call last):
+    # E   File "/nix/store/cwv8aj4vsqvimzljw5dxsxy663vjgibj-python3.9-Werkzeug-1.0.1/lib/python3.9/site-packages/werkzeug/formparser.py", line 318, in parse_multipart_headers
+    # E     return Headers(result)
+    # E ResourceWarning: unclosed file <_io.FileIO name=11 mode='rb+' closefd=True>
+    "test_basic_routing"
+    "test_merge_slashes_match"
+    "test_merge_slashes_build"
+    "TestMultiPart"
+    "TestHTTPUtility"
+  ] ++ lib.optionals stdenv.isDarwin [
+    "test_get_machine_id"
+  ];
+
+  meta = with lib; {
+    homepage = "https://palletsprojects.com/p/werkzeug/";
+    description = "A WSGI utility library for Python";
+    license = licenses.bsd3;
+    maintainers = [ ];
+  };
+}
diff --git a/pkgs/development/python2-modules/wsproto/default.nix b/pkgs/development/python2-modules/wsproto/default.nix
new file mode 100644
index 000000000000..a8488d8c4ab8
--- /dev/null
+++ b/pkgs/development/python2-modules/wsproto/default.nix
@@ -0,0 +1,25 @@
+{ lib, buildPythonPackage, fetchPypi, h11, enum34, pytest }:
+
+buildPythonPackage rec {
+  pname = "wsproto";
+  version = "0.14.1";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "051s127qb5dladxa14n9nqajwq7xki1dz1was5r5v9df5a0jq8pd";
+  };
+
+  propagatedBuildInputs = [ h11 enum34 ];
+
+  checkInputs = [ pytest ];
+
+  checkPhase = ''
+    py.test
+  '';
+
+  meta = with lib; {
+    description = "Pure Python, pure state-machine WebSocket implementation";
+    homepage = "https://github.com/python-hyper/wsproto/";
+    license = licenses.mit;
+  };
+}
diff --git a/pkgs/development/python2-modules/wxPython/default.nix b/pkgs/development/python2-modules/wxPython/default.nix
new file mode 100644
index 000000000000..6649c5f69315
--- /dev/null
+++ b/pkgs/development/python2-modules/wxPython/default.nix
@@ -0,0 +1,91 @@
+{ fetchurl
+, lib
+, stdenv
+, darwin
+, openglSupport ? true
+, libX11
+, wxGTK
+, wxmac
+, pkg-config
+, buildPythonPackage
+, pyopengl
+, isPy3k
+, isPyPy
+, python
+, cairo
+, pango
+}:
+
+assert wxGTK.unicode;
+
+buildPythonPackage rec {
+  pname = "wxPython";
+  version = "3.0.2.0";
+
+  disabled = isPy3k || isPyPy;
+  doCheck = false;
+
+  src = fetchurl {
+    url = "mirror://sourceforge/wxpython/wxPython-src-${version}.tar.bz2";
+    sha256 = "0qfzx3sqx4mwxv99sfybhsij4b5pc03ricl73h4vhkzazgjjjhfm";
+  };
+
+  dontUseSetuptoolsBuild = true;
+  dontUsePipInstall = true;
+
+  hardeningDisable = [ "format" ];
+
+  nativeBuildInputs = [ pkg-config ]
+    ++ (lib.optionals (!stdenv.isDarwin) [ wxGTK libX11 ])
+    ++ (lib.optionals stdenv.isDarwin [ wxmac ]);
+
+  buildInputs = [ ]
+    ++ (lib.optionals (!stdenv.isDarwin) [  (wxGTK.gtk) ])
+    ++ (lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [
+      ApplicationServices
+      AudioToolbox
+      CFNetwork
+      Carbon
+      Cocoa
+      CoreGraphics
+      CoreServices
+      CoreText
+      DiskArbitration
+      IOKit
+      ImageIO
+      OpenGL
+      Security
+    ]))
+    ++ (lib.optional openglSupport pyopengl);
+
+  preConfigure = ''
+    cd wxPython
+    # remove wxPython's darwin hack that interference with python-2.7-distutils-C++.patch
+    substituteInPlace config.py \
+      --replace "distutils.unixccompiler.UnixCCompiler = MyUnixCCompiler" ""
+    # set the WXPREFIX to $out instead of the storepath of wxwidgets
+    substituteInPlace config.py \
+      --replace "WXPREFIX   = getWxConfigValue('--prefix')" "WXPREFIX   = '$out'"
+    # this check is supposed to only return false on older systems running non-framework python
+    substituteInPlace src/osx_cocoa/_core_wrap.cpp \
+      --replace "return wxPyTestDisplayAvailable();" "return true;"
+  '' + lib.optionalString (!stdenv.isDarwin) ''
+    substituteInPlace wx/lib/wxcairo.py \
+      --replace 'cairoLib = None' 'cairoLib = ctypes.CDLL("${cairo}/lib/libcairo.so")'
+    substituteInPlace wx/lib/wxcairo.py \
+      --replace '_dlls = dict()' '_dlls = {k: ctypes.CDLL(v) for k, v in [
+        ("gdk",        "${wxGTK.gtk}/lib/libgtk-x11-2.0.so"),
+        ("pangocairo", "${pango.out}/lib/libpangocairo-1.0.so"),
+        ("appsvc",     None)
+      ]}'
+  '';
+
+  buildPhase = "";
+
+  installPhase = ''
+    ${python.interpreter} setup.py install WXPORT=${if stdenv.isDarwin then "osx_cocoa" else "gtk2"} NO_HEADERS=0 BUILD_GLCANVAS=${if openglSupport then "1" else "0"} UNICODE=1 --prefix=$out
+    wrapPythonPrograms
+  '';
+
+  passthru = { inherit wxGTK openglSupport; };
+}
diff --git a/pkgs/development/python2-modules/zipp/default.nix b/pkgs/development/python2-modules/zipp/default.nix
new file mode 100644
index 000000000000..82f100aaa0d1
--- /dev/null
+++ b/pkgs/development/python2-modules/zipp/default.nix
@@ -0,0 +1,37 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, setuptools-scm
+, pytest
+, pytest-flake8
+, more-itertools
+}:
+
+buildPythonPackage rec {
+  pname = "zipp";
+  version = "1.0.0";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "0v3qayhqv7vyzydpydwcp51bqciw8p2ajddw68x5k8zppc0vx3yk";
+  };
+
+  nativeBuildInputs = [ setuptools-scm ];
+
+  propagatedBuildInputs = [ more-itertools ];
+
+  checkInputs = [ pytest pytest-flake8 ];
+
+  checkPhase = ''
+    pytest
+  '';
+
+  # Prevent infinite recursion with pytest
+  doCheck = false;
+
+  meta = with lib; {
+    description = "Pathlib-compatible object wrapper for zip files";
+    homepage = "https://github.com/jaraco/zipp";
+    license = licenses.mit;
+  };
+}