Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at gcc-offload 234 lines 8.2 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, lib 12, callPackage 13, pkgs 14}: 15 16let 17 # Test whether the interpreter behaves in the different types of environments 18 # we aim to support. 19 environmentTests = let 20 envs = let 21 inherit python; 22 pythonEnv = python.withPackages(ps: with ps; [ ]); 23 pythonVirtualEnv = if python.isPy3k 24 then 25 python.withPackages(ps: with ps; [ virtualenv ]) 26 else 27 python.buildEnv.override { 28 extraLibs = with python.pkgs; [ virtualenv ]; 29 # Collisions because of namespaces __init__.py 30 ignoreCollisions = true; 31 }; 32 in { 33 # Plain Python interpreter 34 plain = rec { 35 env = python; 36 interpreter = env.interpreter; 37 is_venv = "False"; 38 is_nixenv = "False"; 39 is_virtualenv = "False"; 40 }; 41 } // lib.optionalAttrs (!python.isPyPy && !stdenv.hostPlatform.isDarwin) { 42 # Use virtualenv from a Nix env. 43 # Fails on darwin with 44 # virtualenv: error: argument dest: the destination . is not write-able at /nix/store 45 nixenv-virtualenv = rec { 46 env = runCommand "${python.name}-virtualenv" {} '' 47 ${pythonVirtualEnv.interpreter} -m virtualenv venv 48 mv venv $out 49 ''; 50 interpreter = "${env}/bin/${python.executable}"; 51 is_venv = "False"; 52 is_nixenv = "True"; 53 is_virtualenv = "True"; 54 }; 55 } // lib.optionalAttrs (python.implementation != "graal") { 56 # Python Nix environment (python.buildEnv) 57 nixenv = rec { 58 env = pythonEnv; 59 interpreter = env.interpreter; 60 is_venv = "False"; 61 is_nixenv = "True"; 62 is_virtualenv = "False"; 63 }; 64 } // lib.optionalAttrs (python.isPy3k && (!python.isPyPy)) { 65 # Venv built using plain Python 66 # Python 2 does not support venv 67 # TODO: PyPy executable name is incorrect, it should be pypy-c or pypy-3c instead of pypy and pypy3. 68 plain-venv = rec { 69 env = runCommand "${python.name}-venv" {} '' 70 ${python.interpreter} -m venv $out 71 ''; 72 interpreter = "${env}/bin/${python.executable}"; 73 is_venv = "True"; 74 is_nixenv = "False"; 75 is_virtualenv = "False"; 76 }; 77 78 } // { 79 # Venv built using Python Nix environment (python.buildEnv) 80 # TODO: Cannot create venv from a nix env 81 # Error: Command '['/nix/store/ddc8nqx73pda86ibvhzdmvdsqmwnbjf7-python3-3.7.6-venv/bin/python3.7', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1. 82 nixenv-venv = rec { 83 env = runCommand "${python.name}-venv" {} '' 84 ${pythonEnv.interpreter} -m venv $out 85 ''; 86 interpreter = "${env}/bin/${pythonEnv.executable}"; 87 is_venv = "True"; 88 is_nixenv = "True"; 89 is_virtualenv = "False"; 90 }; 91 }; 92 93 testfun = name: attrs: runCommand "${python.name}-tests-${name}" ({ 94 inherit (python) pythonVersion; 95 } // attrs) '' 96 cp -r ${./tests/test_environments} tests 97 chmod -R +w tests 98 substituteAllInPlace tests/test_python.py 99 ${attrs.interpreter} -m unittest discover --verbose tests #/test_python.py 100 mkdir $out 101 touch $out/success 102 ''; 103 104 in lib.mapAttrs testfun envs; 105 106 # Integration tests involving the package set. 107 # All PyPy package builds are broken at the moment 108 integrationTests = lib.optionalAttrs (!python.isPyPy) ({ 109 # Make sure tkinter is importable. See https://github.com/NixOS/nixpkgs/issues/238990 110 tkinter = callPackage ./tests/test_tkinter { 111 interpreter = python; 112 }; 113 } // lib.optionalAttrs (python.isPy3k && python.pythonOlder "3.13" && !stdenv.hostPlatform.isDarwin) { # darwin has no split-debug 114 # fails on python3.13 115 cpython-gdb = callPackage ./tests/test_cpython_gdb { 116 interpreter = python; 117 }; 118 } // lib.optionalAttrs (python.isPy3k && python.pythonOlder "3.13") { 119 # Before the addition of NIX_PYTHONPREFIX mypy was broken with typed packages 120 # mypy does not yet support python3.13 121 # https://github.com/python/mypy/issues/17264 122 nix-pythonprefix-mypy = callPackage ./tests/test_nix_pythonprefix { 123 interpreter = python; 124 }; 125 }); 126 127 # Test editable package support 128 editableTests = let 129 testPython = python.override { 130 self = testPython; 131 packageOverrides = pyfinal: pyprev: { 132 # An editable package with a script that loads our mutable location 133 my-editable = pyfinal.mkPythonEditablePackage { 134 pname = "my-editable"; 135 version = "0.1.0"; 136 root = "$NIX_BUILD_TOP/src"; # Use environment variable expansion at runtime 137 # Inject a script 138 scripts = { 139 my-script = "my_editable.main:main"; 140 }; 141 }; 142 }; 143 }; 144 145 146 in { 147 editable-script = runCommand "editable-test" { 148 nativeBuildInputs = [ (testPython.withPackages (ps: [ ps.my-editable ])) ]; 149 } '' 150 mkdir -p src/my_editable 151 152 cat > src/my_editable/main.py << EOF 153 def main(): 154 print("hello mutable") 155 EOF 156 157 test "$(my-script)" == "hello mutable" 158 test "$(python -c 'import sys; print(sys.path[1])')" == "$NIX_BUILD_TOP/src" 159 160 touch $out 161 ''; 162 }; 163 164 # Tests to ensure overriding works as expected. 165 overrideTests = let 166 extension = self: super: { 167 foobar = super.numpy; 168 }; 169 # `pythonInterpreters.pypy39_prebuilt` does not expose an attribute 170 # name (is not present in top-level `pkgs`). 171 is_prebuilt = python: python.pythonAttr == null; 172 in lib.optionalAttrs (python.isPy3k) ({ 173 test-packageOverrides = let 174 myPython = let 175 self = python.override { 176 packageOverrides = extension; 177 inherit self; 178 }; 179 in self; 180 in assert myPython.pkgs.foobar == myPython.pkgs.numpy; myPython.withPackages(ps: with ps; [ foobar ]); 181 # overrideScope is broken currently 182 # test-overrideScope = let 183 # myPackages = python.pkgs.overrideScope extension; 184 # in assert myPackages.foobar == myPackages.numpy; myPackages.python.withPackages(ps: with ps; [ foobar ]); 185 # 186 # Have to skip prebuilt python as it's not present in top-level 187 # `pkgs` as an attribute. 188 } // lib.optionalAttrs (python ? pythonAttr && !is_prebuilt python) { 189 # Test applying overrides using pythonPackagesOverlays. 190 test-pythonPackagesExtensions = let 191 pkgs_ = pkgs.extend(final: prev: { 192 pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [ 193 (python-final: python-prev: { 194 foo = python-prev.setuptools; 195 }) 196 ]; 197 }); 198 in pkgs_.${python.pythonAttr}.pkgs.foo; 199 }); 200 201 condaTests = let 202 requests = callPackage ({ 203 autoPatchelfHook, 204 fetchurl, 205 pythonCondaPackages, 206 }: 207 python.pkgs.buildPythonPackage { 208 pname = "requests"; 209 version = "2.24.0"; 210 format = "other"; 211 src = fetchurl { 212 url = "https://repo.anaconda.com/pkgs/main/noarch/requests-2.24.0-py_0.tar.bz2"; 213 sha256 = "02qzaf6gwsqbcs69pix1fnjxzgnngwzvrsy65h1d521g750mjvvp"; 214 }; 215 nativeBuildInputs = [ autoPatchelfHook ] ++ (with python.pkgs; [ 216 condaUnpackHook condaInstallHook 217 ]); 218 buildInputs = [ 219 pythonCondaPackages.condaPatchelfLibs 220 ]; 221 propagatedBuildInputs = with python.pkgs; [ 222 chardet idna urllib3 certifi 223 ]; 224 } 225 ) {}; 226 pythonWithRequests = requests.pythonModule.withPackages (ps: [ requests ]); 227 in lib.optionalAttrs (python.isPy3k && stdenv.hostPlatform.isLinux) 228 { 229 condaExamplePackage = runCommand "import-requests" {} '' 230 ${pythonWithRequests.interpreter} -c "import requests" > $out 231 ''; 232 }; 233 234in lib.optionalAttrs (stdenv.hostPlatform == stdenv.buildPlatform ) (environmentTests // integrationTests // overrideTests // condaTests // editableTests)