core/pkgs/by-name/py/python/tests.nix

177 lines
6.8 KiB
Nix
Raw Normal View History

2024-05-02 00:46:19 +00:00
# Tests for the Python interpreters, package sets and environments.
#
# Each Python interpreter has a `passthru.tests` which is the attribute set
# returned by this function. For example, for Python 3 the tests are run with
#
# $ nix-build -A python3.tests
#
2024-05-13 21:24:10 +00:00
{ stdenv, python, runCommand, lib, callPackage, pkgs }:
2024-05-02 00:46:19 +00:00
let
# Test whether the interpreter behaves in the different types of environments
# we aim to support.
environmentTests = let
envs = let
inherit python;
2024-05-13 21:24:10 +00:00
pythonEnv = python.withPackages (ps: with ps; [ ]);
pythonVirtualEnv = if python.isPy3k then
python.withPackages (ps: with ps; [ virtualenv ])
else
python.buildEnv.override {
extraLibs = with python.pkgs; [ virtualenv ];
# Collisions because of namespaces __init__.py
ignoreCollisions = true;
};
2024-05-02 00:46:19 +00:00
in {
# Plain Python interpreter
plain = rec {
env = python;
interpreter = env.interpreter;
is_venv = "False";
is_nixenv = "False";
is_virtualenv = "False";
};
} // lib.optionalAttrs (!python.isPyPy && !stdenv.isDarwin) {
# Use virtualenv from a Nix env.
# Fails on darwin with
# virtualenv: error: argument dest: the destination . is not write-able at /nix/store
nixenv-virtualenv = rec {
2024-05-13 21:24:10 +00:00
env = runCommand "${python.name}-virtualenv" { } ''
2024-05-02 00:46:19 +00:00
${pythonVirtualEnv.interpreter} -m virtualenv venv
mv venv $out
'';
interpreter = "${env}/bin/${python.executable}";
is_venv = "False";
is_nixenv = "True";
is_virtualenv = "True";
};
} // lib.optionalAttrs (python.implementation != "graal") {
# Python Nix environment (python.buildEnv)
nixenv = rec {
env = pythonEnv;
interpreter = env.interpreter;
is_venv = "False";
is_nixenv = "True";
is_virtualenv = "False";
};
} // lib.optionalAttrs (python.isPy3k && (!python.isPyPy)) {
# Venv built using plain Python
# Python 2 does not support venv
# TODO: PyPy executable name is incorrect, it should be pypy-c or pypy-3c instead of pypy and pypy3.
plain-venv = rec {
2024-05-13 21:24:10 +00:00
env = runCommand "${python.name}-venv" { } ''
2024-05-02 00:46:19 +00:00
${python.interpreter} -m venv $out
'';
interpreter = "${env}/bin/${python.executable}";
is_venv = "True";
is_nixenv = "False";
is_virtualenv = "False";
};
} // lib.optionalAttrs (python.pythonAtLeast "3.8") {
# Venv built using Python Nix environment (python.buildEnv)
# TODO: Cannot create venv from a nix env
# Error: Command '['/nix/store/ddc8nqx73pda86ibvhzdmvdsqmwnbjf7-python3-3.7.6-venv/bin/python3.7', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1.
nixenv-venv = rec {
2024-05-13 21:24:10 +00:00
env = runCommand "${python.name}-venv" { } ''
2024-05-02 00:46:19 +00:00
${pythonEnv.interpreter} -m venv $out
'';
interpreter = "${env}/bin/${pythonEnv.executable}";
is_venv = "True";
is_nixenv = "True";
is_virtualenv = "False";
};
};
2024-05-13 21:24:10 +00:00
testfun = name: attrs:
runCommand "${python.name}-tests-${name}"
({ inherit (python) pythonVersion; } // attrs) ''
cp -r ${./tests/test_environments} tests
chmod -R +w tests
substituteAllInPlace tests/test_python.py
${attrs.interpreter} -m unittest discover --verbose tests #/test_python.py
mkdir $out
touch $out/success
'';
2024-05-02 00:46:19 +00:00
in lib.mapAttrs testfun envs;
# Integration tests involving the package set.
# All PyPy package builds are broken at the moment
2024-05-13 21:24:10 +00:00
integrationTests = lib.optionalAttrs (!python.isPyPy) (lib.optionalAttrs
(python.isPy3k && !stdenv.isDarwin) { # darwin has no split-debug
cpython-gdb =
callPackage ./tests/test_cpython_gdb { interpreter = python; };
2024-05-02 00:46:19 +00:00
} // lib.optionalAttrs (python.pythonAtLeast "3.7") {
# Before the addition of NIX_PYTHONPREFIX mypy was broken with typed packages
2024-05-13 21:24:10 +00:00
nix-pythonprefix-mypy =
callPackage ./tests/test_nix_pythonprefix { interpreter = python; };
2024-05-02 00:46:19 +00:00
# Make sure tkinter is importable. See https://github.com/NixOS/nixpkgs/issues/238990
2024-05-13 21:24:10 +00:00
tkinter = callPackage ./tests/test_tkinter { interpreter = python; };
});
2024-05-02 00:46:19 +00:00
# Tests to ensure overriding works as expected.
overrideTests = let
2024-05-13 21:24:10 +00:00
extension = self: super: { foobar = super.numpy; };
2024-05-02 00:46:19 +00:00
# `pythonInterpreters.pypy39_prebuilt` does not expose an attribute
# name (is not present in top-level `pkgs`).
is_prebuilt = python: python.pythonAttr == null;
in lib.optionalAttrs (python.isPy3k) ({
test-packageOverrides = let
myPython = let
self = python.override {
packageOverrides = extension;
inherit self;
};
in self;
2024-05-13 21:24:10 +00:00
in assert myPython.pkgs.foobar == myPython.pkgs.numpy;
myPython.withPackages (ps: with ps; [ foobar ]);
2024-05-02 00:46:19 +00:00
# overrideScope is broken currently
# test-overrideScope = let
# myPackages = python.pkgs.overrideScope extension;
# in assert myPackages.foobar == myPackages.numpy; myPackages.python.withPackages(ps: with ps; [ foobar ]);
#
# Have to skip prebuilt python as it's not present in top-level
# `pkgs` as an attribute.
} // lib.optionalAttrs (python ? pythonAttr && !is_prebuilt python) {
# Test applying overrides using pythonPackagesOverlays.
test-pythonPackagesExtensions = let
2024-05-13 21:24:10 +00:00
pkgs_ = pkgs.extend (final: prev: {
pythonPackagesExtensions = prev.pythonPackagesExtensions
++ [ (python-final: python-prev: { foo = python-prev.setuptools; }) ];
2024-05-02 00:46:19 +00:00
});
in pkgs_.${python.pythonAttr}.pkgs.foo;
});
condaTests = let
2024-05-13 21:24:10 +00:00
requests = callPackage
({ autoPatchelfHook, fetchurl, pythonCondaPackages, }:
python.pkgs.buildPythonPackage {
pname = "requests";
version = "2.24.0";
format = "other";
src = fetchurl {
url =
"https://repo.anaconda.com/pkgs/main/noarch/requests-2.24.0-py_0.tar.bz2";
sha256 = "02qzaf6gwsqbcs69pix1fnjxzgnngwzvrsy65h1d521g750mjvvp";
};
nativeBuildInputs = [ autoPatchelfHook ]
++ (with python.pkgs; [ condaUnpackHook condaInstallHook ]);
buildInputs = [ pythonCondaPackages.condaPatchelfLibs ];
propagatedBuildInputs = with python.pkgs; [
chardet
idna
urllib3
certifi
];
}) { };
2024-05-02 00:46:19 +00:00
pythonWithRequests = requests.pythonModule.withPackages (ps: [ requests ]);
2024-05-13 21:24:10 +00:00
in lib.optionalAttrs (python.isPy3k && stdenv.isLinux) {
condaExamplePackage = runCommand "import-requests" { } ''
${pythonWithRequests.interpreter} -c "import requests" > $out
'';
};
2024-05-02 00:46:19 +00:00
2024-05-13 21:24:10 +00:00
in lib.optionalAttrs (stdenv.hostPlatform == stdenv.buildPlatform)
(environmentTests // integrationTests // overrideTests // condaTests)