at 23.05-pre 6.3 kB view raw
1# Tests for the Python interpreters, package sets and environments. 2# 3# Each Python interpreter has a `passthru.tests` which is the attribute set 4# returned by this function. For example, for Python 3 the tests are run with 5# 6# $ nix-build -A python3.tests 7# 8{ stdenv 9, python 10, runCommand 11, substituteAll 12, lib 13, callPackage 14, pkgs 15}: 16 17let 18 # Test whether the interpreter behaves in the different types of environments 19 # we aim to support. 20 environmentTests = let 21 envs = let 22 inherit python; 23 pythonEnv = python.withPackages(ps: with ps; [ ]); 24 pythonVirtualEnv = if python.isPy3k 25 then 26 python.withPackages(ps: with ps; [ virtualenv ]) 27 else 28 python.buildEnv.override { 29 extraLibs = with python.pkgs; [ virtualenv ]; 30 # Collisions because of namespaces __init__.py 31 ignoreCollisions = true; 32 }; 33 in { 34 # Plain Python interpreter 35 plain = rec { 36 env = python; 37 interpreter = env.interpreter; 38 is_venv = "False"; 39 is_nixenv = "False"; 40 is_virtualenv = "False"; 41 }; 42 } // lib.optionalAttrs (!python.isPyPy) { 43 # Use virtualenv from a Nix env. 44 nixenv-virtualenv = rec { 45 env = runCommand "${python.name}-virtualenv" {} '' 46 ${pythonVirtualEnv.interpreter} -m virtualenv $out 47 ''; 48 interpreter = "${env}/bin/${python.executable}"; 49 is_venv = "False"; 50 is_nixenv = "True"; 51 is_virtualenv = "True"; 52 }; 53 } // lib.optionalAttrs (python.implementation != "graal") { 54 # Python Nix environment (python.buildEnv) 55 nixenv = rec { 56 env = pythonEnv; 57 interpreter = env.interpreter; 58 is_venv = "False"; 59 is_nixenv = "True"; 60 is_virtualenv = "False"; 61 }; 62 } // lib.optionalAttrs (python.isPy3k && (!python.isPyPy)) rec { 63 # Venv built using plain Python 64 # Python 2 does not support venv 65 # TODO: PyPy executable name is incorrect, it should be pypy-c or pypy-3c instead of pypy and pypy3. 66 plain-venv = rec { 67 env = runCommand "${python.name}-venv" {} '' 68 ${python.interpreter} -m venv $out 69 ''; 70 interpreter = "${env}/bin/${python.executable}"; 71 is_venv = "True"; 72 is_nixenv = "False"; 73 is_virtualenv = "False"; 74 }; 75 76 } // lib.optionalAttrs (python.pythonAtLeast "3.8") { 77 # Venv built using Python Nix environment (python.buildEnv) 78 # TODO: Cannot create venv from a nix env 79 # Error: Command '['/nix/store/ddc8nqx73pda86ibvhzdmvdsqmwnbjf7-python3-3.7.6-venv/bin/python3.7', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1. 80 nixenv-venv = rec { 81 env = runCommand "${python.name}-venv" {} '' 82 ${pythonEnv.interpreter} -m venv $out 83 ''; 84 interpreter = "${env}/bin/${pythonEnv.executable}"; 85 is_venv = "True"; 86 is_nixenv = "True"; 87 is_virtualenv = "False"; 88 }; 89 }; 90 91 testfun = name: attrs: runCommand "${python.name}-tests-${name}" ({ 92 inherit (python) pythonVersion; 93 } // attrs) '' 94 cp -r ${./tests/test_environments} tests 95 chmod -R +w tests 96 substituteAllInPlace tests/test_python.py 97 ${attrs.interpreter} -m unittest discover --verbose tests #/test_python.py 98 mkdir $out 99 touch $out/success 100 ''; 101 102 in lib.mapAttrs testfun envs; 103 104 # Integration tests involving the package set. 105 # All PyPy package builds are broken at the moment 106 integrationTests = lib.optionalAttrs (!python.isPyPy) ( 107 lib.optionalAttrs (python.isPy3k && !stdenv.isDarwin) { # darwin has no split-debug 108 cpython-gdb = callPackage ./tests/test_cpython_gdb { 109 interpreter = python; 110 }; 111 } // lib.optionalAttrs (python.pythonAtLeast "3.7") rec { 112 # Before the addition of NIX_PYTHONPREFIX mypy was broken with typed packages 113 nix-pythonprefix-mypy = callPackage ./tests/test_nix_pythonprefix { 114 interpreter = python; 115 }; 116 } 117 ); 118 119 # Tests to ensure overriding works as expected. 120 overrideTests = let 121 extension = self: super: { 122 foobar = super.numpy; 123 }; 124 in { 125 test-packageOverrides = let 126 myPython = let 127 self = python.override { 128 packageOverrides = extension; 129 inherit self; 130 }; 131 in self; 132 in assert myPython.pkgs.foobar == myPython.pkgs.numpy; myPython.withPackages(ps: with ps; [ foobar ]); 133 # overrideScope is broken currently 134 # test-overrideScope = let 135 # myPackages = python.pkgs.overrideScope extension; 136 # in assert myPackages.foobar == myPackages.numpy; myPackages.python.withPackages(ps: with ps; [ foobar ]); 137 } // lib.optionalAttrs (python ? pythonAttr) { 138 # Test applying overrides using pythonPackagesOverlays. 139 test-pythonPackagesExtensions = let 140 pkgs_ = pkgs.extend(final: prev: { 141 pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [ 142 (python-final: python-prev: { 143 foo = python-prev.setuptools; 144 }) 145 ]; 146 }); 147 in pkgs_.${python.pythonAttr}.pkgs.foo; 148 }; 149 150 condaTests = let 151 requests = callPackage ({ 152 autoPatchelfHook, 153 fetchurl, 154 pythonCondaPackages, 155 }: 156 python.pkgs.buildPythonPackage { 157 pname = "requests"; 158 version = "2.24.0"; 159 format = "other"; 160 src = fetchurl { 161 url = "https://repo.anaconda.com/pkgs/main/noarch/requests-2.24.0-py_0.tar.bz2"; 162 sha256 = "02qzaf6gwsqbcs69pix1fnjxzgnngwzvrsy65h1d521g750mjvvp"; 163 }; 164 nativeBuildInputs = [ autoPatchelfHook ] ++ (with python.pkgs; [ 165 condaUnpackHook condaInstallHook 166 ]); 167 buildInputs = [ 168 pythonCondaPackages.condaPatchelfLibs 169 ]; 170 propagatedBuildInputs = with python.pkgs; [ 171 chardet idna urllib3 certifi 172 ]; 173 } 174 ) {}; 175 pythonWithRequests = requests.pythonModule.withPackages (ps: [ requests ]); 176 in 177 { 178 condaExamplePackage = runCommand "import-requests" {} '' 179 ${pythonWithRequests.interpreter} -c "import requests" > $out 180 ''; 181 }; 182 183in lib.optionalAttrs (stdenv.hostPlatform == stdenv.buildPlatform ) (environmentTests // integrationTests // overrideTests // condaTests)