Skip to content

Commit 874e9af

Browse files
authored
Fixup the spec string for sys.executable (#3327)
* Fixup the spec string for sys.executable The previous spec string was: namespace(name='cpython', cache_tag='cpython-313', version=sys.version_info(major=3, minor=13, micro=0, releaselevel='candidate', serial=1), hexversion=51183809, _multiarch='x86_64-linux-gnu')313-True When it was supposed to be: cpython313-64 Fixes https://github.com/tox-dev/tox/pull/3325/files#r1718230254 Fixes https://github.com/tox-dev/tox/pull/3325/files#r1718246292 Adds tests for a new method. * Make the new method private * Silence the linter, this is a test for a private method The error was: tests/tox_env/python/test_python_api.py:314:12: SLF001 Private member accessed: `_python_spec_for_sys_executable` | 312 | mocker.patch.object(sys, "implementation", implementation) 313 | mocker.patch.object(sys, "maxsize", 2**arch // 2 - 1) 314 | spec = Python._python_spec_for_sys_executable() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SLF001 315 | assert spec.implementation == impl 316 | assert spec.major == major | Found 1 error. * Add a changelog fragment
1 parent dde4964 commit 874e9af

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

docs/changelog/3327.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix and test the string spec for the ``sys.executable`` interpreter (introduced in :pull:`3325`)
2+
- by :user:`hroncok`

src/tox/tox_env/python/api.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,14 @@ def extract_base_python(cls, env_name: str) -> str | None:
157157
return next(iter(candidates))
158158
return None
159159

160+
@classmethod
161+
def _python_spec_for_sys_executable(cls) -> PythonSpec:
162+
implementation = sys.implementation.name
163+
version = sys.version_info
164+
bits = "64" if sys.maxsize > 2**32 else "32"
165+
string_spec = f"{implementation}{version.major}{version.minor}-{bits}"
166+
return PythonSpec.from_string_spec(string_spec)
167+
160168
@classmethod
161169
def _validate_base_python(
162170
cls,
@@ -172,8 +180,7 @@ def _validate_base_python(
172180
if spec_base.path is not None:
173181
path = Path(spec_base.path).absolute()
174182
if str(spec_base.path) == sys.executable:
175-
ver, is_64 = sys.version_info, sys.maxsize != 2**32
176-
spec_base = PythonSpec.from_string_spec(f"{sys.implementation}{ver.major}{ver.minor}-{is_64}")
183+
spec_base = cls._python_spec_for_sys_executable()
177184
else:
178185
spec_base = cls.python_spec_for_path(path)
179186
if any(

tests/tox_env/python/test_python_api.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import sys
4+
from types import SimpleNamespace
45
from typing import TYPE_CHECKING, Callable
56
from unittest.mock import patch
67

@@ -289,3 +290,29 @@ def test_usedevelop_with_nonexistent_basepython(tox_project: ToxProjectCreator)
289290
project = tox_project({"tox.ini": ini})
290291
result = project.run()
291292
assert result.code == 0
293+
294+
295+
@pytest.mark.parametrize(
296+
("impl", "major", "minor", "arch"),
297+
[
298+
("cpython", 3, 12, 64),
299+
("pypy", 3, 9, 32),
300+
],
301+
)
302+
def test_python_spec_for_sys_executable(impl: str, major: int, minor: int, arch: int, mocker: MockerFixture) -> None:
303+
version_info = SimpleNamespace(major=major, minor=minor, micro=5, releaselevel="final", serial=0)
304+
implementation = SimpleNamespace(
305+
name=impl,
306+
cache_tag=f"{impl}-{major}{minor}",
307+
version=version_info,
308+
hexversion=...,
309+
_multiarch=...,
310+
)
311+
mocker.patch.object(sys, "version_info", version_info)
312+
mocker.patch.object(sys, "implementation", implementation)
313+
mocker.patch.object(sys, "maxsize", 2**arch // 2 - 1)
314+
spec = Python._python_spec_for_sys_executable() # noqa: SLF001
315+
assert spec.implementation == impl
316+
assert spec.major == major
317+
assert spec.minor == minor
318+
assert spec.architecture == arch

0 commit comments

Comments
 (0)