11from __future__ import annotations
22
33import sys
4+ import sysconfig
45from types import SimpleNamespace
56from typing import TYPE_CHECKING , Callable
67from unittest .mock import patch
@@ -81,30 +82,56 @@ def test_diff_msg_no_diff() -> None:
8182 ("env" , "base_python" ),
8283 [
8384 ("py3" , "py3" ),
85+ ("py3t" , "py3t" ),
8486 ("py311" , "py311" ),
87+ ("py311t" , "py311t" ),
8588 ("py3.12" , "py3.12" ),
89+ ("py3.12t" , "py3.12t" ),
8690 ("pypy2" , "pypy2" ),
91+ ("pypy2t" , "pypy2t" ),
8792 ("rustpython3" , "rustpython3" ),
93+ ("rustpython3t" , "rustpython3t" ),
8894 ("graalpy" , "graalpy" ),
95+ ("graalpyt" , None ),
8996 ("jython" , "jython" ),
97+ ("jythont" , None ),
9098 ("cpython3.8" , "cpython3.8" ),
99+ ("cpython3.8t" , "cpython3.8t" ),
91100 ("ironpython2.7" , "ironpython2.7" ),
101+ ("ironpython2.7t" , "ironpython2.7t" ),
92102 ("functional-py310" , "py310" ),
103+ ("functional-py310t" , "py310t" ),
93104 ("bar-pypy2-foo" , "pypy2" ),
105+ ("bar-foo2t-py2" , "py2" ),
106+ ("bar-pypy2t-foo" , "pypy2t" ),
94107 ("py" , None ),
108+ ("pyt" , None ),
95109 ("django-32" , None ),
110+ ("django-32t" , None ),
96111 ("eslint-8.3" , None ),
112+ ("eslint-8.3t" , None ),
97113 ("py-310" , None ),
114+ ("py-310t" , None ),
98115 ("py3000" , None ),
116+ ("py3000t" , None ),
99117 ("4.foo" , None ),
118+ ("4.foot" , None ),
100119 ("310" , None ),
120+ ("310t" , None ),
101121 ("5" , None ),
122+ ("5t" , None ),
102123 ("2000" , None ),
124+ ("2000t" , None ),
103125 ("4000" , None ),
126+ ("4000t" , None ),
104127 ("3.10" , "3.10" ),
128+ ("3.10t" , "3.10t" ),
105129 ("3.9" , "3.9" ),
130+ ("3.9t" , "3.9t" ),
106131 ("2.7" , "2.7" ),
132+ ("2.7t" , "2.7t" ),
107133 ("pypy-3.10" , "pypy3.10" ),
134+ ("pypy-3.10t" , "pypy3.10t" ),
108135 ],
109136 ids = lambda a : "|" .join (a ) if isinstance (a , list ) else str (a ),
110137)
@@ -294,13 +321,24 @@ def test_usedevelop_with_nonexistent_basepython(tox_project: ToxProjectCreator)
294321
295322
296323@pytest .mark .parametrize (
297- ("impl" , "major" , "minor" , "arch" ),
324+ ("impl" , "major" , "minor" , "arch" , "free_threaded" ),
298325 [
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 ),
301330 ],
302331)
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+
304342 version_info = SimpleNamespace (major = major , minor = minor , micro = 5 , releaselevel = "final" , serial = 0 )
305343 implementation = SimpleNamespace (
306344 name = impl ,
@@ -312,8 +350,10 @@ def test_python_spec_for_sys_executable(impl: str, major: int, minor: int, arch:
312350 mocker .patch .object (sys , "version_info" , version_info )
313351 mocker .patch .object (sys , "implementation" , implementation )
314352 mocker .patch .object (sys , "maxsize" , 2 ** arch // 2 - 1 )
353+ mocker .patch .object (sysconfig , "get_config_var" , get_config_var )
315354 spec = Python ._python_spec_for_sys_executable () # noqa: SLF001
316355 assert spec .implementation == impl
317356 assert spec .major == major
318357 assert spec .minor == minor
319358 assert spec .architecture == arch
359+ assert spec .free_threaded == bool (free_threaded )
0 commit comments