From 93ef49fad85cddbb38da41d458dac247427030d6 Mon Sep 17 00:00:00 2001 From: Bartosz Sokorski Date: Thu, 18 Apr 2024 01:10:30 +0200 Subject: [PATCH] Move to native tags gathering (#9304) --- poetry.lock | 8 +++--- pyproject.toml | 2 +- src/poetry/utils/env/__init__.py | 4 --- src/poetry/utils/env/base_env.py | 17 +++++------ src/poetry/utils/env/script_strings.py | 40 ++------------------------ src/poetry/utils/env/virtual_env.py | 25 ++++++++++++---- tests/inspection/test_info.py | 2 +- 7 files changed, 37 insertions(+), 61 deletions(-) diff --git a/poetry.lock b/poetry.lock index a9e6ace852d..d0fe4a90d84 100644 --- a/poetry.lock +++ b/poetry.lock @@ -878,13 +878,13 @@ dev = ["black", "mypy", "pytest"] [[package]] name = "packaging" -version = "23.2" +version = "24.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, - {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] [[package]] @@ -1596,4 +1596,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "08e1102283e5a8d9a88aee8a081bb45cde8ca52731ea726053dd3cb84bb6d4c1" +content-hash = "e4cb3263453998e44156515f28d1d8c6030b956b2840264045bd57aff8033071" diff --git a/pyproject.toml b/pyproject.toml index ba9422df212..fbaebe74b4d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,7 @@ importlib-metadata = { version = ">=4.4", python = "<3.10" } installer = "^0.7.0" keyring = "^24.3.1" # packaging uses calver, so version is unclamped -packaging = ">=23.1" +packaging = ">=24.0" pexpect = "^4.7.0" pkginfo = "^1.10" platformdirs = ">=3.0.0,<5" diff --git a/src/poetry/utils/env/__init__.py b/src/poetry/utils/env/__init__.py index b460a545595..89882ddfd05 100644 --- a/src/poetry/utils/env/__init__.py +++ b/src/poetry/utils/env/__init__.py @@ -22,10 +22,8 @@ from poetry.utils.env.script_strings import GET_ENVIRONMENT_INFO from poetry.utils.env.script_strings import GET_PATHS from poetry.utils.env.script_strings import GET_PATHS_FOR_GENERIC_ENVS -from poetry.utils.env.script_strings import GET_PYTHON_VERSION from poetry.utils.env.script_strings import GET_PYTHON_VERSION_ONELINER from poetry.utils.env.script_strings import GET_SYS_PATH -from poetry.utils.env.script_strings import GET_SYS_TAGS from poetry.utils.env.site_packages import SitePackages from poetry.utils.env.system_env import SystemEnv from poetry.utils.env.virtual_env import VirtualEnv @@ -96,9 +94,7 @@ def build_environment( "GET_BASE_PREFIX", "GET_ENVIRONMENT_INFO", "GET_PATHS", - "GET_PYTHON_VERSION", "GET_SYS_PATH", - "GET_SYS_TAGS", "GET_ENV_PATH_ONELINER", "GET_PYTHON_VERSION_ONELINER", "GET_PATHS_FOR_GENERIC_ENVS", diff --git a/src/poetry/utils/env/base_env.py b/src/poetry/utils/env/base_env.py index 5ba945e5c62..f4e87d5a5fb 100644 --- a/src/poetry/utils/env/base_env.py +++ b/src/poetry/utils/env/base_env.py @@ -7,6 +7,7 @@ import sys import sysconfig +from functools import cached_property from pathlib import Path from subprocess import CalledProcessError from typing import TYPE_CHECKING @@ -20,12 +21,16 @@ if TYPE_CHECKING: + from typing import Tuple + from packaging.tags import Tag from poetry.core.version.markers import BaseMarker from virtualenv.seed.wheels.util import Wheel from poetry.utils.env.generic_env import GenericEnv + PythonVersion = Tuple[int, int, int, str, int] + class Env: """ @@ -52,7 +57,6 @@ def __init__(self, path: Path, base: Path | None = None) -> None: self._base = base or path - self._marker_env: dict[str, Any] | None = None self._site_packages: SitePackages | None = None self._paths: dict[str, str] | None = None self._supported_tags: list[Tag] | None = None @@ -71,8 +75,8 @@ def base(self) -> Path: return self._base @property - def version_info(self) -> tuple[int, int, int, str, int]: - version_info: tuple[int, int, int, str, int] = self.marker_env["version_info"] + def version_info(self) -> PythonVersion: + version_info: PythonVersion = self.marker_env["version_info"] return version_info @property @@ -87,12 +91,9 @@ def python(self) -> Path: """ return Path(self._bin(self._executable)) - @property + @cached_property def marker_env(self) -> dict[str, Any]: - if self._marker_env is None: - self._marker_env = self.get_marker_env() - - return self._marker_env + return self.get_marker_env() @property def parent_env(self) -> GenericEnv: diff --git a/src/poetry/utils/env/script_strings.py b/src/poetry/utils/env/script_strings.py index 3e663e3e0c6..dc33e00ba05 100644 --- a/src/poetry/utils/env/script_strings.py +++ b/src/poetry/utils/env/script_strings.py @@ -1,31 +1,5 @@ from __future__ import annotations -import packaging.tags - - -GET_SYS_TAGS = f""" -import importlib.util -import json -import sys - -from pathlib import Path - -spec = importlib.util.spec_from_file_location( - "packaging", Path(r"{packaging.__file__}") -) -packaging = importlib.util.module_from_spec(spec) -sys.modules[spec.name] = packaging - -spec = importlib.util.spec_from_file_location( - "packaging.tags", Path(r"{packaging.tags.__file__}") -) -packaging_tags = importlib.util.module_from_spec(spec) -spec.loader.exec_module(packaging_tags) - -print( - json.dumps([(t.interpreter, t.abi, t.platform) for t in packaging_tags.sys_tags()]) -) -""" GET_ENVIRONMENT_INFO = """\ import json @@ -54,12 +28,7 @@ def interpreter_version(): def _version_nodot(version): - if any(v >= 10 for v in version): - sep = "_" - else: - sep = "" - - return sep.join(map(str, version)) + return "".join(map(str, version)) if hasattr(sys, "implementation"): @@ -108,15 +77,10 @@ def _version_nodot(version): print(sys.prefix) """ -GET_PYTHON_VERSION = """\ -import sys - -print('.'.join([str(s) for s in sys.version_info[:3]])) -""" - GET_PYTHON_VERSION_ONELINER = ( "import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))" ) + GET_ENV_PATH_ONELINER = "import sys; print(sys.prefix)" GET_SYS_PATH = """\ diff --git a/src/poetry/utils/env/virtual_env.py b/src/poetry/utils/env/virtual_env.py index 747ba462227..9a8680aaefa 100644 --- a/src/poetry/utils/env/virtual_env.py +++ b/src/poetry/utils/env/virtual_env.py @@ -12,20 +12,19 @@ from typing import TYPE_CHECKING from typing import Any -from packaging.tags import Tag - from poetry.utils.env.base_env import Env from poetry.utils.env.script_strings import GET_BASE_PREFIX from poetry.utils.env.script_strings import GET_ENVIRONMENT_INFO from poetry.utils.env.script_strings import GET_PATHS from poetry.utils.env.script_strings import GET_SYS_PATH -from poetry.utils.env.script_strings import GET_SYS_TAGS from poetry.utils.env.system_env import SystemEnv if TYPE_CHECKING: from collections.abc import Iterator + from packaging.tags import Tag + class VirtualEnv(Env): """ @@ -50,9 +49,25 @@ def sys_path(self) -> list[str]: return paths def get_supported_tags(self) -> list[Tag]: - output = self.run_python_script(GET_SYS_TAGS) + from packaging.tags import compatible_tags + from packaging.tags import cpython_tags + from packaging.tags import generic_tags + + python = self.version_info[:3] + interpreter_name = self.marker_env["interpreter_name"] + interpreter_version = self.marker_env["interpreter_version"] + + if interpreter_name == "pp": + interpreter = "pp3" + elif interpreter_name == "cp": + interpreter = f"{interpreter_name}{interpreter_version}" + else: + interpreter = None - return [Tag(*t) for t in json.loads(output)] + return [ + *(cpython_tags(python) if interpreter_name == "cp" else generic_tags()), + *compatible_tags(python, interpreter=interpreter), + ] def get_marker_env(self) -> dict[str, Any]: output = self.run_python_script(GET_ENVIRONMENT_INFO) diff --git a/tests/inspection/test_info.py b/tests/inspection/test_info.py index 75a86f9e2b8..704eeba7a21 100644 --- a/tests/inspection/test_info.py +++ b/tests/inspection/test_info.py @@ -311,7 +311,7 @@ def test_info_no_setup_pkg_info_no_deps_dynamic(fixture_dir: FixtureDirGetter) - def test_info_setup_simple(mocker: MockerFixture, demo_setup: Path) -> None: spy = mocker.spy(VirtualEnv, "run") info = PackageInfo.from_directory(demo_setup) - assert spy.call_count == 5 + assert spy.call_count == 4 demo_check_info(info, requires_dist={"package"})