nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
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}:
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) {
42 # Use virtualenv from a Nix env.
43 nixenv-virtualenv = rec {
44 env = runCommand "${python.name}-virtualenv" {} ''
45 ${pythonVirtualEnv.interpreter} -m virtualenv $out
46 '';
47 interpreter = "${env}/bin/${python.executable}";
48 is_venv = "False";
49 is_nixenv = "True";
50 is_virtualenv = "True";
51 };
52 } // lib.optionalAttrs (python.implementation != "graal") {
53 # Python Nix environment (python.buildEnv)
54 nixenv = rec {
55 env = pythonEnv;
56 interpreter = env.interpreter;
57 is_venv = "False";
58 is_nixenv = "True";
59 is_virtualenv = "False";
60 };
61 } // lib.optionalAttrs (python.isPy3k && (!python.isPyPy)) rec {
62 # Venv built using plain Python
63 # Python 2 does not support venv
64 # TODO: PyPy executable name is incorrect, it should be pypy-c or pypy-3c instead of pypy and pypy3.
65 plain-venv = rec {
66 env = runCommand "${python.name}-venv" {} ''
67 ${python.interpreter} -m venv $out
68 '';
69 interpreter = "${env}/bin/${python.executable}";
70 is_venv = "True";
71 is_nixenv = "False";
72 is_virtualenv = "False";
73 };
74
75 } // lib.optionalAttrs (python.pythonAtLeast "3.8") {
76 # Venv built using Python Nix environment (python.buildEnv)
77 # TODO: Cannot create venv from a nix env
78 # Error: Command '['/nix/store/ddc8nqx73pda86ibvhzdmvdsqmwnbjf7-python3-3.7.6-venv/bin/python3.7', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1.
79 nixenv-venv = rec {
80 env = runCommand "${python.name}-venv" {} ''
81 ${pythonEnv.interpreter} -m venv $out
82 '';
83 interpreter = "${env}/bin/${pythonEnv.executable}";
84 is_venv = "True";
85 is_nixenv = "True";
86 is_virtualenv = "False";
87 };
88 };
89
90 testfun = name: attrs: runCommand "${python.name}-tests-${name}" ({
91 inherit (python) pythonVersion;
92 } // attrs) ''
93 cp -r ${./tests/test_environments} tests
94 chmod -R +w tests
95 substituteAllInPlace tests/test_python.py
96 ${attrs.interpreter} -m unittest discover --verbose tests #/test_python.py
97 mkdir $out
98 touch $out/success
99 '';
100
101 in lib.mapAttrs testfun envs;
102
103 # Integration tests involving the package set.
104 # All PyPy package builds are broken at the moment
105 integrationTests = lib.optionalAttrs (!python.isPyPy) (
106 lib.optionalAttrs (python.isPy3k && !stdenv.isDarwin) { # darwin has no split-debug
107 cpython-gdb = callPackage ./tests/test_cpython_gdb {
108 interpreter = python;
109 };
110 } // lib.optionalAttrs (python.pythonAtLeast "3.7") rec {
111 # Before the addition of NIX_PYTHONPREFIX mypy was broken with typed packages
112 nix-pythonprefix-mypy = callPackage ./tests/test_nix_pythonprefix {
113 interpreter = python;
114 };
115 }
116 );
117
118 # Tests to ensure overriding works as expected.
119 overrideTests = let
120 extension = self: super: {
121 foobar = super.numpy;
122 };
123 in {
124 test-packageOverrides = let
125 myPython = let
126 self = python.override {
127 packageOverrides = extension;
128 inherit self;
129 };
130 in self;
131 in assert myPython.pkgs.foobar == myPython.pkgs.numpy; myPython.withPackages(ps: with ps; [ foobar ]);
132 # overrideScope is broken currently
133 # test-overrideScope = let
134 # myPackages = python.pkgs.overrideScope extension;
135 # in assert myPackages.foobar == myPackages.numpy; myPackages.python.withPackages(ps: with ps; [ foobar ]);
136 };
137
138 condaTests = let
139 requests = callPackage ({
140 autoPatchelfHook,
141 fetchurl,
142 pythonCondaPackages,
143 }:
144 python.pkgs.buildPythonPackage {
145 pname = "requests";
146 version = "2.24.0";
147 format = "other";
148 src = fetchurl {
149 url = "https://repo.anaconda.com/pkgs/main/noarch/requests-2.24.0-py_0.tar.bz2";
150 sha256 = "02qzaf6gwsqbcs69pix1fnjxzgnngwzvrsy65h1d521g750mjvvp";
151 };
152 nativeBuildInputs = [ autoPatchelfHook ] ++ (with python.pkgs; [
153 condaUnpackHook condaInstallHook
154 ]);
155 buildInputs = [
156 pythonCondaPackages.condaPatchelfLibs
157 ];
158 propagatedBuildInputs = with python.pkgs; [
159 chardet idna urllib3 certifi
160 ];
161 }
162 ) {};
163 pythonWithRequests = requests.pythonModule.withPackages (ps: [ requests ]);
164 in
165 {
166 condaExamplePackage = runCommand "import-requests" {} ''
167 ${pythonWithRequests.interpreter} -c "import requests" > $out
168 '';
169 };
170
171in lib.optionalAttrs (stdenv.hostPlatform == stdenv.buildPlatform ) (environmentTests // integrationTests // overrideTests // condaTests)