1
1
from __future__ import annotations
2
2
3
3
import sys
4
+ import sysconfig
4
5
from types import SimpleNamespace
5
6
from typing import TYPE_CHECKING , Callable
6
7
from unittest .mock import patch
@@ -81,30 +82,56 @@ def test_diff_msg_no_diff() -> None:
81
82
("env" , "base_python" ),
82
83
[
83
84
("py3" , "py3" ),
85
+ ("py3t" , "py3t" ),
84
86
("py311" , "py311" ),
87
+ ("py311t" , "py311t" ),
85
88
("py3.12" , "py3.12" ),
89
+ ("py3.12t" , "py3.12t" ),
86
90
("pypy2" , "pypy2" ),
91
+ ("pypy2t" , "pypy2t" ),
87
92
("rustpython3" , "rustpython3" ),
93
+ ("rustpython3t" , "rustpython3t" ),
88
94
("graalpy" , "graalpy" ),
95
+ ("graalpyt" , None ),
89
96
("jython" , "jython" ),
97
+ ("jythont" , None ),
90
98
("cpython3.8" , "cpython3.8" ),
99
+ ("cpython3.8t" , "cpython3.8t" ),
91
100
("ironpython2.7" , "ironpython2.7" ),
101
+ ("ironpython2.7t" , "ironpython2.7t" ),
92
102
("functional-py310" , "py310" ),
103
+ ("functional-py310t" , "py310t" ),
93
104
("bar-pypy2-foo" , "pypy2" ),
105
+ ("bar-foo2t-py2" , "py2" ),
106
+ ("bar-pypy2t-foo" , "pypy2t" ),
94
107
("py" , None ),
108
+ ("pyt" , None ),
95
109
("django-32" , None ),
110
+ ("django-32t" , None ),
96
111
("eslint-8.3" , None ),
112
+ ("eslint-8.3t" , None ),
97
113
("py-310" , None ),
114
+ ("py-310t" , None ),
98
115
("py3000" , None ),
116
+ ("py3000t" , None ),
99
117
("4.foo" , None ),
118
+ ("4.foot" , None ),
100
119
("310" , None ),
120
+ ("310t" , None ),
101
121
("5" , None ),
122
+ ("5t" , None ),
102
123
("2000" , None ),
124
+ ("2000t" , None ),
103
125
("4000" , None ),
126
+ ("4000t" , None ),
104
127
("3.10" , "3.10" ),
128
+ ("3.10t" , "3.10t" ),
105
129
("3.9" , "3.9" ),
130
+ ("3.9t" , "3.9t" ),
106
131
("2.7" , "2.7" ),
132
+ ("2.7t" , "2.7t" ),
107
133
("pypy-3.10" , "pypy3.10" ),
134
+ ("pypy-3.10t" , "pypy3.10t" ),
108
135
],
109
136
ids = lambda a : "|" .join (a ) if isinstance (a , list ) else str (a ),
110
137
)
@@ -294,13 +321,24 @@ def test_usedevelop_with_nonexistent_basepython(tox_project: ToxProjectCreator)
294
321
295
322
296
323
@pytest .mark .parametrize (
297
- ("impl" , "major" , "minor" , "arch" ),
324
+ ("impl" , "major" , "minor" , "arch" , "free_threaded" ),
298
325
[
299
- ("cpython" , 3 , 12 , 64 ),
300
- ("pypy" , 3 , 9 , 32 ),
326
+ ("cpython" , 3 , 12 , 64 , None ),
327
+ ("cpython" , 3 , 13 , 64 , True ),
328
+ ("cpython" , 3 , 13 , 64 , False ),
329
+ ("pypy" , 3 , 9 , 32 , None ),
301
330
],
302
331
)
303
- def test_python_spec_for_sys_executable (impl : str , major : int , minor : int , arch : int , mocker : MockerFixture ) -> None :
332
+ def test_python_spec_for_sys_executable ( # noqa: PLR0913
333
+ impl : str , major : int , minor : int , arch : int , free_threaded : bool | None , mocker : MockerFixture
334
+ ) -> None :
335
+ get_config_var_ = sysconfig .get_config_var
336
+
337
+ def get_config_var (name : str ) -> object :
338
+ if name == "Py_GIL_DISABLED" :
339
+ return free_threaded
340
+ return get_config_var_ (name )
341
+
304
342
version_info = SimpleNamespace (major = major , minor = minor , micro = 5 , releaselevel = "final" , serial = 0 )
305
343
implementation = SimpleNamespace (
306
344
name = impl ,
@@ -312,8 +350,10 @@ def test_python_spec_for_sys_executable(impl: str, major: int, minor: int, arch:
312
350
mocker .patch .object (sys , "version_info" , version_info )
313
351
mocker .patch .object (sys , "implementation" , implementation )
314
352
mocker .patch .object (sys , "maxsize" , 2 ** arch // 2 - 1 )
353
+ mocker .patch .object (sysconfig , "get_config_var" , get_config_var )
315
354
spec = Python ._python_spec_for_sys_executable () # noqa: SLF001
316
355
assert spec .implementation == impl
317
356
assert spec .major == major
318
357
assert spec .minor == minor
319
358
assert spec .architecture == arch
359
+ assert spec .free_threaded == bool (free_threaded )
0 commit comments