Python: introduce tests for interpreters

This adds tests to the passthru of all Python interpreters.
This commit is contained in:
Frederik Rietdijk 2020-03-14 09:48:06 +01:00
parent 39aac70d74
commit dbf125d286
3 changed files with 117 additions and 0 deletions

View file

@ -44,6 +44,10 @@ with pkgs;
pythonAtLeast = lib.versionAtLeast pythonVersion;
pythonOlder = lib.versionOlder pythonVersion;
inherit hasDistutilsCxxPatch pythonForBuild;
tests = callPackage ./tests.nix {
python = self;
};
};
in {

View file

@ -0,0 +1,63 @@
{ python
, runCommand
, substituteAll
, lib
}:
let
envs = let
inherit python;
pythonEnv = python.withPackages(ps: with ps; [ ]);
in {
# Plain Python interpreter
plain = rec {
env = python;
interpreter = env.interpreter;
is_venv = "False";
is_nixenv = "False";
};
} // lib.optionalAttrs (python.implementation != "graal") {
# Python Nix environment (python.buildEnv)
nixenv = rec {
env = pythonEnv;
interpreter = env.interpreter;
is_venv = "False";
is_nixenv = "True";
};
} // lib.optionalAttrs (python.isPy3k && (!python.isPyPy)) rec {
# 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 {
env = runCommand "${python.name}-venv" {} ''
${python.interpreter} -m venv $out
'';
interpreter = "${env}/bin/${python.executable}";
is_venv = "True";
is_nixenv = "False";
};
# 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 {
# env = runCommand "${python.name}-venv" {} ''
# ${pythonEnv.interpreter} -m venv $out
# '';
# interpreter = "${env}/bin/${pythonEnv.executable}";
# is_venv = "True";
# is_nixenv = "True";
# };
};
testfun = name: attrs: runCommand "${python.name}-tests-${name}" ({
inherit (python) pythonVersion;
} // attrs) ''
cp -r ${./tests} 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
'';
in lib.mapAttrs testfun envs

View file

@ -0,0 +1,50 @@
"""
Python interpreter and environment tests.
These need to be executed with the standard library unittest.
Third party test runners such as pytest cannot be used because
that would interfere with the tests.
"""
import platform
import sys
import unittest
import site
ENV = "@env@"
INTERPRETER = "@interpreter@"
PYTHON_VERSION = "@pythonVersion@"
IS_VENV = @is_venv@
IS_NIXENV = @is_nixenv@
IS_PYPY = platform.python_implementation() == "PyPy"
class TestCasePython(unittest.TestCase):
@unittest.skipIf(IS_PYPY, "Executable is incorrect and needs to be fixed.")
def test_interpreter(self):
self.assertEqual(sys.executable, INTERPRETER)
@unittest.skipIf(IS_NIXENV or IS_PYPY, "Prefix is incorrect and needs to be fixed.")
def test_prefix(self):
self.assertEqual(sys.prefix, ENV)
self.assertEqual(sys.prefix, sys.exec_prefix)
def test_site_prefix(self):
self.assertTrue(sys.prefix in site.PREFIXES)
@unittest.skipIf(sys.version_info.major==2, "Python 2 does not have base_prefix")
def test_base_prefix(self):
if IS_VENV:
self.assertNotEqual(sys.prefix, sys.base_prefix)
else:
self.assertEqual(sys.prefix, sys.base_prefix)
def test_python_version(self):
self.assertTrue(platform.python_version().startswith(PYTHON_VERSION))
if __name__ == "__main__":
unittest.main()