Skip to content

Commit 2dbf4f2

Browse files
authored
Fix backwards incompatible changes on PythonInfo (#2975)
1 parent de1820d commit 2dbf4f2

File tree

5 files changed

+24
-28
lines changed

5 files changed

+24
-28
lines changed

.github/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
changelog:
22
exclude:
33
authors:
4-
- dependabot
5-
- pre-commit-ci
4+
- dependabot[bot]
5+
- pre-commit-ci[bot]

docs/changelog/2975.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix backwards incompatible changes to ``PythonInfo`` - by :user:`gaborbernat`.

src/virtualenv/discovery/py_info.py

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ def _get_path_extensions():
2727

2828

2929
EXTENSIONS = _get_path_extensions()
30-
_CONF_VAR_RE = re.compile(r"\{\w+\}")
30+
_CONF_VAR_RE = re.compile(r"\{\w+}")
3131

3232

33-
class PythonInfo:
33+
class PythonInfo: # noqa: PLR0904
3434
"""Contains information for a Python interpreter."""
3535

3636
def __init__(self) -> None: # noqa: PLR0915
@@ -135,6 +135,7 @@ def abs_path(v):
135135
self.system_stdlib = self.sysconfig_path("stdlib", confs)
136136
self.system_stdlib_platform = self.sysconfig_path("platstdlib", confs)
137137
self.max_size = getattr(sys, "maxsize", getattr(sys, "maxint", None))
138+
self._creators = None
138139

139140
@staticmethod
140141
def _get_tcl_tk_libs():
@@ -310,6 +311,13 @@ def sysconfig_path(self, key, config_var=None, sep=os.sep):
310311
config_var = base
311312
return pattern.format(**config_var).replace("/", sep)
312313

314+
def creators(self, refresh=False): # noqa: FBT002
315+
if self._creators is None or refresh is True:
316+
from virtualenv.run.plugin.creators import CreatorSelector # noqa: PLC0415
317+
318+
self._creators = CreatorSelector.for_interpreter(self)
319+
return self._creators
320+
313321
@property
314322
def system_include(self):
315323
path = self.sysconfig_path(
@@ -423,7 +431,7 @@ def satisfies(self, spec, impl_must_match): # noqa: C901, PLR0911
423431
_current = None
424432

425433
@classmethod
426-
def current(cls, app_data, cache):
434+
def current(cls, app_data=None, cache=None):
427435
"""
428436
This locates the current host interpreter information. This might be different than what we run into in case
429437
the host python has been upgraded from underneath us.
@@ -439,7 +447,7 @@ def current(cls, app_data, cache):
439447
return cls._current
440448

441449
@classmethod
442-
def current_system(cls, app_data, cache) -> PythonInfo:
450+
def current_system(cls, app_data=None, cache=None) -> PythonInfo:
443451
"""
444452
This locates the current host interpreter information. This might be different than what we run into in case
445453
the host python has been upgraded from underneath us.
@@ -467,8 +475,8 @@ def _to_dict(self):
467475
def from_exe( # noqa: PLR0913
468476
cls,
469477
exe,
470-
app_data,
471-
cache,
478+
app_data=None,
479+
cache=None,
472480
raise_on_error=True, # noqa: FBT002
473481
ignore_cache=False, # noqa: FBT002
474482
resolve_to_host=True, # noqa: FBT002
@@ -480,13 +488,7 @@ def from_exe( # noqa: PLR0913
480488

481489
env = os.environ if env is None else env
482490
proposed = from_exe_cache(
483-
cls,
484-
app_data,
485-
exe,
486-
env=env,
487-
raise_on_error=raise_on_error,
488-
ignore_cache=ignore_cache,
489-
cache=cache,
491+
cls, app_data, exe, env=env, raise_on_error=raise_on_error, ignore_cache=ignore_cache, cache=cache
490492
)
491493

492494
if isinstance(proposed, PythonInfo) and resolve_to_host:
@@ -538,7 +540,7 @@ def _resolve_to_system(cls, app_data, target, cache):
538540

539541
_cache_exe_discovery = {} # noqa: RUF012
540542

541-
def discover_exe(self, app_data, cache, prefix, exact=True, env=None): # noqa: FBT002
543+
def discover_exe(self, app_data, prefix, exact=True, env=None, cache=None): # noqa: FBT002
542544
key = prefix, exact
543545
if key in self._cache_exe_discovery and prefix:
544546
LOGGER.debug("discover exe from cache %s - exact %s: %r", prefix, exact, self._cache_exe_discovery[key])
@@ -568,14 +570,7 @@ def _check_exe(self, app_data, cache, folder, name, exact, discovered, env): #
568570
exe_path = os.path.join(folder, name)
569571
if not os.path.exists(exe_path):
570572
return None
571-
info = self.from_exe(
572-
exe_path,
573-
app_data,
574-
cache,
575-
resolve_to_host=False,
576-
raise_on_error=False,
577-
env=env,
578-
)
573+
info = self.from_exe(exe_path, app_data, cache, resolve_to_host=False, raise_on_error=False, env=env)
579574
if info is None: # ignore if for some reason we can't query
580575
return None
581576
for item in ["implementation", "architecture", "version_info"]:

tests/unit/create/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def venv(tmp_path_factory, session_app_data, current_info):
3838
# sadly creating a virtual environment does not tell us where the executable lives in general case
3939
# so discover using some heuristic
4040
cache = FileCache(session_app_data.py_info, session_app_data.py_info_clear)
41-
return current_info.discover_exe(session_app_data, cache, prefix=str(dest)).original_executable
41+
return current_info.discover_exe(session_app_data, prefix=str(dest), cache=cache).original_executable
4242

4343

4444
PYTHON = {

tests/unit/discovery/py_info/test_py_info_exe_based_of.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
def test_discover_empty_folder(tmp_path):
1717
app_data, cache = MockAppData(), MockCache()
1818
with pytest.raises(RuntimeError):
19-
CURRENT.discover_exe(app_data, cache, prefix=str(tmp_path))
19+
CURRENT.discover_exe(app_data, prefix=str(tmp_path), cache=cache)
2020

2121

2222
BASE = (CURRENT.install_path("scripts"), ".")
@@ -43,7 +43,7 @@ def test_discover_ok(tmp_path, suffix, impl, version, arch, into, caplog): # no
4343
if pyvenv.exists():
4444
(folder / pyvenv.name).write_text(pyvenv.read_text(encoding="utf-8"), encoding="utf-8")
4545
inside_folder = str(tmp_path)
46-
base = CURRENT.discover_exe(app_data, cache, inside_folder)
46+
base = CURRENT.discover_exe(app_data, inside_folder, cache=cache)
4747
found = base.executable
4848
dest_str = str(dest)
4949
if not fs_is_case_sensitive():
@@ -56,4 +56,4 @@ def test_discover_ok(tmp_path, suffix, impl, version, arch, into, caplog): # no
5656
dest.rename(dest.parent / (dest.name + "-1"))
5757
CURRENT._cache_exe_discovery.clear() # noqa: SLF001
5858
with pytest.raises(RuntimeError):
59-
CURRENT.discover_exe(app_data, cache, inside_folder)
59+
CURRENT.discover_exe(app_data, inside_folder, cache=cache)

0 commit comments

Comments
 (0)