Skip to content

Commit

Permalink
Fixup the spec string for sys.executable (#3327)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
hroncok committed Aug 17, 2024
1 parent dde4964 commit 874e9af
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
2 changes: 2 additions & 0 deletions docs/changelog/3327.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix and test the string spec for the ``sys.executable`` interpreter (introduced in :pull:`3325`)
- by :user:`hroncok`
11 changes: 9 additions & 2 deletions src/tox/tox_env/python/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,14 @@ def extract_base_python(cls, env_name: str) -> str | None:
return next(iter(candidates))
return None

@classmethod
def _python_spec_for_sys_executable(cls) -> PythonSpec:
implementation = sys.implementation.name
version = sys.version_info
bits = "64" if sys.maxsize > 2**32 else "32"
string_spec = f"{implementation}{version.major}{version.minor}-{bits}"
return PythonSpec.from_string_spec(string_spec)

@classmethod
def _validate_base_python(
cls,
Expand All @@ -172,8 +180,7 @@ def _validate_base_python(
if spec_base.path is not None:
path = Path(spec_base.path).absolute()
if str(spec_base.path) == sys.executable:
ver, is_64 = sys.version_info, sys.maxsize != 2**32
spec_base = PythonSpec.from_string_spec(f"{sys.implementation}{ver.major}{ver.minor}-{is_64}")
spec_base = cls._python_spec_for_sys_executable()
else:
spec_base = cls.python_spec_for_path(path)
if any(
Expand Down
27 changes: 27 additions & 0 deletions tests/tox_env/python/test_python_api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import sys
from types import SimpleNamespace
from typing import TYPE_CHECKING, Callable
from unittest.mock import patch

Expand Down Expand Up @@ -289,3 +290,29 @@ def test_usedevelop_with_nonexistent_basepython(tox_project: ToxProjectCreator)
project = tox_project({"tox.ini": ini})
result = project.run()
assert result.code == 0


@pytest.mark.parametrize(
("impl", "major", "minor", "arch"),
[
("cpython", 3, 12, 64),
("pypy", 3, 9, 32),
],
)
def test_python_spec_for_sys_executable(impl: str, major: int, minor: int, arch: int, mocker: MockerFixture) -> None:
version_info = SimpleNamespace(major=major, minor=minor, micro=5, releaselevel="final", serial=0)
implementation = SimpleNamespace(
name=impl,
cache_tag=f"{impl}-{major}{minor}",
version=version_info,
hexversion=...,
_multiarch=...,
)
mocker.patch.object(sys, "version_info", version_info)
mocker.patch.object(sys, "implementation", implementation)
mocker.patch.object(sys, "maxsize", 2**arch // 2 - 1)
spec = Python._python_spec_for_sys_executable() # noqa: SLF001
assert spec.implementation == impl
assert spec.major == major
assert spec.minor == minor
assert spec.architecture == arch

0 comments on commit 874e9af

Please sign in to comment.