Commit b9334439 by David Hotham Committed by GitHub

Misc tidying (#7673)

* correct logger for publisher
* build 0.10.0 to get metadata in PackageInfo
* prefer pathlib
* passwords must be strings
parent 7687539d
...@@ -211,6 +211,7 @@ To remove a repository (repo is a short alias for repositories): ...@@ -211,6 +211,7 @@ To remove a repository (repo is a short alias for repositories):
username = values[0] username = values[0]
# Only username, so we prompt for password # Only username, so we prompt for password
password = self.secret("Password:") password = self.secret("Password:")
assert isinstance(password, str)
elif len(values) != 2: elif len(values) != 2:
raise ValueError( raise ValueError(
"Expected one or two arguments " "Expected one or two arguments "
......
...@@ -44,7 +44,7 @@ The --repository option should match the name of a configured repository using ...@@ -44,7 +44,7 @@ The --repository option should match the name of a configured repository using
the config command. the config command.
""" """
loggers = ["poetry.masonry.publishing.publisher"] loggers = ["poetry.publishing.publisher"]
def handle(self) -> int: def handle(self) -> int:
from poetry.publishing.publisher import Publisher from poetry.publishing.publisher import Publisher
......
...@@ -58,11 +58,11 @@ with build.env.IsolatedEnvBuilder() as env: ...@@ -58,11 +58,11 @@ with build.env.IsolatedEnvBuilder() as env:
builder.metadata_path(dest) builder.metadata_path(dest)
""" """
PEP517_META_BUILD_DEPS = ["build==0.9.0", "pyproject_hooks==1.0.0"] PEP517_META_BUILD_DEPS = ["build==0.10.0", "pyproject_hooks==1.0.0"]
class PackageInfoError(ValueError): class PackageInfoError(ValueError):
def __init__(self, path: Path | str, *reasons: BaseException | str) -> None: def __init__(self, path: Path, *reasons: BaseException | str) -> None:
reasons = (f"Unable to determine package info for path: {path!s}",) + reasons reasons = (f"Unable to determine package info for path: {path!s}",) + reasons
super().__init__("\n\n".join(str(msg).strip() for msg in reasons if msg)) super().__init__("\n\n".join(str(msg).strip() for msg in reasons if msg))
...@@ -617,7 +617,7 @@ def get_pep517_metadata(path: Path) -> PackageInfo: ...@@ -617,7 +617,7 @@ def get_pep517_metadata(path: Path) -> PackageInfo:
) )
cwd = Path.cwd() cwd = Path.cwd()
os.chdir(path.as_posix()) os.chdir(path)
try: try:
venv.run("python", "setup.py", "egg_info") venv.run("python", "setup.py", "egg_info")
info = PackageInfo.from_metadata(path) info = PackageInfo.from_metadata(path)
...@@ -626,7 +626,7 @@ def get_pep517_metadata(path: Path) -> PackageInfo: ...@@ -626,7 +626,7 @@ def get_pep517_metadata(path: Path) -> PackageInfo:
path, "Fallback egg_info generation failed.", fbe path, "Fallback egg_info generation failed.", fbe
) )
finally: finally:
os.chdir(cwd.as_posix()) os.chdir(cwd)
if info: if info:
logger.debug("Falling back to parsed setup.py file for %s", path) logger.debug("Falling back to parsed setup.py file for %s", path)
......
...@@ -650,7 +650,7 @@ class Executor: ...@@ -650,7 +650,7 @@ class Executor:
if package.source_subdirectory: if package.source_subdirectory:
req /= package.source_subdirectory req /= package.source_subdirectory
pyproject = PyProjectTOML(os.path.join(req, "pyproject.toml")) pyproject = PyProjectTOML(req / "pyproject.toml")
package_poetry = None package_poetry = None
if pyproject.is_poetry_project(): if pyproject.is_poetry_project():
......
...@@ -221,7 +221,7 @@ class PipInstaller(BaseInstaller): ...@@ -221,7 +221,7 @@ class PipInstaller(BaseInstaller):
if package.source_subdirectory: if package.source_subdirectory:
req /= package.source_subdirectory req /= package.source_subdirectory
pyproject = PyProjectTOML(os.path.join(req, "pyproject.toml")) pyproject = PyProjectTOML(req / "pyproject.toml")
package_poetry = None package_poetry = None
if pyproject.is_poetry_project(): if pyproject.is_poetry_project():
......
...@@ -31,7 +31,7 @@ class WheelDestination(SchemeDictionaryDestination): ...@@ -31,7 +31,7 @@ class WheelDestination(SchemeDictionaryDestination):
def write_to_fs( def write_to_fs(
self, self,
scheme: Scheme, scheme: Scheme,
path: Path | str, path: str,
stream: BinaryIO, stream: BinaryIO,
is_executable: bool, is_executable: bool,
) -> RecordEntry: ) -> RecordEntry:
...@@ -58,7 +58,7 @@ class WheelDestination(SchemeDictionaryDestination): ...@@ -58,7 +58,7 @@ class WheelDestination(SchemeDictionaryDestination):
if is_executable: if is_executable:
make_file_executable(target_path) make_file_executable(target_path)
return RecordEntry(str(path), Hash(self.hash_algorithm, hash_), size) return RecordEntry(path, Hash(self.hash_algorithm, hash_), size)
def for_source(self, source: WheelFile) -> WheelDestination: def for_source(self, source: WheelFile) -> WheelDestination:
scheme_dict = self.scheme_dict.copy() scheme_dict = self.scheme_dict.copy()
...@@ -90,7 +90,7 @@ class WheelInstaller: ...@@ -90,7 +90,7 @@ class WheelInstaller:
schemes["headers"] = schemes["include"] schemes["headers"] = schemes["include"]
self._destination = WheelDestination( self._destination = WheelDestination(
schemes, interpreter=self._env.python, script_kind=script_kind schemes, interpreter=str(self._env.python), script_kind=script_kind
) )
def enable_bytecode_compilation(self, enable: bool = True) -> None: def enable_bytecode_compilation(self, enable: bool = True) -> None:
......
...@@ -53,8 +53,8 @@ class Locker: ...@@ -53,8 +53,8 @@ class Locker:
_legacy_keys = ["dependencies", "source", "extras", "dev-dependencies"] _legacy_keys = ["dependencies", "source", "extras", "dev-dependencies"]
_relevant_keys = [*_legacy_keys, "group"] _relevant_keys = [*_legacy_keys, "group"]
def __init__(self, lock: str | Path, local_config: dict[str, Any]) -> None: def __init__(self, lock: Path, local_config: dict[str, Any]) -> None:
self._lock = lock if isinstance(lock, Path) else Path(lock) self._lock = lock
self._local_config = local_config self._local_config = local_config
self._lock_data: dict[str, Any] | None = None self._lock_data: dict[str, Any] | None = None
self._content_hash = self._get_content_hash() self._content_hash = self._get_content_hash()
......
...@@ -290,9 +290,8 @@ class ArtifactCache: ...@@ -290,9 +290,8 @@ class ArtifactCache:
cache_dir = self.get_cache_directory_for_link(link) cache_dir = self.get_cache_directory_for_link(link)
archive_types = ["whl", "tar.gz", "tar.bz2", "bz2", "zip"] archive_types = ["whl", "tar.gz", "tar.bz2", "bz2", "zip"]
paths = [] paths: list[Path] = []
for archive_type in archive_types: for archive_type in archive_types:
for archive in cache_dir.glob(f"*.{archive_type}"): paths += cache_dir.glob(f"*.{archive_type}")
paths.append(Path(archive))
return paths return paths
...@@ -380,7 +380,7 @@ class SitePackages: ...@@ -380,7 +380,7 @@ class SitePackages:
distribution_path: Path = distribution._path # type: ignore[attr-defined] distribution_path: Path = distribution._path # type: ignore[attr-defined]
if distribution_path.exists(): if distribution_path.exists():
remove_directory(str(distribution_path), force=True) remove_directory(distribution_path, force=True)
paths.append(distribution_path) paths.append(distribution_path)
...@@ -388,16 +388,13 @@ class SitePackages: ...@@ -388,16 +388,13 @@ class SitePackages:
def _path_method_wrapper( def _path_method_wrapper(
self, self,
path: str | Path, path: Path,
method: str, method: str,
*args: Any, *args: Any,
return_first: bool = True, return_first: bool = True,
writable_only: bool = False, writable_only: bool = False,
**kwargs: Any, **kwargs: Any,
) -> tuple[Path, Any] | list[tuple[Path, Any]]: ) -> tuple[Path, Any] | list[tuple[Path, Any]]:
if isinstance(path, str):
path = Path(path)
candidates = self.make_candidates( candidates = self.make_candidates(
path, writable_only=writable_only, strict=True path, writable_only=writable_only, strict=True
) )
...@@ -419,17 +416,17 @@ class SitePackages: ...@@ -419,17 +416,17 @@ class SitePackages:
raise OSError(f"Unable to access any of {paths_csv(candidates)}") raise OSError(f"Unable to access any of {paths_csv(candidates)}")
def write_text(self, path: str | Path, *args: Any, **kwargs: Any) -> Path: def write_text(self, path: Path, *args: Any, **kwargs: Any) -> Path:
paths = self._path_method_wrapper(path, "write_text", *args, **kwargs) paths = self._path_method_wrapper(path, "write_text", *args, **kwargs)
assert isinstance(paths, tuple) assert isinstance(paths, tuple)
return paths[0] return paths[0]
def mkdir(self, path: str | Path, *args: Any, **kwargs: Any) -> Path: def mkdir(self, path: Path, *args: Any, **kwargs: Any) -> Path:
paths = self._path_method_wrapper(path, "mkdir", *args, **kwargs) paths = self._path_method_wrapper(path, "mkdir", *args, **kwargs)
assert isinstance(paths, tuple) assert isinstance(paths, tuple)
return paths[0] return paths[0]
def exists(self, path: str | Path) -> bool: def exists(self, path: Path) -> bool:
return any( return any(
value[-1] value[-1]
for value in self._path_method_wrapper(path, "exists", return_first=False) for value in self._path_method_wrapper(path, "exists", return_first=False)
...@@ -437,7 +434,7 @@ class SitePackages: ...@@ -437,7 +434,7 @@ class SitePackages:
def find( def find(
self, self,
path: str | Path, path: Path,
writable_only: bool = False, writable_only: bool = False,
) -> list[Path]: ) -> list[Path]:
return [ return [
...@@ -520,7 +517,7 @@ class EnvManager: ...@@ -520,7 +517,7 @@ class EnvManager:
self._io = io or NullIO() self._io = io or NullIO()
@staticmethod @staticmethod
def _full_python_path(python: str) -> str: def _full_python_path(python: str) -> Path:
try: try:
executable = decode( executable = decode(
subprocess.check_output( subprocess.check_output(
...@@ -530,10 +527,10 @@ class EnvManager: ...@@ -530,10 +527,10 @@ class EnvManager:
except CalledProcessError as e: except CalledProcessError as e:
raise EnvCommandError(e) raise EnvCommandError(e)
return executable return Path(executable)
@staticmethod @staticmethod
def _detect_active_python(io: None | IO = None) -> str | None: def _detect_active_python(io: None | IO = None) -> Path | None:
io = io or NullIO() io = io or NullIO()
executable = None executable = None
...@@ -594,12 +591,12 @@ class EnvManager: ...@@ -594,12 +591,12 @@ class EnvManager:
# Executable in PATH or full executable path # Executable in PATH or full executable path
pass pass
python = self._full_python_path(python) python_path = self._full_python_path(python)
try: try:
python_version_string = decode( python_version_string = decode(
subprocess.check_output( subprocess.check_output(
[python, "-c", GET_PYTHON_VERSION_ONELINER], [python_path, "-c", GET_PYTHON_VERSION_ONELINER],
) )
) )
except CalledProcessError as e: except CalledProcessError as e:
...@@ -624,7 +621,7 @@ class EnvManager: ...@@ -624,7 +621,7 @@ class EnvManager:
if patch != current_patch: if patch != current_patch:
create = True create = True
self.create_venv(executable=python, force=create) self.create_venv(executable=python_path, force=create)
return self.get(reload=True) return self.get(reload=True)
...@@ -658,7 +655,7 @@ class EnvManager: ...@@ -658,7 +655,7 @@ class EnvManager:
if patch != current_patch: if patch != current_patch:
create = True create = True
self.create_venv(executable=python, force=create) self.create_venv(executable=python_path, force=create)
# Activate # Activate
envs[base_env_name] = {"minor": minor, "patch": patch} envs[base_env_name] = {"minor": minor, "patch": patch}
...@@ -759,9 +756,7 @@ class EnvManager: ...@@ -759,9 +756,7 @@ class EnvManager:
venv_name = self.generate_env_name(name, str(self._poetry.file.parent)) venv_name = self.generate_env_name(name, str(self._poetry.file.parent))
venv_path = self._poetry.config.virtualenvs_path venv_path = self._poetry.config.virtualenvs_path
env_list = [ env_list = [VirtualEnv(p) for p in sorted(venv_path.glob(f"{venv_name}-py*"))]
VirtualEnv(Path(p)) for p in sorted(venv_path.glob(f"{venv_name}-py*"))
]
venv = self._poetry.file.parent / ".venv" venv = self._poetry.file.parent / ".venv"
if ( if (
...@@ -837,7 +832,7 @@ class EnvManager: ...@@ -837,7 +832,7 @@ class EnvManager:
else: else:
venv_path = self._poetry.config.virtualenvs_path venv_path = self._poetry.config.virtualenvs_path
# Get all the poetry envs, even for other projects # Get all the poetry envs, even for other projects
env_names = [Path(p).name for p in sorted(venv_path.glob("*-*-py*"))] env_names = [p.name for p in sorted(venv_path.glob("*-*-py*"))]
if python in env_names: if python in env_names:
raise IncorrectEnvError(python) raise IncorrectEnvError(python)
...@@ -885,7 +880,7 @@ class EnvManager: ...@@ -885,7 +880,7 @@ class EnvManager:
def create_venv( def create_venv(
self, self,
name: str | None = None, name: str | None = None,
executable: str | None = None, executable: Path | None = None,
force: bool = False, force: bool = False,
) -> Env: ) -> Env:
if self._env is not None and not force: if self._env is not None and not force:
...@@ -918,7 +913,9 @@ class EnvManager: ...@@ -918,7 +913,9 @@ class EnvManager:
if not executable and prefer_active_python: if not executable and prefer_active_python:
executable = self._detect_active_python() executable = self._detect_active_python()
venv_path = cwd / ".venv" if root_venv else self._poetry.config.virtualenvs_path venv_path: Path = (
cwd / ".venv" if root_venv else self._poetry.config.virtualenvs_path
)
if not name: if not name:
name = self._poetry.package.name name = self._poetry.package.name
assert name is not None assert name is not None
...@@ -1071,8 +1068,8 @@ class EnvManager: ...@@ -1071,8 +1068,8 @@ class EnvManager:
@classmethod @classmethod
def build_venv( def build_venv(
cls, cls,
path: Path | str, path: Path,
executable: str | Path | None = None, executable: Path | None = None,
flags: dict[str, bool] | None = None, flags: dict[str, bool] | None = None,
with_pip: bool | None = None, with_pip: bool | None = None,
with_wheel: bool | None = None, with_wheel: bool | None = None,
...@@ -1103,14 +1100,13 @@ class EnvManager: ...@@ -1103,14 +1100,13 @@ class EnvManager:
else flags.pop("no-wheel", flags["no-pip"]) else flags.pop("no-wheel", flags["no-pip"])
) )
if isinstance(executable, Path): executable_str = None if executable is None else executable.resolve().as_posix()
executable = executable.resolve().as_posix()
args = [ args = [
"--no-download", "--no-download",
"--no-periodic-update", "--no-periodic-update",
"--python", "--python",
executable or sys.executable, executable_str or sys.executable,
] ]
if prompt is not None: if prompt is not None:
...@@ -1138,9 +1134,7 @@ class EnvManager: ...@@ -1138,9 +1134,7 @@ class EnvManager:
return cli_result return cli_result
@classmethod @classmethod
def remove_venv(cls, path: Path | str) -> None: def remove_venv(cls, path: Path) -> None:
if isinstance(path, str):
path = Path(path)
assert path.is_dir() assert path.is_dir()
try: try:
remove_directory(path) remove_directory(path)
...@@ -1251,7 +1245,7 @@ class Env: ...@@ -1251,7 +1245,7 @@ class Env:
self._platlib: Path | None = None self._platlib: Path | None = None
self._script_dirs: list[Path] | None = None self._script_dirs: list[Path] | None = None
self._embedded_pip_path: str | None = None self._embedded_pip_path: Path | None = None
@property @property
def path(self) -> Path: def path(self) -> Path:
...@@ -1271,7 +1265,7 @@ class Env: ...@@ -1271,7 +1265,7 @@ class Env:
return implementation return implementation
@property @property
def python(self) -> str: def python(self) -> Path:
""" """
Path to current python executable Path to current python executable
""" """
...@@ -1331,21 +1325,21 @@ class Env: ...@@ -1331,21 +1325,21 @@ class Env:
return path return path
@property @property
def pip_embedded(self) -> str: def pip_embedded(self) -> Path:
if self._embedded_pip_path is None: if self._embedded_pip_path is None:
self._embedded_pip_path = str(self.get_embedded_wheel("pip") / "pip") self._embedded_pip_path = self.get_embedded_wheel("pip") / "pip"
return self._embedded_pip_path return self._embedded_pip_path
@property @property
def pip(self) -> str: def pip(self) -> Path:
""" """
Path to current pip executable Path to current pip executable
""" """
# we do not use as_posix() here due to issues with windows pathlib2 # we do not use as_posix() here due to issues with windows pathlib2
# implementation # implementation
path = self._bin(self._pip_executable) path = self._bin(self._pip_executable)
if not Path(path).exists(): if not path.exists():
return str(self.pip_embedded) return self.pip_embedded
return path return path
@property @property
...@@ -1463,10 +1457,10 @@ class Env: ...@@ -1463,10 +1457,10 @@ class Env:
raise NotImplementedError() raise NotImplementedError()
def get_pip_command(self, embedded: bool = False) -> list[str]: def get_pip_command(self, embedded: bool = False) -> list[str]:
if embedded or not Path(self._bin(self._pip_executable)).exists(): if embedded or not self._bin(self._pip_executable).exists():
return [self.python, self.pip_embedded] return [str(self.python), str(self.pip_embedded)]
# run as module so that pip can update itself on Windows # run as module so that pip can update itself on Windows
return [self.python, "-m", "pip"] return [str(self.python), "-m", "pip"]
def get_supported_tags(self) -> list[Tag]: def get_supported_tags(self) -> list[Tag]:
raise NotImplementedError() raise NotImplementedError()
...@@ -1493,7 +1487,7 @@ class Env: ...@@ -1493,7 +1487,7 @@ class Env:
# embedded pip when pip is not available in the environment # embedded pip when pip is not available in the environment
return self.get_pip_command() return self.get_pip_command()
return [self._bin(bin)] return [str(self._bin(bin))]
def run(self, bin: str, *args: str, **kwargs: Any) -> str | int: def run(self, bin: str, *args: str, **kwargs: Any) -> str | int:
cmd = self.get_command_from_bin(bin) + list(args) cmd = self.get_command_from_bin(bin) + list(args)
...@@ -1572,7 +1566,7 @@ class Env: ...@@ -1572,7 +1566,7 @@ class Env:
self._script_dirs.append(self.userbase / self._script_dirs[0].name) self._script_dirs.append(self.userbase / self._script_dirs[0].name)
return self._script_dirs return self._script_dirs
def _bin(self, bin: str) -> str: def _bin(self, bin: str) -> Path:
""" """
Return path to the given executable. Return path to the given executable.
""" """
...@@ -1593,11 +1587,11 @@ class Env: ...@@ -1593,11 +1587,11 @@ class Env:
bin_path = self._path / bin bin_path = self._path / bin
if bin_path.exists(): if bin_path.exists():
return str(bin_path) return bin_path
return bin return Path(bin)
return str(bin_path) return bin_path
def __eq__(self, other: object) -> bool: def __eq__(self, other: object) -> bool:
if not isinstance(other, Env): if not isinstance(other, Env):
...@@ -1615,8 +1609,8 @@ class SystemEnv(Env): ...@@ -1615,8 +1609,8 @@ class SystemEnv(Env):
""" """
@property @property
def python(self) -> str: def python(self) -> Path:
return sys.executable return Path(sys.executable)
@property @property
def sys_path(self) -> list[str]: def sys_path(self) -> list[str]:
...@@ -1942,20 +1936,20 @@ class NullEnv(SystemEnv): ...@@ -1942,20 +1936,20 @@ class NullEnv(SystemEnv):
return super().execute(bin, *args, **kwargs) return super().execute(bin, *args, **kwargs)
return 0 return 0
def _bin(self, bin: str) -> str: def _bin(self, bin: str) -> Path:
return bin return Path(bin)
@contextmanager @contextmanager
def ephemeral_environment( def ephemeral_environment(
executable: str | Path | None = None, executable: Path | None = None,
flags: dict[str, bool] | None = None, flags: dict[str, bool] | None = None,
) -> Iterator[VirtualEnv]: ) -> Iterator[VirtualEnv]:
with temporary_directory() as tmp_dir: with temporary_directory() as tmp_dir:
# TODO: cache PEP 517 build environment corresponding to each project venv # TODO: cache PEP 517 build environment corresponding to each project venv
venv_dir = Path(tmp_dir) / ".venv" venv_dir = Path(tmp_dir) / ".venv"
EnvManager.build_venv( EnvManager.build_venv(
path=venv_dir.as_posix(), path=venv_dir,
executable=executable, executable=executable,
flags=flags, flags=flags,
) )
......
...@@ -65,7 +65,7 @@ def _on_rm_error(func: Callable[[str], None], path: str, exc_info: Exception) -> ...@@ -65,7 +65,7 @@ def _on_rm_error(func: Callable[[str], None], path: str, exc_info: Exception) ->
def remove_directory( def remove_directory(
path: Path | str, *args: Any, force: bool = False, **kwargs: Any path: Path, *args: Any, force: bool = False, **kwargs: Any
) -> None: ) -> None:
""" """
Helper function handle safe removal, and optionally forces stubborn file removal. Helper function handle safe removal, and optionally forces stubborn file removal.
...@@ -74,8 +74,8 @@ def remove_directory( ...@@ -74,8 +74,8 @@ def remove_directory(
Internally, all arguments are passed to `shutil.rmtree`. Internally, all arguments are passed to `shutil.rmtree`.
""" """
if Path(path).is_symlink(): if path.is_symlink():
return os.unlink(str(path)) return os.unlink(path)
kwargs["onerror"] = kwargs.pop("onerror", _on_rm_error if force else None) kwargs["onerror"] = kwargs.pop("onerror", _on_rm_error if force else None)
shutil.rmtree(path, *args, **kwargs) shutil.rmtree(path, *args, **kwargs)
...@@ -239,7 +239,7 @@ def get_win_folder(csidl_name: str) -> Path: ...@@ -239,7 +239,7 @@ def get_win_folder(csidl_name: str) -> Path:
raise RuntimeError("Method can only be called on Windows.") raise RuntimeError("Method can only be called on Windows.")
def get_real_windows_path(path: str | Path) -> Path: def get_real_windows_path(path: Path) -> Path:
program_files = get_win_folder("CSIDL_PROGRAM_FILES") program_files = get_win_folder("CSIDL_PROGRAM_FILES")
local_appdata = get_win_folder("CSIDL_LOCAL_APPDATA") local_appdata = get_win_folder("CSIDL_LOCAL_APPDATA")
......
...@@ -3,12 +3,16 @@ from __future__ import annotations ...@@ -3,12 +3,16 @@ from __future__ import annotations
import ast import ast
from configparser import ConfigParser from configparser import ConfigParser
from pathlib import Path from typing import TYPE_CHECKING
from typing import Any from typing import Any
from poetry.core.constraints.version import Version from poetry.core.constraints.version import Version
if TYPE_CHECKING:
from pathlib import Path
class SetupReader: class SetupReader:
""" """
Class that reads a setup.py file without executing it. Class that reads a setup.py file without executing it.
...@@ -25,10 +29,7 @@ class SetupReader: ...@@ -25,10 +29,7 @@ class SetupReader:
FILES = ["setup.py", "setup.cfg"] FILES = ["setup.py", "setup.cfg"]
@classmethod @classmethod
def read_from_directory(cls, directory: str | Path) -> dict[str, Any]: def read_from_directory(cls, directory: Path) -> dict[str, Any]:
if isinstance(directory, str):
directory = Path(directory)
result = cls.DEFAULT.copy() result = cls.DEFAULT.copy()
for filename in cls.FILES: for filename in cls.FILES:
filepath = directory / filename filepath = directory / filename
...@@ -44,10 +45,7 @@ class SetupReader: ...@@ -44,10 +45,7 @@ class SetupReader:
return result return result
def read_setup_py(self, filepath: str | Path) -> dict[str, Any]: def read_setup_py(self, filepath: Path) -> dict[str, Any]:
if isinstance(filepath, str):
filepath = Path(filepath)
with filepath.open(encoding="utf-8") as f: with filepath.open(encoding="utf-8") as f:
content = f.read() content = f.read()
...@@ -71,7 +69,7 @@ class SetupReader: ...@@ -71,7 +69,7 @@ class SetupReader:
return result return result
def read_setup_cfg(self, filepath: str | Path) -> dict[str, Any]: def read_setup_cfg(self, filepath: Path) -> dict[str, Any]:
parser = ConfigParser() parser = ConfigParser()
parser.read(str(filepath)) parser.read(str(filepath))
......
...@@ -137,11 +137,11 @@ class GitRefSpec: ...@@ -137,11 +137,11 @@ class GitRefSpec:
@dataclasses.dataclass @dataclasses.dataclass
class GitRepoLocalInfo: class GitRepoLocalInfo:
repo: dataclasses.InitVar[Repo | Path | str] repo: dataclasses.InitVar[Repo | Path]
origin: str = dataclasses.field(init=False) origin: str = dataclasses.field(init=False)
revision: str = dataclasses.field(init=False) revision: str = dataclasses.field(init=False)
def __post_init__(self, repo: Repo | Path | str) -> None: def __post_init__(self, repo: Repo | Path) -> None:
repo = Git.as_repo(repo=repo) if not isinstance(repo, Repo) else repo repo = Git.as_repo(repo=repo) if not isinstance(repo, Repo) else repo
self.origin = Git.get_remote_url(repo=repo, remote="origin") self.origin = Git.get_remote_url(repo=repo, remote="origin")
self.revision = Git.get_revision(repo=repo) self.revision = Git.get_revision(repo=repo)
...@@ -149,7 +149,7 @@ class GitRepoLocalInfo: ...@@ -149,7 +149,7 @@ class GitRepoLocalInfo:
class Git: class Git:
@staticmethod @staticmethod
def as_repo(repo: Path | str) -> Repo: def as_repo(repo: Path) -> Repo:
return Repo(str(repo)) return Repo(str(repo))
@staticmethod @staticmethod
...@@ -171,7 +171,7 @@ class Git: ...@@ -171,7 +171,7 @@ class Git:
return repo.head().decode("utf-8") return repo.head().decode("utf-8")
@classmethod @classmethod
def info(cls, repo: Repo | Path | str) -> GitRepoLocalInfo: def info(cls, repo: Repo | Path) -> GitRepoLocalInfo:
return GitRepoLocalInfo(repo=repo) return GitRepoLocalInfo(repo=repo)
@staticmethod @staticmethod
...@@ -302,7 +302,7 @@ class Git: ...@@ -302,7 +302,7 @@ class Git:
), ),
local.path, local.path,
) )
remove_directory(local.path, force=True) remove_directory(Path(local.path), force=True)
if isinstance(e, AssertionError) and "Invalid object name" not in str(e): if isinstance(e, AssertionError) and "Invalid object name" not in str(e):
raise raise
......
...@@ -295,10 +295,11 @@ def fixture_dir(fixture_base: Path) -> FixtureDirGetter: ...@@ -295,10 +295,11 @@ def fixture_dir(fixture_base: Path) -> FixtureDirGetter:
@pytest.fixture @pytest.fixture
def tmp_dir() -> Iterator[str]: def tmp_dir() -> Iterator[str]:
dir_ = tempfile.mkdtemp(prefix="poetry_") dir_ = tempfile.mkdtemp(prefix="poetry_")
path = Path(dir_)
yield Path(dir_).resolve().as_posix() yield path.resolve().as_posix()
remove_directory(dir_, force=True) remove_directory(path, force=True)
@pytest.fixture @pytest.fixture
......
...@@ -55,7 +55,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file( ...@@ -55,7 +55,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
venv_cache: Path, venv_cache: Path,
venv_name: str, venv_name: str,
venvs_in_cache_config: None, venvs_in_cache_config: None,
): ) -> None:
mocker.patch( mocker.patch(
"subprocess.check_output", "subprocess.check_output",
side_effect=check_output_wrapper(), side_effect=check_output_wrapper(),
...@@ -70,7 +70,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file( ...@@ -70,7 +70,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
venv_py37 = venv_cache / f"{venv_name}-py3.7" venv_py37 = venv_cache / f"{venv_name}-py3.7"
mock_build_env.assert_called_with( mock_build_env.assert_called_with(
venv_py37, venv_py37,
executable="/usr/bin/python3.7", executable=Path("/usr/bin/python3.7"),
flags={ flags={
"always-copy": False, "always-copy": False,
"system-site-packages": False, "system-site-packages": False,
...@@ -99,7 +99,7 @@ def test_get_prefers_explicitly_activated_virtualenvs_over_env_var( ...@@ -99,7 +99,7 @@ def test_get_prefers_explicitly_activated_virtualenvs_over_env_var(
venv_cache: Path, venv_cache: Path,
venv_name: str, venv_name: str,
venvs_in_cache_config: None, venvs_in_cache_config: None,
): ) -> None:
os.environ["VIRTUAL_ENV"] = "/environment/prefix" os.environ["VIRTUAL_ENV"] = "/environment/prefix"
python_minor = ".".join(str(v) for v in current_python[:2]) python_minor = ".".join(str(v) for v in current_python[:2])
...@@ -128,7 +128,7 @@ def test_get_prefers_explicitly_activated_non_existing_virtualenvs_over_env_var( ...@@ -128,7 +128,7 @@ def test_get_prefers_explicitly_activated_non_existing_virtualenvs_over_env_var(
venv_cache: Path, venv_cache: Path,
venv_name: str, venv_name: str,
venvs_in_cache_config: None, venvs_in_cache_config: None,
): ) -> None:
os.environ["VIRTUAL_ENV"] = "/environment/prefix" os.environ["VIRTUAL_ENV"] = "/environment/prefix"
python_minor = ".".join(str(v) for v in current_python[:2]) python_minor = ".".join(str(v) for v in current_python[:2])
......
...@@ -36,11 +36,10 @@ if TYPE_CHECKING: ...@@ -36,11 +36,10 @@ if TYPE_CHECKING:
@pytest.fixture @pytest.fixture
def source_dir(tmp_path: Path) -> Iterator[Path]: def source_dir(tmp_path: Path) -> Iterator[Path]:
cwd = os.getcwd() cwd = Path.cwd()
try: try:
os.chdir(str(tmp_path)) os.chdir(tmp_path)
yield Path(tmp_path.as_posix()) yield tmp_path
finally: finally:
os.chdir(cwd) os.chdir(cwd)
......
...@@ -67,7 +67,7 @@ def installer(pool: RepositoryPool, env: NullEnv) -> PipInstaller: ...@@ -67,7 +67,7 @@ def installer(pool: RepositoryPool, env: NullEnv) -> PipInstaller:
return PipInstaller(env, NullIO(), pool) return PipInstaller(env, NullIO(), pool)
def test_requirement(installer: PipInstaller): def test_requirement(installer: PipInstaller) -> None:
package = Package("ipython", "7.5.0") package = Package("ipython", "7.5.0")
package.files = [ package.files = [
{"file": "foo-0.1.0.tar.gz", "hash": "md5:dbdc53e3918f28fa335a173432402a00"}, {"file": "foo-0.1.0.tar.gz", "hash": "md5:dbdc53e3918f28fa335a173432402a00"},
...@@ -88,7 +88,7 @@ def test_requirement(installer: PipInstaller): ...@@ -88,7 +88,7 @@ def test_requirement(installer: PipInstaller):
assert result == expected assert result == expected
def test_requirement_source_type_url(env: NullEnv): def test_requirement_source_type_url(env: NullEnv) -> None:
installer = PipInstaller(env, NullIO(), RepositoryPool()) installer = PipInstaller(env, NullIO(), RepositoryPool())
foo = Package( foo = Package(
...@@ -121,7 +121,9 @@ def test_requirement_git_subdirectory( ...@@ -121,7 +121,9 @@ def test_requirement_git_subdirectory(
assert Path(cmd[-1]).parts[-3:] == ("demo", "subdirectories", "two") assert Path(cmd[-1]).parts[-3:] == ("demo", "subdirectories", "two")
def test_requirement_git_develop_false(installer: PipInstaller, package_git: Package): def test_requirement_git_develop_false(
installer: PipInstaller, package_git: Package
) -> None:
package_git.develop = False package_git.develop = False
result = installer.requirement(package_git) result = installer.requirement(package_git)
expected = "git+git@github.com:demo/demo.git@master#egg=demo" expected = "git+git@github.com:demo/demo.git@master#egg=demo"
...@@ -131,7 +133,7 @@ def test_requirement_git_develop_false(installer: PipInstaller, package_git: Pac ...@@ -131,7 +133,7 @@ def test_requirement_git_develop_false(installer: PipInstaller, package_git: Pac
def test_install_with_non_pypi_default_repository( def test_install_with_non_pypi_default_repository(
pool: RepositoryPool, installer: PipInstaller pool: RepositoryPool, installer: PipInstaller
): ) -> None:
default = LegacyRepository("default", "https://default.com") default = LegacyRepository("default", "https://default.com")
another = LegacyRepository("another", "https://another.com") another = LegacyRepository("another", "https://another.com")
...@@ -164,7 +166,9 @@ def test_install_with_non_pypi_default_repository( ...@@ -164,7 +166,9 @@ def test_install_with_non_pypi_default_repository(
("cert", "cert"), ("cert", "cert"),
], ],
) )
def test_install_with_certs(mocker: MockerFixture, key: str, option: str, env: NullEnv): def test_install_with_certs(
mocker: MockerFixture, key: str, option: str, env: NullEnv
) -> None:
client_path = "path/to/client.pem" client_path = "path/to/client.pem"
mocker.patch( mocker.patch(
"poetry.utils.authenticator.Authenticator.get_certs_for_url", "poetry.utils.authenticator.Authenticator.get_certs_for_url",
...@@ -195,7 +199,9 @@ def test_install_with_certs(mocker: MockerFixture, key: str, option: str, env: N ...@@ -195,7 +199,9 @@ def test_install_with_certs(mocker: MockerFixture, key: str, option: str, env: N
assert cmd[cert_index + 1] == str(Path(client_path)) assert cmd[cert_index + 1] == str(Path(client_path))
def test_requirement_git_develop_true(installer: PipInstaller, package_git: Package): def test_requirement_git_develop_true(
installer: PipInstaller, package_git: Package
) -> None:
package_git.develop = True package_git.develop = True
result = installer.requirement(package_git) result = installer.requirement(package_git)
expected = ["-e", "git+git@github.com:demo/demo.git@master#egg=demo"] expected = ["-e", "git+git@github.com:demo/demo.git@master#egg=demo"]
...@@ -205,7 +211,7 @@ def test_requirement_git_develop_true(installer: PipInstaller, package_git: Pack ...@@ -205,7 +211,7 @@ def test_requirement_git_develop_true(installer: PipInstaller, package_git: Pack
def test_uninstall_git_package_nspkg_pth_cleanup( def test_uninstall_git_package_nspkg_pth_cleanup(
mocker: MockerFixture, tmp_venv: VirtualEnv, pool: RepositoryPool mocker: MockerFixture, tmp_venv: VirtualEnv, pool: RepositoryPool
): ) -> None:
# this test scenario requires a real installation using the pip installer # this test scenario requires a real installation using the pip installer
installer = PipInstaller(tmp_venv, NullIO(), pool) installer = PipInstaller(tmp_venv, NullIO(), pool)
...@@ -236,7 +242,7 @@ def test_uninstall_git_package_nspkg_pth_cleanup( ...@@ -236,7 +242,7 @@ def test_uninstall_git_package_nspkg_pth_cleanup(
installer.install(package) installer.install(package)
installer.remove(package) installer.remove(package)
pth_file = f"{package.name}-nspkg.pth" pth_file = Path(f"{package.name}-nspkg.pth")
assert not tmp_venv.site_packages.exists(pth_file) assert not tmp_venv.site_packages.exists(pth_file)
# any command in the virtual environment should trigger the error message # any command in the virtual environment should trigger the error message
...@@ -244,7 +250,7 @@ def test_uninstall_git_package_nspkg_pth_cleanup( ...@@ -244,7 +250,7 @@ def test_uninstall_git_package_nspkg_pth_cleanup(
assert not re.match(rf"Error processing line 1 of .*{pth_file}", output) assert not re.match(rf"Error processing line 1 of .*{pth_file}", output)
def test_install_with_trusted_host(config: Config, env: NullEnv): def test_install_with_trusted_host(config: Config, env: NullEnv) -> None:
config.merge({"certificates": {"default": {"cert": False}}}) config.merge({"certificates": {"default": {"cert": False}}})
default = LegacyRepository("default", "https://foo.bar") default = LegacyRepository("default", "https://foo.bar")
...@@ -272,7 +278,7 @@ def test_install_with_trusted_host(config: Config, env: NullEnv): ...@@ -272,7 +278,7 @@ def test_install_with_trusted_host(config: Config, env: NullEnv):
def test_install_directory_fallback_on_poetry_create_error( def test_install_directory_fallback_on_poetry_create_error(
mocker: MockerFixture, tmp_venv: VirtualEnv, pool: RepositoryPool mocker: MockerFixture, tmp_venv: VirtualEnv, pool: RepositoryPool
): ) -> None:
mock_create_poetry = mocker.patch( mock_create_poetry = mocker.patch(
"poetry.factory.Factory.create_poetry", side_effect=RuntimeError "poetry.factory.Factory.create_poetry", side_effect=RuntimeError
) )
......
...@@ -86,7 +86,7 @@ def env_manager(simple_poetry: Poetry) -> EnvManager: ...@@ -86,7 +86,7 @@ def env_manager(simple_poetry: Poetry) -> EnvManager:
def tmp_venv(tmp_dir: str, env_manager: EnvManager) -> VirtualEnv: def tmp_venv(tmp_dir: str, env_manager: EnvManager) -> VirtualEnv:
venv_path = Path(tmp_dir) / "venv" venv_path = Path(tmp_dir) / "venv"
env_manager.build_venv(str(venv_path)) env_manager.build_venv(venv_path)
venv = VirtualEnv(venv_path) venv = VirtualEnv(venv_path)
yield venv yield venv
...@@ -96,20 +96,20 @@ def tmp_venv(tmp_dir: str, env_manager: EnvManager) -> VirtualEnv: ...@@ -96,20 +96,20 @@ def tmp_venv(tmp_dir: str, env_manager: EnvManager) -> VirtualEnv:
def test_builder_installs_proper_files_for_standard_packages( def test_builder_installs_proper_files_for_standard_packages(
simple_poetry: Poetry, tmp_venv: VirtualEnv simple_poetry: Poetry, tmp_venv: VirtualEnv
): ) -> None:
builder = EditableBuilder(simple_poetry, tmp_venv, NullIO()) builder = EditableBuilder(simple_poetry, tmp_venv, NullIO())
builder.build() builder.build()
assert tmp_venv._bin_dir.joinpath("foo").exists() assert tmp_venv._bin_dir.joinpath("foo").exists()
pth_file = "simple_project.pth" pth_file = Path("simple_project.pth")
assert tmp_venv.site_packages.exists(pth_file) assert tmp_venv.site_packages.exists(pth_file)
assert ( assert (
simple_poetry.file.parent.resolve().as_posix() simple_poetry.file.parent.resolve().as_posix()
== tmp_venv.site_packages.find(pth_file)[0].read_text().strip(os.linesep) == tmp_venv.site_packages.find(pth_file)[0].read_text().strip(os.linesep)
) )
dist_info = "simple_project-1.2.3.dist-info" dist_info = Path("simple_project-1.2.3.dist-info")
assert tmp_venv.site_packages.exists(dist_info) assert tmp_venv.site_packages.exists(dist_info)
dist_info = tmp_venv.site_packages.find(dist_info)[0] dist_info = tmp_venv.site_packages.find(dist_info)[0]
...@@ -176,7 +176,7 @@ My Package ...@@ -176,7 +176,7 @@ My Package
assert all(len(row) == 3 for row in records) assert all(len(row) == 3 for row in records)
record_entries = {row[0] for row in records} record_entries = {row[0] for row in records}
pth_file = "simple_project.pth" pth_file = Path("simple_project.pth")
assert tmp_venv.site_packages.exists(pth_file) assert tmp_venv.site_packages.exists(pth_file)
assert str(tmp_venv.site_packages.find(pth_file)[0]) in record_entries assert str(tmp_venv.site_packages.find(pth_file)[0]) in record_entries
assert str(tmp_venv._bin_dir.joinpath("foo")) in record_entries assert str(tmp_venv._bin_dir.joinpath("foo")) in record_entries
...@@ -223,7 +223,7 @@ if __name__ == '__main__': ...@@ -223,7 +223,7 @@ if __name__ == '__main__':
def test_builder_falls_back_on_setup_and_pip_for_packages_with_build_scripts( def test_builder_falls_back_on_setup_and_pip_for_packages_with_build_scripts(
mocker: MockerFixture, extended_poetry: Poetry, tmp_dir: str mocker: MockerFixture, extended_poetry: Poetry, tmp_dir: str
): ) -> None:
pip_install = mocker.patch("poetry.masonry.builders.editable.pip_install") pip_install = mocker.patch("poetry.masonry.builders.editable.pip_install")
env = MockEnv(path=Path(tmp_dir) / "foo") env = MockEnv(path=Path(tmp_dir) / "foo")
builder = EditableBuilder(extended_poetry, env, NullIO()) builder = EditableBuilder(extended_poetry, env, NullIO())
...@@ -273,11 +273,11 @@ def test_builder_setup_generation_runs_with_pip_editable(tmp_dir: str) -> None: ...@@ -273,11 +273,11 @@ def test_builder_setup_generation_runs_with_pip_editable(tmp_dir: str) -> None:
def test_builder_installs_proper_files_when_packages_configured( def test_builder_installs_proper_files_when_packages_configured(
project_with_include: Poetry, tmp_venv: VirtualEnv project_with_include: Poetry, tmp_venv: VirtualEnv
): ) -> None:
builder = EditableBuilder(project_with_include, tmp_venv, NullIO()) builder = EditableBuilder(project_with_include, tmp_venv, NullIO())
builder.build() builder.build()
pth_file = "with_include.pth" pth_file = Path("with_include.pth")
assert tmp_venv.site_packages.exists(pth_file) assert tmp_venv.site_packages.exists(pth_file)
pth_file = tmp_venv.site_packages.find(pth_file)[0] pth_file = tmp_venv.site_packages.find(pth_file)[0]
...@@ -298,12 +298,12 @@ def test_builder_installs_proper_files_when_packages_configured( ...@@ -298,12 +298,12 @@ def test_builder_installs_proper_files_when_packages_configured(
def test_builder_generates_proper_metadata_when_multiple_readme_files( def test_builder_generates_proper_metadata_when_multiple_readme_files(
with_multiple_readme_files: Poetry, tmp_venv: VirtualEnv with_multiple_readme_files: Poetry, tmp_venv: VirtualEnv
): ) -> None:
builder = EditableBuilder(with_multiple_readme_files, tmp_venv, NullIO()) builder = EditableBuilder(with_multiple_readme_files, tmp_venv, NullIO())
builder.build() builder.build()
dist_info = "my_package-0.1.dist-info" dist_info = Path("my_package-0.1.dist-info")
assert tmp_venv.site_packages.exists(dist_info) assert tmp_venv.site_packages.exists(dist_info)
dist_info = tmp_venv.site_packages.find(dist_info)[0] dist_info = tmp_venv.site_packages.find(dist_info)[0]
...@@ -336,7 +336,7 @@ Changelog ...@@ -336,7 +336,7 @@ Changelog
def test_builder_should_execute_build_scripts( def test_builder_should_execute_build_scripts(
mocker: MockerFixture, extended_without_setup_poetry: Poetry, tmp_path: Path mocker: MockerFixture, extended_without_setup_poetry: Poetry, tmp_path: Path
): ) -> None:
env = MockEnv(path=tmp_path / "foo") env = MockEnv(path=tmp_path / "foo")
mocker.patch( mocker.patch(
"poetry.masonry.builders.editable.build_environment" "poetry.masonry.builders.editable.build_environment"
......
...@@ -34,7 +34,7 @@ if TYPE_CHECKING: ...@@ -34,7 +34,7 @@ if TYPE_CHECKING:
def locker() -> Locker: def locker() -> Locker:
with tempfile.NamedTemporaryFile() as f: with tempfile.NamedTemporaryFile() as f:
f.close() f.close()
locker = Locker(f.name, {}) locker = Locker(Path(f.name), {})
return locker return locker
...@@ -44,7 +44,7 @@ def root() -> ProjectPackage: ...@@ -44,7 +44,7 @@ def root() -> ProjectPackage:
return ProjectPackage("root", "1.2.3") return ProjectPackage("root", "1.2.3")
def test_lock_file_data_is_ordered(locker: Locker, root: ProjectPackage): def test_lock_file_data_is_ordered(locker: Locker, root: ProjectPackage) -> None:
package_a = get_package("A", "1.0.0") package_a = get_package("A", "1.0.0")
package_a.add_dependency(Factory.create_dependency("B", "^1.0")) package_a.add_dependency(Factory.create_dependency("B", "^1.0"))
package_a.files = [{"file": "foo", "hash": "456"}, {"file": "bar", "hash": "123"}] package_a.files = [{"file": "foo", "hash": "456"}, {"file": "bar", "hash": "123"}]
...@@ -200,7 +200,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8 ...@@ -200,7 +200,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8
assert content == expected assert content == expected
def test_locker_properly_loads_extras(locker: Locker): def test_locker_properly_loads_extras(locker: Locker) -> None:
content = f"""\ content = f"""\
# {GENERATED_COMMENT} # {GENERATED_COMMENT}
...@@ -246,7 +246,7 @@ content-hash = "c3d07fca33fba542ef2b2a4d75bf5b48d892d21a830e2ad9c952ba5123a52f77 ...@@ -246,7 +246,7 @@ content-hash = "c3d07fca33fba542ef2b2a4d75bf5b48d892d21a830e2ad9c952ba5123a52f77
assert lockfile_dep.name == "lockfile" assert lockfile_dep.name == "lockfile"
def test_locker_properly_loads_nested_extras(locker: Locker): def test_locker_properly_loads_nested_extras(locker: Locker) -> None:
content = f"""\ content = f"""\
# {GENERATED_COMMENT} # {GENERATED_COMMENT}
...@@ -327,7 +327,7 @@ content-hash = "123456789" ...@@ -327,7 +327,7 @@ content-hash = "123456789"
assert len(packages) == 1 assert len(packages) == 1
def test_locker_properly_loads_extras_legacy(locker: Locker): def test_locker_properly_loads_extras_legacy(locker: Locker) -> None:
content = f"""\ content = f"""\
# {GENERATED_COMMENT} # {GENERATED_COMMENT}
...@@ -530,7 +530,9 @@ demo = [ ...@@ -530,7 +530,9 @@ demo = [
package.files = [] package.files = []
def test_lock_packages_with_null_description(locker: Locker, root: ProjectPackage): def test_lock_packages_with_null_description(
locker: Locker, root: ProjectPackage
) -> None:
package_a = get_package("A", "1.0.0") package_a = get_package("A", "1.0.0")
package_a.description = None package_a.description = None
...@@ -560,7 +562,9 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8 ...@@ -560,7 +562,9 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8
assert content == expected assert content == expected
def test_lock_file_should_not_have_mixed_types(locker: Locker, root: ProjectPackage): def test_lock_file_should_not_have_mixed_types(
locker: Locker, root: ProjectPackage
) -> None:
package_a = get_package("A", "1.0.0") package_a = get_package("A", "1.0.0")
package_a.add_dependency(Factory.create_dependency("B", "^1.0.0")) package_a.add_dependency(Factory.create_dependency("B", "^1.0.0"))
package_a.add_dependency( package_a.add_dependency(
...@@ -604,7 +608,9 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8 ...@@ -604,7 +608,9 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8
assert content == expected assert content == expected
def test_reading_lock_file_should_raise_an_error_on_invalid_data(locker: Locker): def test_reading_lock_file_should_raise_an_error_on_invalid_data(
locker: Locker,
) -> None:
content = f"""\ content = f"""\
# {GENERATED_COMMENT} # {GENERATED_COMMENT}
...@@ -639,7 +645,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8 ...@@ -639,7 +645,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8
def test_locking_legacy_repository_package_should_include_source_section( def test_locking_legacy_repository_package_should_include_source_section(
root: ProjectPackage, locker: Locker root: ProjectPackage, locker: Locker
): ) -> None:
package_a = Package( package_a = Package(
"A", "A",
"1.0.0", "1.0.0",
...@@ -682,7 +688,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8 ...@@ -682,7 +688,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8
def test_locker_should_emit_warnings_if_lock_version_is_newer_but_allowed( def test_locker_should_emit_warnings_if_lock_version_is_newer_but_allowed(
locker: Locker, caplog: LogCaptureFixture locker: Locker, caplog: LogCaptureFixture
): ) -> None:
version = ".".join(Version.parse(Locker._VERSION).next_minor().text.split(".")[:2]) version = ".".join(Version.parse(Locker._VERSION).next_minor().text.split(".")[:2])
content = f"""\ content = f"""\
[metadata] [metadata]
...@@ -712,7 +718,7 @@ regenerate the lock file with the `poetry lock` command.\ ...@@ -712,7 +718,7 @@ regenerate the lock file with the `poetry lock` command.\
def test_locker_should_raise_an_error_if_lock_version_is_newer_and_not_allowed( def test_locker_should_raise_an_error_if_lock_version_is_newer_and_not_allowed(
locker: Locker, caplog: LogCaptureFixture locker: Locker, caplog: LogCaptureFixture
): ) -> None:
content = f"""\ content = f"""\
# {GENERATED_COMMENT} # {GENERATED_COMMENT}
...@@ -730,7 +736,9 @@ content-hash = "c3d07fca33fba542ef2b2a4d75bf5b48d892d21a830e2ad9c952ba5123a52f77 ...@@ -730,7 +736,9 @@ content-hash = "c3d07fca33fba542ef2b2a4d75bf5b48d892d21a830e2ad9c952ba5123a52f77
_ = locker.lock_data _ = locker.lock_data
def test_root_extras_dependencies_are_ordered(locker: Locker, root: ProjectPackage): def test_root_extras_dependencies_are_ordered(
locker: Locker, root: ProjectPackage
) -> None:
root_dir = Path(__file__).parent.parent.joinpath("fixtures") root_dir = Path(__file__).parent.parent.joinpath("fixtures")
Factory.create_dependency("B", "1.0.0", root_dir=root_dir) Factory.create_dependency("B", "1.0.0", root_dir=root_dir)
Factory.create_dependency("C", "1.0.0", root_dir=root_dir) Factory.create_dependency("C", "1.0.0", root_dir=root_dir)
...@@ -765,7 +773,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8 ...@@ -765,7 +773,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8
assert content == expected assert content == expected
def test_extras_dependencies_are_ordered(locker: Locker, root: ProjectPackage): def test_extras_dependencies_are_ordered(locker: Locker, root: ProjectPackage) -> None:
package_a = get_package("A", "1.0.0") package_a = get_package("A", "1.0.0")
package_a.add_dependency( package_a.add_dependency(
Factory.create_dependency( Factory.create_dependency(
...@@ -805,7 +813,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8 ...@@ -805,7 +813,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8
def test_locker_should_neither_emit_warnings_nor_raise_error_for_lower_compatible_versions( # noqa: E501 def test_locker_should_neither_emit_warnings_nor_raise_error_for_lower_compatible_versions( # noqa: E501
locker: Locker, caplog: LogCaptureFixture locker: Locker, caplog: LogCaptureFixture
): ) -> None:
older_version = "1.1" older_version = "1.1"
content = f"""\ content = f"""\
[metadata] [metadata]
...@@ -827,7 +835,7 @@ content-hash = "c3d07fca33fba542ef2b2a4d75bf5b48d892d21a830e2ad9c952ba5123a52f77 ...@@ -827,7 +835,7 @@ content-hash = "c3d07fca33fba542ef2b2a4d75bf5b48d892d21a830e2ad9c952ba5123a52f77
def test_locker_dumps_dependency_information_correctly( def test_locker_dumps_dependency_information_correctly(
locker: Locker, root: ProjectPackage locker: Locker, root: ProjectPackage
): ) -> None:
root_dir = Path(__file__).parent.parent.joinpath("fixtures") root_dir = Path(__file__).parent.parent.joinpath("fixtures")
package_a = get_package("A", "1.0.0") package_a = get_package("A", "1.0.0")
package_a.add_dependency( package_a.add_dependency(
...@@ -950,7 +958,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8 ...@@ -950,7 +958,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8
def test_locker_dumps_dependency_extras_in_correct_order( def test_locker_dumps_dependency_extras_in_correct_order(
locker: Locker, root: ProjectPackage locker: Locker, root: ProjectPackage
): ) -> None:
root_dir = Path(__file__).parent.parent.joinpath("fixtures") root_dir = Path(__file__).parent.parent.joinpath("fixtures")
package_a = get_package("A", "1.0.0") package_a = get_package("A", "1.0.0")
Factory.create_dependency("B", "1.0.0", root_dir=root_dir) Factory.create_dependency("B", "1.0.0", root_dir=root_dir)
...@@ -996,7 +1004,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8 ...@@ -996,7 +1004,7 @@ content-hash = "115cf985d932e9bf5f540555bbdd75decbb62cac81e399375fc19f6277f8c1d8
def test_locked_repository_uses_root_dir_of_package( def test_locked_repository_uses_root_dir_of_package(
locker: Locker, mocker: MockerFixture locker: Locker, mocker: MockerFixture
): ) -> None:
content = f"""\ content = f"""\
# {GENERATED_COMMENT} # {GENERATED_COMMENT}
...@@ -1084,7 +1092,7 @@ def test_content_hash_with_legacy_is_compatible( ...@@ -1084,7 +1092,7 @@ def test_content_hash_with_legacy_is_compatible(
assert (content_hash == old_content_hash) or fresh assert (content_hash == old_content_hash) or fresh
def test_lock_file_resolves_file_url_symlinks(root: ProjectPackage): def test_lock_file_resolves_file_url_symlinks(root: ProjectPackage) -> None:
""" """
Create directories and file structure as follows: Create directories and file structure as follows:
...@@ -1119,7 +1127,7 @@ def test_lock_file_resolves_file_url_symlinks(root: ProjectPackage): ...@@ -1119,7 +1127,7 @@ def test_lock_file_resolves_file_url_symlinks(root: ProjectPackage):
# Test is not possible in that case. # Test is not possible in that case.
return return
raise raise
locker = Locker(str(symlink_path) + os.sep + Path(lock_file.name).name, {}) locker = Locker(symlink_path / lock_file.name, {})
package_local = Package( package_local = Package(
"local-package", "local-package",
......
...@@ -68,7 +68,7 @@ class MockVirtualEnv(VirtualEnv): ...@@ -68,7 +68,7 @@ class MockVirtualEnv(VirtualEnv):
self._sys_path = sys_path self._sys_path = sys_path
@property @property
def sys_path(self) -> list[str] | None: def sys_path(self) -> list[str]:
if self._sys_path is not None: if self._sys_path is not None:
return self._sys_path return self._sys_path
...@@ -88,10 +88,10 @@ def manager(poetry: Poetry) -> EnvManager: ...@@ -88,10 +88,10 @@ def manager(poetry: Poetry) -> EnvManager:
def test_virtualenvs_with_spaces_in_their_path_work_as_expected( def test_virtualenvs_with_spaces_in_their_path_work_as_expected(
tmp_dir: str, manager: EnvManager tmp_dir: str, manager: EnvManager
): ) -> None:
venv_path = Path(tmp_dir) / "Virtual Env" venv_path = Path(tmp_dir) / "Virtual Env"
manager.build_venv(str(venv_path)) manager.build_venv(venv_path)
venv = VirtualEnv(venv_path) venv = VirtualEnv(venv_path)
...@@ -99,12 +99,12 @@ def test_virtualenvs_with_spaces_in_their_path_work_as_expected( ...@@ -99,12 +99,12 @@ def test_virtualenvs_with_spaces_in_their_path_work_as_expected(
@pytest.mark.skipif(sys.platform != "darwin", reason="requires darwin") @pytest.mark.skipif(sys.platform != "darwin", reason="requires darwin")
def test_venv_backup_exclusion(tmp_dir: str, manager: EnvManager): def test_venv_backup_exclusion(tmp_dir: str, manager: EnvManager) -> None:
import xattr import xattr
venv_path = Path(tmp_dir) / "Virtual Env" venv_path = Path(tmp_dir) / "Virtual Env"
manager.build_venv(str(venv_path)) manager.build_venv(venv_path)
value = ( value = (
b"bplist00_\x10\x11com.apple.backupd" b"bplist00_\x10\x11com.apple.backupd"
...@@ -121,20 +121,20 @@ def test_venv_backup_exclusion(tmp_dir: str, manager: EnvManager): ...@@ -121,20 +121,20 @@ def test_venv_backup_exclusion(tmp_dir: str, manager: EnvManager):
def test_env_commands_with_spaces_in_their_arg_work_as_expected( def test_env_commands_with_spaces_in_their_arg_work_as_expected(
tmp_dir: str, manager: EnvManager tmp_dir: str, manager: EnvManager
): ) -> None:
venv_path = Path(tmp_dir) / "Virtual Env" venv_path = Path(tmp_dir) / "Virtual Env"
manager.build_venv(str(venv_path)) manager.build_venv(venv_path)
venv = VirtualEnv(venv_path) venv = VirtualEnv(venv_path)
assert venv.run("python", venv.pip, "--version").startswith( assert venv.run("python", str(venv.pip), "--version").startswith(
f"pip {venv.pip_version} from " f"pip {venv.pip_version} from "
) )
def test_env_shell_commands_with_stdinput_in_their_arg_work_as_expected( def test_env_shell_commands_with_stdinput_in_their_arg_work_as_expected(
tmp_dir: str, manager: EnvManager tmp_dir: str, manager: EnvManager
): ) -> None:
venv_path = Path(tmp_dir) / "Virtual Env" venv_path = Path(tmp_dir) / "Virtual Env"
manager.build_venv(str(venv_path)) manager.build_venv(venv_path)
venv = VirtualEnv(venv_path) venv = VirtualEnv(venv_path)
run_output_path = Path(venv.run("python", "-", input_=GET_BASE_PREFIX).strip()) run_output_path = Path(venv.run("python", "-", input_=GET_BASE_PREFIX).strip())
venv_base_prefix_path = Path(str(venv.get_base_prefix())) venv_base_prefix_path = Path(str(venv.get_base_prefix()))
...@@ -143,9 +143,9 @@ def test_env_shell_commands_with_stdinput_in_their_arg_work_as_expected( ...@@ -143,9 +143,9 @@ def test_env_shell_commands_with_stdinput_in_their_arg_work_as_expected(
def test_env_get_supported_tags_matches_inside_virtualenv( def test_env_get_supported_tags_matches_inside_virtualenv(
tmp_dir: str, manager: EnvManager tmp_dir: str, manager: EnvManager
): ) -> None:
venv_path = Path(tmp_dir) / "Virtual Env" venv_path = Path(tmp_dir) / "Virtual Env"
manager.build_venv(str(venv_path)) manager.build_venv(venv_path)
venv = VirtualEnv(venv_path) venv = VirtualEnv(venv_path)
import packaging.tags import packaging.tags
...@@ -170,7 +170,7 @@ def test_env_get_venv_with_venv_folder_present( ...@@ -170,7 +170,7 @@ def test_env_get_venv_with_venv_folder_present(
poetry: Poetry, poetry: Poetry,
in_project_venv_dir: Path, in_project_venv_dir: Path,
in_project: bool | None, in_project: bool | None,
): ) -> None:
poetry.config.config["virtualenvs"]["in-project"] = in_project poetry.config.config["virtualenvs"]["in-project"] = in_project
venv = manager.get() venv = manager.get()
if in_project is False: if in_project is False:
...@@ -212,7 +212,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file( ...@@ -212,7 +212,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -232,7 +232,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file( ...@@ -232,7 +232,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
m.assert_called_with( m.assert_called_with(
Path(tmp_dir) / f"{venv_name}-py3.7", Path(tmp_dir) / f"{venv_name}-py3.7",
executable="/usr/bin/python3.7", executable=Path("/usr/bin/python3.7"),
flags={ flags={
"always-copy": False, "always-copy": False,
"system-site-packages": False, "system-site-packages": False,
...@@ -259,7 +259,7 @@ def test_activate_activates_existing_virtualenv_no_envs_file( ...@@ -259,7 +259,7 @@ def test_activate_activates_existing_virtualenv_no_envs_file(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -298,7 +298,7 @@ def test_activate_activates_same_virtualenv_with_envs_file( ...@@ -298,7 +298,7 @@ def test_activate_activates_same_virtualenv_with_envs_file(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -341,7 +341,7 @@ def test_activate_activates_different_virtualenv_with_envs_file( ...@@ -341,7 +341,7 @@ def test_activate_activates_different_virtualenv_with_envs_file(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -368,7 +368,7 @@ def test_activate_activates_different_virtualenv_with_envs_file( ...@@ -368,7 +368,7 @@ def test_activate_activates_different_virtualenv_with_envs_file(
m.assert_called_with( m.assert_called_with(
Path(tmp_dir) / f"{venv_name}-py3.6", Path(tmp_dir) / f"{venv_name}-py3.6",
executable="/usr/bin/python3.6", executable=Path("/usr/bin/python3.6"),
flags={ flags={
"always-copy": False, "always-copy": False,
"system-site-packages": False, "system-site-packages": False,
...@@ -394,7 +394,7 @@ def test_activate_activates_recreates_for_different_patch( ...@@ -394,7 +394,7 @@ def test_activate_activates_recreates_for_different_patch(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -432,7 +432,7 @@ def test_activate_activates_recreates_for_different_patch( ...@@ -432,7 +432,7 @@ def test_activate_activates_recreates_for_different_patch(
build_venv_m.assert_called_with( build_venv_m.assert_called_with(
Path(tmp_dir) / f"{venv_name}-py3.7", Path(tmp_dir) / f"{venv_name}-py3.7",
executable="/usr/bin/python3.7", executable=Path("/usr/bin/python3.7"),
flags={ flags={
"always-copy": False, "always-copy": False,
"system-site-packages": False, "system-site-packages": False,
...@@ -460,7 +460,7 @@ def test_activate_does_not_recreate_when_switching_minor( ...@@ -460,7 +460,7 @@ def test_activate_does_not_recreate_when_switching_minor(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -511,7 +511,7 @@ def test_deactivate_non_activated_but_existing( ...@@ -511,7 +511,7 @@ def test_deactivate_non_activated_but_existing(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -529,7 +529,6 @@ def test_deactivate_non_activated_but_existing( ...@@ -529,7 +529,6 @@ def test_deactivate_non_activated_but_existing(
env = manager.get() env = manager.get()
assert env.path == Path(tmp_dir) / f"{venv_name}-py{python}" assert env.path == Path(tmp_dir) / f"{venv_name}-py{python}"
assert Path("/prefix")
def test_deactivate_activated( def test_deactivate_activated(
...@@ -539,7 +538,7 @@ def test_deactivate_activated( ...@@ -539,7 +538,7 @@ def test_deactivate_activated(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -569,7 +568,6 @@ def test_deactivate_activated( ...@@ -569,7 +568,6 @@ def test_deactivate_activated(
env = manager.get() env = manager.get()
assert env.path == Path(tmp_dir) / f"{venv_name}-py{version.major}.{version.minor}" assert env.path == Path(tmp_dir) / f"{venv_name}-py{version.major}.{version.minor}"
assert Path("/prefix")
envs = envs_file.read() envs = envs_file.read()
assert len(envs) == 0 assert len(envs) == 0
...@@ -582,7 +580,7 @@ def test_get_prefers_explicitly_activated_virtualenvs_over_env_var( ...@@ -582,7 +580,7 @@ def test_get_prefers_explicitly_activated_virtualenvs_over_env_var(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
os.environ["VIRTUAL_ENV"] = "/environment/prefix" os.environ["VIRTUAL_ENV"] = "/environment/prefix"
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
...@@ -614,7 +612,7 @@ def test_list( ...@@ -614,7 +612,7 @@ def test_list(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
venv_name: str, venv_name: str,
): ) -> None:
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
...@@ -634,7 +632,7 @@ def test_remove_by_python_version( ...@@ -634,7 +632,7 @@ def test_remove_by_python_version(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
...@@ -659,7 +657,7 @@ def test_remove_by_name( ...@@ -659,7 +657,7 @@ def test_remove_by_name(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
...@@ -684,7 +682,7 @@ def test_remove_by_string_with_python_and_version( ...@@ -684,7 +682,7 @@ def test_remove_by_string_with_python_and_version(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
...@@ -709,7 +707,7 @@ def test_remove_by_full_path_to_python( ...@@ -709,7 +707,7 @@ def test_remove_by_full_path_to_python(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
...@@ -735,7 +733,7 @@ def test_raises_if_acting_on_different_project_by_full_path( ...@@ -735,7 +733,7 @@ def test_raises_if_acting_on_different_project_by_full_path(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
): ) -> None:
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
different_venv_name = "different-project" different_venv_name = "different-project"
...@@ -761,7 +759,7 @@ def test_raises_if_acting_on_different_project_by_name( ...@@ -761,7 +759,7 @@ def test_raises_if_acting_on_different_project_by_name(
manager: EnvManager, manager: EnvManager,
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
): ) -> None:
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
different_venv_name = ( different_venv_name = (
...@@ -788,7 +786,7 @@ def test_raises_when_passing_old_env_after_dir_rename( ...@@ -788,7 +786,7 @@ def test_raises_when_passing_old_env_after_dir_rename(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
venv_name: str, venv_name: str,
): ) -> None:
# Make sure that poetry raises when trying to remove old venv after you've renamed # Make sure that poetry raises when trying to remove old venv after you've renamed
# root directory of the project, which will create another venv with new name. # root directory of the project, which will create another venv with new name.
# This is not ideal as you still "can't" remove it by name, but it at least doesn't # This is not ideal as you still "can't" remove it by name, but it at least doesn't
...@@ -817,7 +815,7 @@ def test_remove_also_deactivates( ...@@ -817,7 +815,7 @@ def test_remove_also_deactivates(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
...@@ -850,7 +848,7 @@ def test_remove_keeps_dir_if_not_deleteable( ...@@ -850,7 +848,7 @@ def test_remove_keeps_dir_if_not_deleteable(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str, venv_name: str,
): ) -> None:
# Ensure we empty rather than delete folder if its is an active mount point. # Ensure we empty rather than delete folder if its is an active mount point.
# See https://github.com/python-poetry/poetry/pull/2064 # See https://github.com/python-poetry/poetry/pull/2064
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
...@@ -897,17 +895,17 @@ def test_remove_keeps_dir_if_not_deleteable( ...@@ -897,17 +895,17 @@ def test_remove_keeps_dir_if_not_deleteable(
@pytest.mark.skipif(os.name == "nt", reason="Symlinks are not support for Windows") @pytest.mark.skipif(os.name == "nt", reason="Symlinks are not support for Windows")
def test_env_has_symlinks_on_nix(tmp_dir: str, tmp_venv: VirtualEnv): def test_env_has_symlinks_on_nix(tmp_dir: str, tmp_venv: VirtualEnv) -> None:
assert os.path.islink(tmp_venv.python) assert os.path.islink(tmp_venv.python)
def test_run_with_input(tmp_dir: str, tmp_venv: VirtualEnv): def test_run_with_input(tmp_dir: str, tmp_venv: VirtualEnv) -> None:
result = tmp_venv.run("python", "-", input_=MINIMAL_SCRIPT) result = tmp_venv.run("python", "-", input_=MINIMAL_SCRIPT)
assert result == "Minimal Output" + os.linesep assert result == "Minimal Output" + os.linesep
def test_run_with_input_non_zero_return(tmp_dir: str, tmp_venv: VirtualEnv): def test_run_with_input_non_zero_return(tmp_dir: str, tmp_venv: VirtualEnv) -> None:
with pytest.raises(EnvCommandError) as process_error: with pytest.raises(EnvCommandError) as process_error:
# Test command that will return non-zero returncode. # Test command that will return non-zero returncode.
tmp_venv.run("python", "-", input_=ERRORING_SCRIPT) tmp_venv.run("python", "-", input_=ERRORING_SCRIPT)
...@@ -917,7 +915,7 @@ def test_run_with_input_non_zero_return(tmp_dir: str, tmp_venv: VirtualEnv): ...@@ -917,7 +915,7 @@ def test_run_with_input_non_zero_return(tmp_dir: str, tmp_venv: VirtualEnv):
def test_run_with_keyboard_interrupt( def test_run_with_keyboard_interrupt(
tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture
): ) -> None:
mocker.patch("subprocess.run", side_effect=KeyboardInterrupt()) mocker.patch("subprocess.run", side_effect=KeyboardInterrupt())
with pytest.raises(KeyboardInterrupt): with pytest.raises(KeyboardInterrupt):
tmp_venv.run("python", "-", input_=MINIMAL_SCRIPT) tmp_venv.run("python", "-", input_=MINIMAL_SCRIPT)
...@@ -926,7 +924,7 @@ def test_run_with_keyboard_interrupt( ...@@ -926,7 +924,7 @@ def test_run_with_keyboard_interrupt(
def test_call_with_input_and_keyboard_interrupt( def test_call_with_input_and_keyboard_interrupt(
tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture
): ) -> None:
mocker.patch("subprocess.run", side_effect=KeyboardInterrupt()) mocker.patch("subprocess.run", side_effect=KeyboardInterrupt())
kwargs = {"call": True} kwargs = {"call": True}
with pytest.raises(KeyboardInterrupt): with pytest.raises(KeyboardInterrupt):
...@@ -936,7 +934,7 @@ def test_call_with_input_and_keyboard_interrupt( ...@@ -936,7 +934,7 @@ def test_call_with_input_and_keyboard_interrupt(
def test_call_no_input_with_keyboard_interrupt( def test_call_no_input_with_keyboard_interrupt(
tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture
): ) -> None:
mocker.patch("subprocess.call", side_effect=KeyboardInterrupt()) mocker.patch("subprocess.call", side_effect=KeyboardInterrupt())
kwargs = {"call": True} kwargs = {"call": True}
with pytest.raises(KeyboardInterrupt): with pytest.raises(KeyboardInterrupt):
...@@ -946,7 +944,7 @@ def test_call_no_input_with_keyboard_interrupt( ...@@ -946,7 +944,7 @@ def test_call_no_input_with_keyboard_interrupt(
def test_run_with_called_process_error( def test_run_with_called_process_error(
tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture
): ) -> None:
mocker.patch( mocker.patch(
"subprocess.run", "subprocess.run",
side_effect=subprocess.CalledProcessError( side_effect=subprocess.CalledProcessError(
...@@ -962,7 +960,7 @@ def test_run_with_called_process_error( ...@@ -962,7 +960,7 @@ def test_run_with_called_process_error(
def test_call_with_input_and_called_process_error( def test_call_with_input_and_called_process_error(
tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture
): ) -> None:
mocker.patch( mocker.patch(
"subprocess.run", "subprocess.run",
side_effect=subprocess.CalledProcessError( side_effect=subprocess.CalledProcessError(
...@@ -979,7 +977,7 @@ def test_call_with_input_and_called_process_error( ...@@ -979,7 +977,7 @@ def test_call_with_input_and_called_process_error(
def test_call_no_input_with_called_process_error( def test_call_no_input_with_called_process_error(
tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture
): ) -> None:
mocker.patch( mocker.patch(
"subprocess.call", "subprocess.call",
side_effect=subprocess.CalledProcessError( side_effect=subprocess.CalledProcessError(
...@@ -996,7 +994,7 @@ def test_call_no_input_with_called_process_error( ...@@ -996,7 +994,7 @@ def test_call_no_input_with_called_process_error(
def test_check_output_with_called_process_error( def test_check_output_with_called_process_error(
tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture
): ) -> None:
mocker.patch( mocker.patch(
"subprocess.check_output", "subprocess.check_output",
side_effect=subprocess.CalledProcessError( side_effect=subprocess.CalledProcessError(
...@@ -1037,7 +1035,7 @@ for i in range(10000): ...@@ -1037,7 +1035,7 @@ for i in range(10000):
def test_run_python_script_called_process_error( def test_run_python_script_called_process_error(
tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture tmp_dir: str, tmp_venv: VirtualEnv, mocker: MockerFixture
): ) -> None:
mocker.patch( mocker.patch(
"subprocess.run", "subprocess.run",
side_effect=subprocess.CalledProcessError( side_effect=subprocess.CalledProcessError(
...@@ -1050,7 +1048,7 @@ def test_run_python_script_called_process_error( ...@@ -1050,7 +1048,7 @@ def test_run_python_script_called_process_error(
assert "some error" in str(error.value) assert "some error" in str(error.value)
def test_run_python_script_only_stdout(tmp_dir: str, tmp_venv: VirtualEnv): def test_run_python_script_only_stdout(tmp_dir: str, tmp_venv: VirtualEnv) -> None:
output = tmp_venv.run_python_script( output = tmp_venv.run_python_script(
"import sys; print('some warning', file=sys.stderr); print('some output')" "import sys; print('some warning', file=sys.stderr); print('some output')"
) )
...@@ -1065,7 +1063,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_ ...@@ -1065,7 +1063,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_
mocker: MockerFixture, mocker: MockerFixture,
config_virtualenvs_path: Path, config_virtualenvs_path: Path,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -1084,7 +1082,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_ ...@@ -1084,7 +1082,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_
m.assert_called_with( m.assert_called_with(
config_virtualenvs_path / f"{venv_name}-py3.7", config_virtualenvs_path / f"{venv_name}-py3.7",
executable="/usr/bin/python3", executable=Path("/usr/bin/python3"),
flags={ flags={
"always-copy": False, "always-copy": False,
"system-site-packages": False, "system-site-packages": False,
...@@ -1102,7 +1100,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific ...@@ -1102,7 +1100,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific
mocker: MockerFixture, mocker: MockerFixture,
config_virtualenvs_path: Path, config_virtualenvs_path: Path,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -1120,7 +1118,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific ...@@ -1120,7 +1118,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific
m.assert_called_with( m.assert_called_with(
config_virtualenvs_path / f"{venv_name}-py3.9", config_virtualenvs_path / f"{venv_name}-py3.9",
executable="/usr/bin/python3.9", executable=Path("/usr/bin/python3.9"),
flags={ flags={
"always-copy": False, "always-copy": False,
"system-site-packages": False, "system-site-packages": False,
...@@ -1133,7 +1131,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific ...@@ -1133,7 +1131,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific
def test_create_venv_fails_if_no_compatible_python_version_could_be_found( def test_create_venv_fails_if_no_compatible_python_version_could_be_found(
manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -1159,7 +1157,7 @@ def test_create_venv_fails_if_no_compatible_python_version_could_be_found( ...@@ -1159,7 +1157,7 @@ def test_create_venv_fails_if_no_compatible_python_version_could_be_found(
def test_create_venv_does_not_try_to_find_compatible_versions_with_executable( def test_create_venv_does_not_try_to_find_compatible_versions_with_executable(
manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -1171,7 +1169,7 @@ def test_create_venv_does_not_try_to_find_compatible_versions_with_executable( ...@@ -1171,7 +1169,7 @@ def test_create_venv_does_not_try_to_find_compatible_versions_with_executable(
) )
with pytest.raises(NoCompatiblePythonVersionFound) as e: with pytest.raises(NoCompatiblePythonVersionFound) as e:
manager.create_venv(executable="3.8") manager.create_venv(executable=Path("python3.8"))
expected_message = ( expected_message = (
"The specified Python version (3.8.0) is not supported by the project (^4.8).\n" "The specified Python version (3.8.0) is not supported by the project (^4.8).\n"
...@@ -1190,7 +1188,7 @@ def test_create_venv_uses_patch_version_to_detect_compatibility( ...@@ -1190,7 +1188,7 @@ def test_create_venv_uses_patch_version_to_detect_compatibility(
mocker: MockerFixture, mocker: MockerFixture,
config_virtualenvs_path: Path, config_virtualenvs_path: Path,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -1231,7 +1229,7 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable( ...@@ -1231,7 +1229,7 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable(
mocker: MockerFixture, mocker: MockerFixture,
config_virtualenvs_path: Path, config_virtualenvs_path: Path,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -1249,12 +1247,12 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable( ...@@ -1249,12 +1247,12 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable(
"poetry.utils.env.EnvManager.build_venv", side_effect=lambda *args, **kwargs: "" "poetry.utils.env.EnvManager.build_venv", side_effect=lambda *args, **kwargs: ""
) )
manager.create_venv(executable=f"python{version.major}.{version.minor - 1}") manager.create_venv(executable=Path(f"python{version.major}.{version.minor - 1}"))
assert check_output.called assert check_output.called
m.assert_called_with( m.assert_called_with(
config_virtualenvs_path / f"{venv_name}-py{version.major}.{version.minor - 1}", config_virtualenvs_path / f"{venv_name}-py{version.major}.{version.minor - 1}",
executable=f"python{version.major}.{version.minor - 1}", executable=Path(f"python{version.major}.{version.minor - 1}"),
flags={ flags={
"always-copy": False, "always-copy": False,
"system-site-packages": False, "system-site-packages": False,
...@@ -1267,7 +1265,7 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable( ...@@ -1267,7 +1265,7 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable(
def test_create_venv_fails_if_current_python_version_is_not_supported( def test_create_venv_fails_if_current_python_version_is_not_supported(
manager: EnvManager, poetry: Poetry manager: EnvManager, poetry: Poetry
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -1298,7 +1296,7 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir( ...@@ -1298,7 +1296,7 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir(
config: Config, config: Config,
tmp_dir: str, tmp_dir: str,
mocker: MockerFixture, mocker: MockerFixture,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -1325,7 +1323,7 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir( ...@@ -1325,7 +1323,7 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir(
m.assert_called_with( m.assert_called_with(
poetry.file.parent / ".venv", poetry.file.parent / ".venv",
executable="/usr/bin/python3.7", executable=Path("/usr/bin/python3.7"),
flags={ flags={
"always-copy": False, "always-copy": False,
"system-site-packages": False, "system-site-packages": False,
...@@ -1339,7 +1337,7 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir( ...@@ -1339,7 +1337,7 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir(
assert not envs_file.exists() assert not envs_file.exists()
def test_system_env_has_correct_paths(): def test_system_env_has_correct_paths() -> None:
env = SystemEnv(Path(sys.prefix)) env = SystemEnv(Path(sys.prefix))
paths = env.paths paths = env.paths
...@@ -1355,7 +1353,7 @@ def test_system_env_has_correct_paths(): ...@@ -1355,7 +1353,7 @@ def test_system_env_has_correct_paths():
"enabled", "enabled",
[True, False], [True, False],
) )
def test_system_env_usersite(mocker: MockerFixture, enabled: bool): def test_system_env_usersite(mocker: MockerFixture, enabled: bool) -> None:
mocker.patch("site.check_enableusersite", return_value=enabled) mocker.patch("site.check_enableusersite", return_value=enabled)
env = SystemEnv(Path(sys.prefix)) env = SystemEnv(Path(sys.prefix))
assert (enabled and env.usersite is not None) or ( assert (enabled and env.usersite is not None) or (
...@@ -1363,7 +1361,7 @@ def test_system_env_usersite(mocker: MockerFixture, enabled: bool): ...@@ -1363,7 +1361,7 @@ def test_system_env_usersite(mocker: MockerFixture, enabled: bool):
) )
def test_venv_has_correct_paths(tmp_venv: VirtualEnv): def test_venv_has_correct_paths(tmp_venv: VirtualEnv) -> None:
paths = tmp_venv.paths paths = tmp_venv.paths
assert paths.get("purelib") is not None assert paths.get("purelib") is not None
...@@ -1377,7 +1375,7 @@ def test_venv_has_correct_paths(tmp_venv: VirtualEnv): ...@@ -1377,7 +1375,7 @@ def test_venv_has_correct_paths(tmp_venv: VirtualEnv):
) )
def test_env_system_packages(tmp_path: Path, poetry: Poetry): def test_env_system_packages(tmp_path: Path, poetry: Poetry) -> None:
venv_path = tmp_path / "venv" venv_path = tmp_path / "venv"
pyvenv_cfg = venv_path / "pyvenv.cfg" pyvenv_cfg = venv_path / "pyvenv.cfg"
...@@ -1401,7 +1399,7 @@ def test_env_system_packages(tmp_path: Path, poetry: Poetry): ...@@ -1401,7 +1399,7 @@ def test_env_system_packages(tmp_path: Path, poetry: Poetry):
) )
def test_env_no_pip( def test_env_no_pip(
tmp_path: Path, poetry: Poetry, flags: dict[str, bool], packages: set[str] tmp_path: Path, poetry: Poetry, flags: dict[str, bool], packages: set[str]
): ) -> None:
venv_path = tmp_path / "venv" venv_path = tmp_path / "venv"
EnvManager(poetry).build_venv(path=venv_path, flags=flags) EnvManager(poetry).build_venv(path=venv_path, flags=flags)
env = VirtualEnv(venv_path) env = VirtualEnv(venv_path)
...@@ -1416,9 +1414,9 @@ def test_env_no_pip( ...@@ -1416,9 +1414,9 @@ def test_env_no_pip(
assert installed_packages == packages assert installed_packages == packages
def test_env_finds_the_correct_executables(tmp_dir: str, manager: EnvManager): def test_env_finds_the_correct_executables(tmp_dir: str, manager: EnvManager) -> None:
venv_path = Path(tmp_dir) / "Virtual Env" venv_path = Path(tmp_dir) / "Virtual Env"
manager.build_venv(str(venv_path), with_pip=True) manager.build_venv(venv_path, with_pip=True)
venv = VirtualEnv(venv_path) venv = VirtualEnv(venv_path)
default_executable = expected_executable = f"python{'.exe' if WINDOWS else ''}" default_executable = expected_executable = f"python{'.exe' if WINDOWS else ''}"
...@@ -1448,14 +1446,12 @@ def test_env_finds_the_correct_executables(tmp_dir: str, manager: EnvManager): ...@@ -1448,14 +1446,12 @@ def test_env_finds_the_correct_executables(tmp_dir: str, manager: EnvManager):
def test_env_finds_the_correct_executables_for_generic_env( def test_env_finds_the_correct_executables_for_generic_env(
tmp_dir: str, manager: EnvManager tmp_dir: str, manager: EnvManager
): ) -> None:
venv_path = Path(tmp_dir) / "Virtual Env" venv_path = Path(tmp_dir) / "Virtual Env"
child_venv_path = Path(tmp_dir) / "Child Virtual Env" child_venv_path = Path(tmp_dir) / "Child Virtual Env"
manager.build_venv(str(venv_path), with_pip=True) manager.build_venv(venv_path, with_pip=True)
parent_venv = VirtualEnv(venv_path) parent_venv = VirtualEnv(venv_path)
manager.build_venv( manager.build_venv(child_venv_path, executable=parent_venv.python, with_pip=True)
str(child_venv_path), executable=parent_venv.python, with_pip=True
)
venv = GenericEnv(parent_venv.path, child_env=VirtualEnv(child_venv_path)) venv = GenericEnv(parent_venv.path, child_env=VirtualEnv(child_venv_path))
expected_executable = ( expected_executable = (
...@@ -1475,14 +1471,12 @@ def test_env_finds_the_correct_executables_for_generic_env( ...@@ -1475,14 +1471,12 @@ def test_env_finds_the_correct_executables_for_generic_env(
def test_env_finds_fallback_executables_for_generic_env( def test_env_finds_fallback_executables_for_generic_env(
tmp_dir: str, manager: EnvManager tmp_dir: str, manager: EnvManager
): ) -> None:
venv_path = Path(tmp_dir) / "Virtual Env" venv_path = Path(tmp_dir) / "Virtual Env"
child_venv_path = Path(tmp_dir) / "Child Virtual Env" child_venv_path = Path(tmp_dir) / "Child Virtual Env"
manager.build_venv(str(venv_path), with_pip=True) manager.build_venv(venv_path, with_pip=True)
parent_venv = VirtualEnv(venv_path) parent_venv = VirtualEnv(venv_path)
manager.build_venv( manager.build_venv(child_venv_path, executable=parent_venv.python, with_pip=True)
str(child_venv_path), executable=parent_venv.python, with_pip=True
)
venv = GenericEnv(parent_venv.path, child_env=VirtualEnv(child_venv_path)) venv = GenericEnv(parent_venv.path, child_env=VirtualEnv(child_venv_path))
default_executable = f"python{'.exe' if WINDOWS else ''}" default_executable = f"python{'.exe' if WINDOWS else ''}"
...@@ -1544,7 +1538,7 @@ def test_create_venv_accepts_fallback_version_w_nonzero_patchlevel( ...@@ -1544,7 +1538,7 @@ def test_create_venv_accepts_fallback_version_w_nonzero_patchlevel(
mocker: MockerFixture, mocker: MockerFixture,
config_virtualenvs_path: Path, config_virtualenvs_path: Path,
venv_name: str, venv_name: str,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -1572,7 +1566,7 @@ def test_create_venv_accepts_fallback_version_w_nonzero_patchlevel( ...@@ -1572,7 +1566,7 @@ def test_create_venv_accepts_fallback_version_w_nonzero_patchlevel(
assert check_output.called assert check_output.called
m.assert_called_with( m.assert_called_with(
config_virtualenvs_path / f"{venv_name}-py3.5", config_virtualenvs_path / f"{venv_name}-py3.5",
executable="/usr/bin/python3.5", executable=Path("/usr/bin/python3.5"),
flags={ flags={
"always-copy": False, "always-copy": False,
"system-site-packages": False, "system-site-packages": False,
...@@ -1586,7 +1580,7 @@ def test_create_venv_accepts_fallback_version_w_nonzero_patchlevel( ...@@ -1586,7 +1580,7 @@ def test_create_venv_accepts_fallback_version_w_nonzero_patchlevel(
def test_generate_env_name_ignores_case_for_case_insensitive_fs( def test_generate_env_name_ignores_case_for_case_insensitive_fs(
poetry: Poetry, poetry: Poetry,
tmp_dir: str, tmp_dir: str,
): ) -> None:
venv_name1 = EnvManager.generate_env_name(poetry.package.name, "MyDiR") venv_name1 = EnvManager.generate_env_name(poetry.package.name, "MyDiR")
venv_name2 = EnvManager.generate_env_name(poetry.package.name, "mYdIr") venv_name2 = EnvManager.generate_env_name(poetry.package.name, "mYdIr")
if sys.platform == "win32": if sys.platform == "win32":
...@@ -1595,7 +1589,7 @@ def test_generate_env_name_ignores_case_for_case_insensitive_fs( ...@@ -1595,7 +1589,7 @@ def test_generate_env_name_ignores_case_for_case_insensitive_fs(
assert venv_name1 != venv_name2 assert venv_name1 != venv_name2
def test_generate_env_name_uses_real_path(tmp_dir: str, mocker: MockerFixture): def test_generate_env_name_uses_real_path(tmp_dir: str, mocker: MockerFixture) -> None:
mocker.patch("os.path.realpath", return_value="the_real_dir") mocker.patch("os.path.realpath", return_value="the_real_dir")
venv_name1 = EnvManager.generate_env_name("simple-project", "the_real_dir") venv_name1 = EnvManager.generate_env_name("simple-project", "the_real_dir")
venv_name2 = EnvManager.generate_env_name("simple-project", "linked_dir") venv_name2 = EnvManager.generate_env_name("simple-project", "linked_dir")
...@@ -1613,7 +1607,7 @@ def extended_without_setup_poetry() -> Poetry: ...@@ -1613,7 +1607,7 @@ def extended_without_setup_poetry() -> Poetry:
def test_build_environment_called_build_script_specified( def test_build_environment_called_build_script_specified(
mocker: MockerFixture, extended_without_setup_poetry: Poetry, tmp_dir: str mocker: MockerFixture, extended_without_setup_poetry: Poetry, tmp_dir: str
): ) -> None:
project_env = MockEnv(path=Path(tmp_dir) / "project") project_env = MockEnv(path=Path(tmp_dir) / "project")
ephemeral_env = MockEnv(path=Path(tmp_dir) / "ephemeral") ephemeral_env = MockEnv(path=Path(tmp_dir) / "ephemeral")
...@@ -1625,8 +1619,8 @@ def test_build_environment_called_build_script_specified( ...@@ -1625,8 +1619,8 @@ def test_build_environment_called_build_script_specified(
assert env == ephemeral_env assert env == ephemeral_env
assert env.executed == [ assert env.executed == [
[ [
sys.executable, str(sys.executable),
env.pip_embedded, str(env.pip_embedded),
"install", "install",
"--disable-pip-version-check", "--disable-pip-version-check",
"--ignore-installed", "--ignore-installed",
...@@ -1638,7 +1632,7 @@ def test_build_environment_called_build_script_specified( ...@@ -1638,7 +1632,7 @@ def test_build_environment_called_build_script_specified(
def test_build_environment_not_called_without_build_script_specified( def test_build_environment_not_called_without_build_script_specified(
mocker: MockerFixture, poetry: Poetry, tmp_dir: str mocker: MockerFixture, poetry: Poetry, tmp_dir: str
): ) -> None:
project_env = MockEnv(path=Path(tmp_dir) / "project") project_env = MockEnv(path=Path(tmp_dir) / "project")
ephemeral_env = MockEnv(path=Path(tmp_dir) / "ephemeral") ephemeral_env = MockEnv(path=Path(tmp_dir) / "ephemeral")
...@@ -1656,7 +1650,7 @@ def test_create_venv_project_name_empty_sets_correct_prompt( ...@@ -1656,7 +1650,7 @@ def test_create_venv_project_name_empty_sets_correct_prompt(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
config_virtualenvs_path: Path, config_virtualenvs_path: Path,
): ) -> None:
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -1680,7 +1674,7 @@ def test_create_venv_project_name_empty_sets_correct_prompt( ...@@ -1680,7 +1674,7 @@ def test_create_venv_project_name_empty_sets_correct_prompt(
m.assert_called_with( m.assert_called_with(
config_virtualenvs_path / f"{venv_name}-py3.7", config_virtualenvs_path / f"{venv_name}-py3.7",
executable="/usr/bin/python3", executable=Path("/usr/bin/python3"),
flags={ flags={
"always-copy": False, "always-copy": False,
"system-site-packages": False, "system-site-packages": False,
...@@ -1691,7 +1685,9 @@ def test_create_venv_project_name_empty_sets_correct_prompt( ...@@ -1691,7 +1685,9 @@ def test_create_venv_project_name_empty_sets_correct_prompt(
) )
def test_fallback_on_detect_active_python(poetry: Poetry, mocker: MockerFixture): def test_fallback_on_detect_active_python(
poetry: Poetry, mocker: MockerFixture
) -> None:
m = mocker.patch( m = mocker.patch(
"subprocess.check_output", "subprocess.check_output",
side_effect=subprocess.CalledProcessError(1, "some command"), side_effect=subprocess.CalledProcessError(1, "some command"),
......
from __future__ import annotations from __future__ import annotations
import os from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import pytest import pytest
...@@ -16,16 +15,16 @@ if TYPE_CHECKING: ...@@ -16,16 +15,16 @@ if TYPE_CHECKING:
@pytest.fixture() @pytest.fixture()
def setup() -> Callable[[str], str]: def setup() -> Callable[[str], Path]:
def _setup(name: str) -> str: def _setup(name: str) -> Path:
return os.path.join(os.path.dirname(__file__), "fixtures", "setups", name) return Path(__file__).parent / "fixtures" / "setups" / name
return _setup return _setup
def test_setup_reader_read_first_level_setup_call_with_direct_types( def test_setup_reader_read_first_level_setup_call_with_direct_types(
setup: Callable[[str], str] setup: Callable[[str], Path]
): ) -> None:
result = SetupReader.read_from_directory(setup("flask")) result = SetupReader.read_from_directory(setup("flask"))
expected_name = "Flask" expected_name = "Flask"
...@@ -58,8 +57,8 @@ def test_setup_reader_read_first_level_setup_call_with_direct_types( ...@@ -58,8 +57,8 @@ def test_setup_reader_read_first_level_setup_call_with_direct_types(
def test_setup_reader_read_first_level_setup_call_with_variables( def test_setup_reader_read_first_level_setup_call_with_variables(
setup: Callable[[str], str] setup: Callable[[str], Path]
): ) -> None:
result = SetupReader.read_from_directory(setup("requests")) result = SetupReader.read_from_directory(setup("requests"))
expected_name = None expected_name = None
...@@ -85,8 +84,8 @@ def test_setup_reader_read_first_level_setup_call_with_variables( ...@@ -85,8 +84,8 @@ def test_setup_reader_read_first_level_setup_call_with_variables(
def test_setup_reader_read_sub_level_setup_call_with_direct_types( def test_setup_reader_read_sub_level_setup_call_with_direct_types(
setup: Callable[[str], str] setup: Callable[[str], Path]
): ) -> None:
result = SetupReader.read_from_directory(setup("sqlalchemy")) result = SetupReader.read_from_directory(setup("sqlalchemy"))
expected_name = "SQLAlchemy" expected_name = "SQLAlchemy"
...@@ -110,7 +109,7 @@ def test_setup_reader_read_sub_level_setup_call_with_direct_types( ...@@ -110,7 +109,7 @@ def test_setup_reader_read_sub_level_setup_call_with_direct_types(
assert result["python_requires"] is None assert result["python_requires"] is None
def test_setup_reader_read_setup_cfg(setup: Callable[[str], str]): def test_setup_reader_read_setup_cfg(setup: Callable[[str], Path]) -> None:
result = SetupReader.read_from_directory(setup("with-setup-cfg")) result = SetupReader.read_from_directory(setup("with-setup-cfg"))
expected_name = "with-setup-cfg" expected_name = "with-setup-cfg"
...@@ -129,12 +128,12 @@ def test_setup_reader_read_setup_cfg(setup: Callable[[str], str]): ...@@ -129,12 +128,12 @@ def test_setup_reader_read_setup_cfg(setup: Callable[[str], str]):
assert result["python_requires"] == expected_python_requires assert result["python_requires"] == expected_python_requires
def test_setup_reader_read_setup_cfg_with_attr(setup: Callable[[str], str]): def test_setup_reader_read_setup_cfg_with_attr(setup: Callable[[str], Path]) -> None:
with pytest.raises(InvalidVersion): with pytest.raises(InvalidVersion):
SetupReader.read_from_directory(setup("with-setup-cfg-attr")) SetupReader.read_from_directory(setup("with-setup-cfg-attr"))
def test_setup_reader_read_setup_kwargs(setup: Callable[[str], str]): def test_setup_reader_read_setup_kwargs(setup: Callable[[str], Path]) -> None:
result = SetupReader.read_from_directory(setup("pendulum")) result = SetupReader.read_from_directory(setup("pendulum"))
expected_name = "pendulum" expected_name = "pendulum"
...@@ -150,7 +149,7 @@ def test_setup_reader_read_setup_kwargs(setup: Callable[[str], str]): ...@@ -150,7 +149,7 @@ def test_setup_reader_read_setup_kwargs(setup: Callable[[str], str]):
assert result["python_requires"] == expected_python_requires assert result["python_requires"] == expected_python_requires
def test_setup_reader_read_setup_call_in_main(setup: Callable[[str], str]): def test_setup_reader_read_setup_call_in_main(setup: Callable[[str], Path]) -> None:
result = SetupReader.read_from_directory(setup("pyyaml")) result = SetupReader.read_from_directory(setup("pyyaml"))
expected_name = "PyYAML" expected_name = "PyYAML"
...@@ -166,7 +165,9 @@ def test_setup_reader_read_setup_call_in_main(setup: Callable[[str], str]): ...@@ -166,7 +165,9 @@ def test_setup_reader_read_setup_call_in_main(setup: Callable[[str], str]):
assert result["python_requires"] == expected_python_requires assert result["python_requires"] == expected_python_requires
def test_setup_reader_read_extras_require_with_variables(setup: Callable[[str], str]): def test_setup_reader_read_extras_require_with_variables(
setup: Callable[[str], Path]
) -> None:
result = SetupReader.read_from_directory(setup("extras_require_with_vars")) result = SetupReader.read_from_directory(setup("extras_require_with_vars"))
expected_name = "extras_require_with_vars" expected_name = "extras_require_with_vars"
...@@ -182,7 +183,7 @@ def test_setup_reader_read_extras_require_with_variables(setup: Callable[[str], ...@@ -182,7 +183,7 @@ def test_setup_reader_read_extras_require_with_variables(setup: Callable[[str],
assert result["python_requires"] == expected_python_requires assert result["python_requires"] == expected_python_requires
def test_setup_reader_setuptools(setup: Callable[[str], str]): def test_setup_reader_setuptools(setup: Callable[[str], Path]) -> None:
result = SetupReader.read_from_directory(setup("setuptools_setup")) result = SetupReader.read_from_directory(setup("setuptools_setup"))
expected_name = "my_package" expected_name = "my_package"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment