6
6
import logging
7
7
import os
8
8
import sys
9
+ import sysconfig
9
10
from abc import ABC
10
11
from functools import cached_property
11
12
from importlib .resources import as_file , files
@@ -131,6 +132,7 @@ def _get_python(self, base_python: list[str]) -> PythonInfo | None: # noqa: PLR
131
132
is_64 = sys .maxsize > 2 ** 32 ,
132
133
platform = sys .platform ,
133
134
extra = {},
135
+ free_threaded = sysconfig .get_config_var ("Py_GIL_DISABLED" ) == 1 ,
134
136
)
135
137
base_path = Path (base )
136
138
if base_path .is_absolute ():
@@ -142,6 +144,7 @@ def _get_python(self, base_python: list[str]) -> PythonInfo | None: # noqa: PLR
142
144
is_64 = info .architecture == 64 , # noqa: PLR2004
143
145
platform = info .platform ,
144
146
extra = {"executable" : base },
147
+ free_threaded = info .free_threaded ,
145
148
)
146
149
spec = PythonSpec .from_string_spec (base )
147
150
return PythonInfo (
@@ -157,6 +160,7 @@ def _get_python(self, base_python: list[str]) -> PythonInfo | None: # noqa: PLR
157
160
is_64 = spec .architecture == 64 , # noqa: PLR2004
158
161
platform = sys .platform ,
159
162
extra = {"architecture" : spec .architecture },
163
+ free_threaded = spec .free_threaded ,
160
164
)
161
165
162
166
return None # pragma: no cover
@@ -256,25 +260,28 @@ def env_version_spec(self) -> str:
256
260
imp = self .base_python .impl_lower
257
261
executable = self .base_python .extra .get ("executable" )
258
262
architecture = self .base_python .extra .get ("architecture" )
263
+ free_threaded = self .base_python .free_threaded
259
264
if executable :
260
265
version_spec = str (executable )
261
266
elif (
262
267
architecture is None
263
268
and (base .major , base .minor ) == sys .version_info [:2 ]
264
269
and (sys .implementation .name .lower () == imp )
270
+ and ((sysconfig .get_config_var ("Py_GIL_DISABLED" ) == 1 ) == free_threaded )
265
271
):
266
272
version_spec = sys .executable
267
273
else :
268
274
uv_imp = imp or ""
275
+ free_threaded_tag = "+freethreaded" if free_threaded else ""
269
276
if not base .major :
270
277
version_spec = f"{ uv_imp } "
271
278
elif not base .minor :
272
- version_spec = f"{ uv_imp } { base .major } "
279
+ version_spec = f"{ uv_imp } { base .major } { free_threaded_tag } "
273
280
elif architecture is not None and self .base_python .platform == "win32" :
274
281
uv_arch = {32 : "x86" , 64 : "x86_64" }[architecture ]
275
- version_spec = f"{ uv_imp } -{ base .major } .{ base .minor } -windows-{ uv_arch } -none"
282
+ version_spec = f"{ uv_imp } -{ base .major } .{ base .minor } { free_threaded_tag } -windows-{ uv_arch } -none"
276
283
else :
277
- version_spec = f"{ uv_imp } { base .major } .{ base .minor } "
284
+ version_spec = f"{ uv_imp } { base .major } .{ base .minor } { free_threaded_tag } "
278
285
return version_spec
279
286
280
287
@cached_property
0 commit comments