diff --git a/src/poetry/console/commands/python/list.py b/src/poetry/console/commands/python/list.py index 4c628f3ab9c..6cac677e5e1 100644 --- a/src/poetry/console/commands/python/list.py +++ b/src/poetry/console/commands/python/list.py @@ -8,9 +8,9 @@ from poetry.core.constraints.version import parse_constraint from poetry.core.version.exceptions import InvalidVersionError -from poetry.config.config import Config from poetry.console.commands.command import Command from poetry.utils.env.python import Python +from poetry.utils.env.python.providers import PoetryPythonPathProvider if TYPE_CHECKING: @@ -84,7 +84,7 @@ def handle(self) -> int: ) implementations = {"cpython": "CPython", "pypy": "PyPy"} - python_installation_path = Config.create().python_installation_dir + python_installation_path = PoetryPythonPathProvider.base_installation_dir() row_count = 0 diff --git a/src/poetry/console/commands/python/remove.py b/src/poetry/console/commands/python/remove.py index 2f17628da28..5a2dfb910d8 100644 --- a/src/poetry/console/commands/python/remove.py +++ b/src/poetry/console/commands/python/remove.py @@ -10,8 +10,8 @@ from poetry.core.constraints.version.version import Version from poetry.core.version.exceptions import InvalidVersionError -from poetry.config.config import Config from poetry.console.commands.command import Command +from poetry.utils.env.python.providers import PoetryPythonPathProvider if TYPE_CHECKING: @@ -63,7 +63,9 @@ def remove_python_installation(request: str, implementation: str, io: IO) -> int return 1 request_title = f"{request} ({implementation})" - path = Config.create().python_installation_dir / f"{implementation}@{version}" + path = PoetryPythonPathProvider.installation_dir( + version=version, implementation=implementation + ) if path.exists(): if io.is_verbose(): diff --git a/src/poetry/utils/env/python/installer.py b/src/poetry/utils/env/python/installer.py index ebbb61911de..8c2178c138a 100644 --- a/src/poetry/utils/env/python/installer.py +++ b/src/poetry/utils/env/python/installer.py @@ -10,10 +10,10 @@ from poetry.core.constraints.version import Version -from poetry.config.config import Config from poetry.console.exceptions import ConsoleMessage from poetry.console.exceptions import PoetryRuntimeError from poetry.utils.env.python import Python +from poetry.utils.env.python.providers import PoetryPythonPathProvider if TYPE_CHECKING: @@ -46,7 +46,8 @@ class PythonInstaller: implementation: Literal["cpython", "pypy"] = dataclasses.field(default="cpython") free_threaded: bool = dataclasses.field(default=False) installation_directory: Path = dataclasses.field( - init=False, default_factory=lambda: Config.create().python_installation_dir + init=False, + default_factory=lambda: PoetryPythonPathProvider.base_installation_dir(), ) @property diff --git a/src/poetry/utils/env/python/providers.py b/src/poetry/utils/env/python/providers.py index d39d5e6500f..9e650edad8b 100644 --- a/src/poetry/utils/env/python/providers.py +++ b/src/poetry/utils/env/python/providers.py @@ -1,5 +1,6 @@ from __future__ import annotations +import contextlib import dataclasses import shutil import sysconfig @@ -12,6 +13,7 @@ from findpython.providers.path import PathProvider from poetry.config.config import Config +from poetry.toml import TOMLFile from poetry.utils._compat import WINDOWS @@ -41,9 +43,25 @@ def find_python_by_name(cls, name: str) -> findpython.PythonVersion | None: @dataclasses.dataclass class PoetryPythonPathProvider(PathProvider): # type: ignore[misc] + @classmethod + def base_installation_dir(cls) -> Path: + from poetry.factory import Factory + + config = Config.create() + + # Let's check if there is a local config file. + with contextlib.suppress(RuntimeError): + pyproject = Factory.locate() + + local_config_file = TOMLFile(pyproject.parent / "poetry.toml") + if local_config_file.exists(): + config.merge(local_config_file.read()) + + return config.python_installation_dir + @classmethod def installation_dir(cls, version: Version, implementation: str) -> Path: - return Config.create().python_installation_dir / f"{implementation}@{version}" + return cls.base_installation_dir() / f"{implementation}@{version}" @classmethod def _make_bin_paths(cls, base: Path | None = None) -> list[Path]: @@ -55,7 +73,7 @@ def _make_bin_paths(cls, base: Path | None = None) -> list[Path]: # If both versions exist, the first one is preferred. # However, sometimes (especially for free-threaded Python), # only the second version exists! - install_dir = base or Config.create().python_installation_dir + install_dir = base or cls.base_installation_dir() if WINDOWS and not sysconfig.get_platform().startswith("mingw"): # On Windows Python executables are top level. # (Only in virtualenvs, they are in the Scripts directory.)