Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/poetry/console/commands/python/list.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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

Expand Down
6 changes: 4 additions & 2 deletions src/poetry/console/commands/python/remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -63,7 +63,9 @@ def remove_python_installation(request: str, implementation: str, io: IO) -> int
return 1

request_title = f"<c1>{request}</> (<b>{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():
Expand Down
5 changes: 3 additions & 2 deletions src/poetry/utils/env/python/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
22 changes: 20 additions & 2 deletions src/poetry/utils/env/python/providers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import contextlib
import dataclasses
import shutil
import sysconfig
Expand All @@ -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


Expand Down Expand Up @@ -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()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe, we have to pass the project directory to base_installation_dir() and call Factory.locate() with it. Otherwise, --project and --directory will not work. In Command classes, we can call self.get_application().project_directory. Then, we will probably have to pass it to all relevant methods.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch 👍 I forgot these command line arguments. Looks like it is not trivial to pass it to all relevant methods 🤔 I will have a closer look at it the next days.


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]:
Expand All @@ -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.)
Expand Down