1{
2 lib,
3 stdenv,
4 buildPythonPackage,
5 fetchFromGitHub,
6 fetchpatch2,
7 gitUpdater,
8 pythonAtLeast,
9 pythonOlder,
10
11 # build-system
12 setuptools,
13 types-psutil,
14 types-setuptools,
15 wheel,
16
17 # propagates
18 mypy-extensions,
19 tomli,
20 typing-extensions,
21
22 # optionals
23 lxml,
24 psutil,
25
26 # tests
27 attrs,
28 filelock,
29 pytest-xdist,
30 pytestCheckHook,
31 nixosTests,
32}:
33
34buildPythonPackage rec {
35 pname = "mypy";
36 version = "1.11.2";
37 pyproject = true;
38
39 # mypy doesn't support python313 yet
40 # https://github.com/python/mypy/issues/17264
41 disabled = pythonOlder "3.8" || pythonAtLeast "3.13";
42
43 src = fetchFromGitHub {
44 owner = "python";
45 repo = "mypy";
46 rev = "refs/tags/v${version}";
47 hash = "sha256-5gfqIBtI/G5HARYdXHjYNYNRxeNgrk9dnpSgvMSu9bw=";
48 };
49
50 patches = [
51 (fetchpatch2 {
52 name = "python3.12.7-compat.patch";
53 url = "https://github.com/python/mypy/commit/1a2c8e2a4df21532e4952191cad74ae50083f4ad.patch";
54 hash = "sha256-GBQPTkdoLeErjbRUjZBFEwvCcN/WzC3OYVvou6M+f80=";
55 })
56 ];
57
58 passthru.updateScript = gitUpdater {
59 rev-prefix = "v";
60 };
61
62 build-system = [
63 mypy-extensions
64 setuptools
65 types-psutil
66 types-setuptools
67 typing-extensions
68 wheel
69 ] ++ lib.optionals (pythonOlder "3.11") [ tomli ];
70
71 dependencies = [
72 mypy-extensions
73 typing-extensions
74 ] ++ lib.optionals (pythonOlder "3.11") [ tomli ];
75
76 optional-dependencies = {
77 dmypy = [ psutil ];
78 reports = [ lxml ];
79 };
80
81 # Compile mypy with mypyc, which makes mypy about 4 times faster. The compiled
82 # version is also the default in the wheels on Pypi that include binaries.
83 # is64bit: unfortunately the build would exhaust all possible memory on i686-linux.
84 env.MYPY_USE_MYPYC = stdenv.buildPlatform.is64bit;
85
86 # when testing reduce optimisation level to reduce build time by 20%
87 env.MYPYC_OPT_LEVEL = 1;
88
89 pythonImportsCheck =
90 [
91 "mypy"
92 "mypy.api"
93 "mypy.fastparse"
94 "mypy.types"
95 "mypyc"
96 "mypyc.analysis"
97 ]
98 ++ lib.optionals (!stdenv.hostPlatform.isi686) [
99 # ImportError: cannot import name 'map_instance_to_supertype' from partially initialized module 'mypy.maptype' (most likely due to a circular import)
100 "mypy.report"
101 ];
102
103 nativeCheckInputs = [
104 attrs
105 filelock
106 pytest-xdist
107 pytestCheckHook
108 setuptools
109 tomli
110 ] ++ lib.flatten (lib.attrValues optional-dependencies);
111
112 disabledTests =
113 [
114 # fails with typing-extensions>=4.10
115 # https://github.com/python/mypy/issues/17005
116 "test_runtime_typing_objects"
117 ]
118 ++ lib.optionals (pythonAtLeast "3.12") [
119 # requires distutils
120 "test_c_unit_test"
121 ];
122
123 disabledTestPaths =
124 [
125 # fails to find tyoing_extensions
126 "mypy/test/testcmdline.py"
127 "mypy/test/testdaemon.py"
128 # fails to find setuptools
129 "mypyc/test/test_commandline.py"
130 # fails to find hatchling
131 "mypy/test/testpep561.py"
132 ]
133 ++ lib.optionals stdenv.hostPlatform.isi686 [
134 # https://github.com/python/mypy/issues/15221
135 "mypyc/test/test_run.py"
136 ];
137
138 passthru.tests = {
139 # Failing typing checks on the test-driver result in channel blockers.
140 inherit (nixosTests) nixos-test-driver;
141 };
142
143 meta = with lib; {
144 description = "Optional static typing for Python";
145 homepage = "https://www.mypy-lang.org";
146 changelog = "https://github.com/python/mypy/blob/${src.rev}/CHANGELOG.md";
147 license = licenses.mit;
148 mainProgram = "mypy";
149 maintainers = with maintainers; [ lnl7 ];
150 };
151}