Commit 9e31f7a2 by Randy Döring Committed by GitHub

Use flake8 type checking (#4787)

* Use flake8-type-checking

* Fixes for flake8-type-checking violations

* Set enable-extensions before ignores and excludes

* Remove noqa duplicate

* Use new flake8-type-checking version with type-checking-exempt-modules feature for imports of typing and typing-extensions so that noqa comments are not required anymore

* Ignore TC002 in __init__ files

* Remove noqa from pyi files because they are not checked anyway
parent 6ff23efb
...@@ -3,6 +3,8 @@ min_python_version = 3.6.0 ...@@ -3,6 +3,8 @@ min_python_version = 3.6.0
max-line-length = 88 max-line-length = 88
ban-relative-imports = true ban-relative-imports = true
inline-quotes = double inline-quotes = double
enable-extensions = TC, TC2
type-checking-exempt-modules = typing, typing-extensions
extend-ignore = extend-ignore =
# E501: Line too long (FIXME: long string constants) # E501: Line too long (FIXME: long string constants)
E501, E501,
...@@ -10,7 +12,8 @@ extend-ignore = ...@@ -10,7 +12,8 @@ extend-ignore =
E203, E203,
per-file-ignores = per-file-ignores =
# F401: Module imported by unused (non-implicit modules) # F401: Module imported by unused (non-implicit modules)
__init__.py:F401, # TC002: Move third-party import '...' into a type-checking block
__init__.py:F401,TC002,
extend-exclude = extend-exclude =
# Frozen and not subject to change in this repo: # Frozen and not subject to change in this repo:
get-poetry.py, get-poetry.py,
......
...@@ -37,6 +37,7 @@ repos: ...@@ -37,6 +37,7 @@ repos:
- flake8-no-pep420==1.2.0 - flake8-no-pep420==1.2.0
- flake8-quotes==3.3.1 - flake8-quotes==3.3.1
- flake8-tidy-imports==4.5.0 - flake8-tidy-imports==4.5.0
- flake8-type-checking==1.1.0
- flake8-typing-imports==1.11.0 - flake8-typing-imports==1.11.0
- pep8-naming==0.12.1 - pep8-naming==0.12.1
......
...@@ -3,16 +3,20 @@ import re ...@@ -3,16 +3,20 @@ import re
from copy import deepcopy from copy import deepcopy
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any from typing import Any
from typing import Callable from typing import Callable
from typing import Dict from typing import Dict
from typing import Optional from typing import Optional
from poetry.config.config_source import ConfigSource
from poetry.config.dict_config_source import DictConfigSource from poetry.config.dict_config_source import DictConfigSource
from poetry.locations import CACHE_DIR from poetry.locations import CACHE_DIR
if TYPE_CHECKING:
from poetry.config.config_source import ConfigSource
def boolean_validator(val: str) -> bool: def boolean_validator(val: str) -> bool:
return val in {"true", "false", "1", "0"} return val in {"true", "false", "1", "0"}
...@@ -41,27 +45,27 @@ class Config: ...@@ -41,27 +45,27 @@ class Config:
self._config = deepcopy(self.default_config) self._config = deepcopy(self.default_config)
self._use_environment = use_environment self._use_environment = use_environment
self._base_dir = base_dir self._base_dir = base_dir
self._config_source: ConfigSource = DictConfigSource() self._config_source: "ConfigSource" = DictConfigSource()
self._auth_config_source: ConfigSource = DictConfigSource() self._auth_config_source: "ConfigSource" = DictConfigSource()
@property @property
def config(self) -> Dict: def config(self) -> Dict:
return self._config return self._config
@property @property
def config_source(self) -> ConfigSource: def config_source(self) -> "ConfigSource":
return self._config_source return self._config_source
@property @property
def auth_config_source(self) -> ConfigSource: def auth_config_source(self) -> "ConfigSource":
return self._auth_config_source return self._auth_config_source
def set_config_source(self, config_source: ConfigSource) -> "Config": def set_config_source(self, config_source: "ConfigSource") -> "Config":
self._config_source = config_source self._config_source = config_source
return self return self
def set_auth_config_source(self, config_source: ConfigSource) -> "Config": def set_auth_config_source(self, config_source: "ConfigSource") -> "Config":
self._auth_config_source = config_source self._auth_config_source = config_source
return self return self
......
...@@ -10,15 +10,11 @@ from typing import Type ...@@ -10,15 +10,11 @@ from typing import Type
from typing import cast from typing import cast
from cleo.application import Application as BaseApplication from cleo.application import Application as BaseApplication
from cleo.events.console_command_event import ConsoleCommandEvent
from cleo.events.console_events import COMMAND from cleo.events.console_events import COMMAND
from cleo.events.event_dispatcher import EventDispatcher from cleo.events.event_dispatcher import EventDispatcher
from cleo.exceptions import CleoException from cleo.exceptions import CleoException
from cleo.formatters.style import Style from cleo.formatters.style import Style
from cleo.io.inputs.argv_input import ArgvInput from cleo.io.inputs.argv_input import ArgvInput
from cleo.io.inputs.input import Input
from cleo.io.io import IO
from cleo.io.outputs.output import Output
from poetry.__version__ import __version__ from poetry.__version__ import __version__
from poetry.console.command_loader import CommandLoader from poetry.console.command_loader import CommandLoader
...@@ -27,10 +23,18 @@ from poetry.core.utils._compat import PY37 ...@@ -27,10 +23,18 @@ from poetry.core.utils._compat import PY37
if TYPE_CHECKING: if TYPE_CHECKING:
from cleo.events.console_command_event import ConsoleCommandEvent
from cleo.io.inputs.definition import Definition
from cleo.io.inputs.input import Input
from cleo.io.io import IO
from cleo.io.outputs.output import Output
from crashtest.solution_providers.solution_provider_repository import ( from crashtest.solution_providers.solution_provider_repository import (
SolutionProviderRepository, SolutionProviderRepository,
) )
from poetry.console.commands.installer_command import InstallerCommand
from poetry.poetry import Poetry
def load_command(name: str) -> Callable: def load_command(name: str) -> Callable:
def _load() -> Type[Command]: def _load() -> Type[Command]:
...@@ -88,19 +92,13 @@ COMMANDS = [ ...@@ -88,19 +92,13 @@ COMMANDS = [
"source show", "source show",
] ]
if TYPE_CHECKING:
from cleo.io.inputs.definition import Definition
from poetry.console.commands.installer_command import InstallerCommand
from poetry.poetry import Poetry
class Application(BaseApplication): class Application(BaseApplication):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__("poetry", __version__) super().__init__("poetry", __version__)
self._poetry = None self._poetry = None
self._io: Optional[IO] = None self._io: Optional["IO"] = None
self._disable_plugins = False self._disable_plugins = False
self._plugins_loaded = False self._plugins_loaded = False
...@@ -137,10 +135,10 @@ class Application(BaseApplication): ...@@ -137,10 +135,10 @@ class Application(BaseApplication):
def create_io( def create_io(
self, self,
input: Optional[Input] = None, input: Optional["Input"] = None,
output: Optional[Output] = None, output: Optional["Output"] = None,
error_output: Optional[Output] = None, error_output: Optional["Output"] = None,
) -> IO: ) -> "IO":
io = super().create_io(input, output, error_output) io = super().create_io(input, output, error_output)
# Remove when support for Python 3.6 is removed # Remove when support for Python 3.6 is removed
...@@ -179,21 +177,21 @@ class Application(BaseApplication): ...@@ -179,21 +177,21 @@ class Application(BaseApplication):
return io return io
def render_error(self, error: Exception, io: IO) -> None: def render_error(self, error: Exception, io: "IO") -> None:
# We set the solution provider repository here to load providers # We set the solution provider repository here to load providers
# only when an error occurs # only when an error occurs
self.set_solution_provider_repository(self._get_solution_provider_repository()) self.set_solution_provider_repository(self._get_solution_provider_repository())
super().render_error(error, io) super().render_error(error, io)
def _run(self, io: IO) -> int: def _run(self, io: "IO") -> int:
self._disable_plugins = io.input.parameter_option("--no-plugins") self._disable_plugins = io.input.parameter_option("--no-plugins")
self._load_plugins(io) self._load_plugins(io)
return super()._run(io) return super()._run(io)
def _configure_io(self, io: IO) -> None: def _configure_io(self, io: "IO") -> None:
# We need to check if the command being run # We need to check if the command being run
# is the "run" command. # is the "run" command.
definition = self.definition definition = self.definition
...@@ -234,7 +232,7 @@ class Application(BaseApplication): ...@@ -234,7 +232,7 @@ class Application(BaseApplication):
return super()._configure_io(io) return super()._configure_io(io)
def register_command_loggers( def register_command_loggers(
self, event: ConsoleCommandEvent, event_name: str, _: Any self, event: "ConsoleCommandEvent", event_name: str, _: Any
) -> None: ) -> None:
from poetry.console.logging.io_formatter import IOFormatter from poetry.console.logging.io_formatter import IOFormatter
from poetry.console.logging.io_handler import IOHandler from poetry.console.logging.io_handler import IOHandler
...@@ -275,7 +273,7 @@ class Application(BaseApplication): ...@@ -275,7 +273,7 @@ class Application(BaseApplication):
logger.setLevel(level) logger.setLevel(level)
def configure_env( def configure_env(
self, event: ConsoleCommandEvent, event_name: str, _: Any self, event: "ConsoleCommandEvent", event_name: str, _: Any
) -> None: ) -> None:
from poetry.console.commands.env_command import EnvCommand from poetry.console.commands.env_command import EnvCommand
...@@ -300,11 +298,11 @@ class Application(BaseApplication): ...@@ -300,11 +298,11 @@ class Application(BaseApplication):
command.set_env(env) command.set_env(env)
def configure_installer( def configure_installer(
self, event: ConsoleCommandEvent, event_name: str, _: Any self, event: "ConsoleCommandEvent", event_name: str, _: Any
) -> None: ) -> None:
from poetry.console.commands.installer_command import InstallerCommand from poetry.console.commands.installer_command import InstallerCommand
command: InstallerCommand = cast(InstallerCommand, event.command) command: "InstallerCommand" = cast(InstallerCommand, event.command)
if not isinstance(command, InstallerCommand): if not isinstance(command, InstallerCommand):
return return
...@@ -330,7 +328,7 @@ class Application(BaseApplication): ...@@ -330,7 +328,7 @@ class Application(BaseApplication):
installer.use_executor(poetry.config.get("experimental.new-installer", False)) installer.use_executor(poetry.config.get("experimental.new-installer", False))
command.set_installer(installer) command.set_installer(installer)
def _load_plugins(self, io: IO) -> None: def _load_plugins(self, io: "IO") -> None:
if self._plugins_loaded: if self._plugins_loaded:
return return
......
...@@ -93,7 +93,7 @@ class DebugResolveCommand(InitCommand): ...@@ -93,7 +93,7 @@ class DebugResolveCommand(InitCommand):
self.line("") self.line("")
if self.option("tree"): if self.option("tree"):
show_command: ShowCommand = self.application.find("show") show_command: "ShowCommand" = self.application.find("show")
show_command.init_styles(self.io) show_command.init_styles(self.io)
packages = [op.package for op in ops] packages = [op.package for op in ops]
......
from typing import TYPE_CHECKING
from typing import Optional from typing import Optional
from poetry.console.commands.command import Command from poetry.console.commands.command import Command
from poetry.utils.env import Env
if TYPE_CHECKING:
from poetry.utils.env import Env
class EnvCommand(Command): class EnvCommand(Command):
...@@ -11,8 +15,8 @@ class EnvCommand(Command): ...@@ -11,8 +15,8 @@ class EnvCommand(Command):
super().__init__() super().__init__()
@property @property
def env(self) -> Optional[Env]: def env(self) -> Optional["Env"]:
return self._env return self._env
def set_env(self, env: Env) -> None: def set_env(self, env: "Env") -> None:
self._env = env self._env = env
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Optional
from poetry.console.commands.env_command import EnvCommand from poetry.console.commands.env_command import EnvCommand
if TYPE_CHECKING: if TYPE_CHECKING:
from poetry.installation.installer import Installer from poetry.installation.installer import Installer
from poetry.installation.installer import Optional
class InstallerCommand(EnvCommand): class InstallerCommand(EnvCommand):
......
import os import os
from typing import TYPE_CHECKING
from typing import Dict from typing import Dict
from typing import List from typing import List
from typing import cast from typing import cast
...@@ -8,12 +7,9 @@ from typing import cast ...@@ -8,12 +7,9 @@ from typing import cast
from cleo.helpers import argument from cleo.helpers import argument
from cleo.helpers import option from cleo.helpers import option
from poetry.console.application import Application
from poetry.console.commands.init import InitCommand from poetry.console.commands.init import InitCommand
from poetry.console.commands.update import UpdateCommand
if TYPE_CHECKING:
from poetry.console.application import Application
from poetry.console.commands.update import UpdateCommand
class PluginAddCommand(InitCommand): class PluginAddCommand(InitCommand):
...@@ -153,10 +149,8 @@ You can specify a package in the following forms: ...@@ -153,10 +149,8 @@ You can specify a package in the following forms:
# From this point forward, all the logic will be deferred to # From this point forward, all the logic will be deferred to
# the update command, by using the previously created `pyproject.toml` # the update command, by using the previously created `pyproject.toml`
# file. # file.
application = cast("Application", self.application) application = cast(Application, self.application)
update_command: "UpdateCommand" = cast( update_command: UpdateCommand = cast(UpdateCommand, application.find("update"))
"UpdateCommand", application.find("update")
)
# We won't go through the event dispatching done by the application # We won't go through the event dispatching done by the application
# so we need to configure the command manually # so we need to configure the command manually
update_command.set_poetry(Factory().create_poetry(env_dir)) update_command.set_poetry(Factory().create_poetry(env_dir))
......
import os import os
from typing import TYPE_CHECKING
from typing import cast from typing import cast
from cleo.helpers import argument from cleo.helpers import argument
from cleo.helpers import option from cleo.helpers import option
from poetry.console.application import Application
from poetry.console.commands.command import Command from poetry.console.commands.command import Command
from poetry.console.commands.remove import RemoveCommand
if TYPE_CHECKING:
from poetry.console.application import Application
from poetry.console.commands.remove import RemoveCommand
class PluginRemoveCommand(Command): class PluginRemoveCommand(Command):
...@@ -50,10 +46,8 @@ class PluginRemoveCommand(Command): ...@@ -50,10 +46,8 @@ class PluginRemoveCommand(Command):
# From this point forward, all the logic will be deferred to # From this point forward, all the logic will be deferred to
# the remove command, by using the global `pyproject.toml` file. # the remove command, by using the global `pyproject.toml` file.
application = cast("Application", self.application) application = cast(Application, self.application)
remove_command: "RemoveCommand" = cast( remove_command: RemoveCommand = cast(RemoveCommand, application.find("remove"))
"RemoveCommand", application.find("remove")
)
# We won't go through the event dispatching done by the application # We won't go through the event dispatching done by the application
# so we need to configure the command manually # so we need to configure the command manually
remove_command.set_poetry(Factory().create_poetry(env_dir)) remove_command.set_poetry(Factory().create_poetry(env_dir))
......
from typing import TYPE_CHECKING
from typing import Optional from typing import Optional
from cleo.helpers import argument from cleo.helpers import argument
...@@ -6,12 +7,15 @@ from cleo.io.null_io import NullIO ...@@ -6,12 +7,15 @@ from cleo.io.null_io import NullIO
from tomlkit import nl from tomlkit import nl
from tomlkit import table from tomlkit import table
from tomlkit.items import AoT from tomlkit.items import AoT
from tomlkit.items import Table
from poetry.config.source import Source from poetry.config.source import Source
from poetry.console.commands.command import Command from poetry.console.commands.command import Command
if TYPE_CHECKING:
from tomlkit.items import Table
class SourceAddCommand(Command): class SourceAddCommand(Command):
name = "source add" name = "source add"
...@@ -37,8 +41,8 @@ class SourceAddCommand(Command): ...@@ -37,8 +41,8 @@ class SourceAddCommand(Command):
] ]
@staticmethod @staticmethod
def source_to_table(source: "Source") -> Table: def source_to_table(source: Source) -> "Table":
source_table: Table = table() source_table: "Table" = table()
for key, value in source.to_dict().items(): for key, value in source.to_dict().items():
source_table.add(key, value) source_table.add(key, value)
source_table.add(nl()) source_table.add(nl())
......
from typing import TYPE_CHECKING
from typing import Optional from typing import Optional
from cleo.helpers import argument from cleo.helpers import argument
from tomlkit import nl from tomlkit import nl
from tomlkit import table from tomlkit import table
from tomlkit.items import AoT from tomlkit.items import AoT
from tomlkit.items import Table
from poetry.config.source import Source
from poetry.console.commands.command import Command from poetry.console.commands.command import Command
if TYPE_CHECKING:
from tomlkit.items import Table
from poetry.config.source import Source
class SourceRemoveCommand(Command): class SourceRemoveCommand(Command):
name = "source remove" name = "source remove"
...@@ -23,8 +28,8 @@ class SourceRemoveCommand(Command): ...@@ -23,8 +28,8 @@ class SourceRemoveCommand(Command):
] ]
@staticmethod @staticmethod
def source_to_table(source: Source) -> Table: def source_to_table(source: "Source") -> "Table":
source_table: Table = table() source_table: "Table" = table()
for key, value in source.to_dict().items(): for key, value in source.to_dict().items():
source_table.add(key, value) source_table.add(key, value)
source_table.add(nl()) source_table.add(nl())
......
from typing import TYPE_CHECKING
from typing import List from typing import List
from typing import Optional from typing import Optional
from typing import Union from typing import Union
from cleo.io.inputs.argv_input import ArgvInput from cleo.io.inputs.argv_input import ArgvInput
from cleo.io.inputs.definition import Definition
if TYPE_CHECKING:
from cleo.io.inputs.definition import Definition
class RunArgvInput(ArgvInput): class RunArgvInput(ArgvInput):
def __init__( def __init__(
self, argv: Optional[List[str]] = None, definition: Optional[Definition] = None self,
argv: Optional[List[str]] = None,
definition: Optional["Definition"] = None,
) -> None: ) -> None:
super().__init__(argv, definition=definition) super().__init__(argv, definition=definition)
......
import logging from typing import TYPE_CHECKING
if TYPE_CHECKING:
import logging
class Formatter: class Formatter:
def format(self, record: logging.LogRecord) -> str: def format(self, record: "logging.LogRecord") -> str:
raise NotImplementedError() raise NotImplementedError()
...@@ -4,7 +4,6 @@ from typing import Dict ...@@ -4,7 +4,6 @@ from typing import Dict
from typing import List from typing import List
from typing import Optional from typing import Optional
from cleo.io.io import IO
from cleo.io.null_io import NullIO from cleo.io.null_io import NullIO
from poetry.config.config import Config from poetry.config.config import Config
...@@ -19,6 +18,8 @@ from poetry.poetry import Poetry ...@@ -19,6 +18,8 @@ from poetry.poetry import Poetry
if TYPE_CHECKING: if TYPE_CHECKING:
from cleo.io.io import IO
from poetry.repositories.legacy_repository import LegacyRepository from poetry.repositories.legacy_repository import LegacyRepository
...@@ -30,7 +31,7 @@ class Factory(BaseFactory): ...@@ -30,7 +31,7 @@ class Factory(BaseFactory):
def create_poetry( def create_poetry(
self, self,
cwd: Optional[Path] = None, cwd: Optional[Path] = None,
io: Optional[IO] = None, io: Optional["IO"] = None,
disable_plugins: bool = False, disable_plugins: bool = False,
) -> Poetry: ) -> Poetry:
if io is None: if io is None:
...@@ -90,7 +91,7 @@ class Factory(BaseFactory): ...@@ -90,7 +91,7 @@ class Factory(BaseFactory):
return ProjectPackage(name, version, version) return ProjectPackage(name, version, version)
@classmethod @classmethod
def create_config(cls, io: Optional[IO] = None) -> Config: def create_config(cls, io: Optional["IO"] = None) -> Config:
if io is None: if io is None:
io = NullIO() io = NullIO()
...@@ -127,7 +128,7 @@ class Factory(BaseFactory): ...@@ -127,7 +128,7 @@ class Factory(BaseFactory):
@classmethod @classmethod
def configure_sources( def configure_sources(
cls, poetry: "Poetry", sources: List[Dict[str, str]], config: "Config", io: "IO" cls, poetry: Poetry, sources: List[Dict[str, str]], config: Config, io: "IO"
) -> None: ) -> None:
for source in sources: for source in sources:
repository = cls.create_legacy_repository(source, config) repository = cls.create_legacy_repository(source, config)
...@@ -185,9 +186,7 @@ class Factory(BaseFactory): ...@@ -185,9 +186,7 @@ class Factory(BaseFactory):
) )
@classmethod @classmethod
def create_pyproject_from_package( def create_pyproject_from_package(cls, package: ProjectPackage, path: Path) -> None:
cls, package: "ProjectPackage", path: "Path"
) -> None:
import tomlkit import tomlkit
from poetry.layouts.layout import POETRY_DEFAULT from poetry.layouts.layout import POETRY_DEFAULT
......
...@@ -5,6 +5,7 @@ import tarfile ...@@ -5,6 +5,7 @@ import tarfile
import zipfile import zipfile
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING
from typing import Dict from typing import Dict
from typing import Iterator from typing import Iterator
from typing import List from typing import List
...@@ -16,7 +17,6 @@ import pkginfo ...@@ -16,7 +17,6 @@ import pkginfo
from poetry.core.factory import Factory from poetry.core.factory import Factory
from poetry.core.packages.dependency import Dependency from poetry.core.packages.dependency import Dependency
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
from poetry.core.packages.project_package import ProjectPackage
from poetry.core.pyproject.toml import PyProjectTOML from poetry.core.pyproject.toml import PyProjectTOML
from poetry.core.utils.helpers import parse_requires from poetry.core.utils.helpers import parse_requires
from poetry.core.utils.helpers import temporary_directory from poetry.core.utils.helpers import temporary_directory
...@@ -26,6 +26,10 @@ from poetry.utils.env import ephemeral_environment ...@@ -26,6 +26,10 @@ from poetry.utils.env import ephemeral_environment
from poetry.utils.setup_reader import SetupReader from poetry.utils.setup_reader import SetupReader
if TYPE_CHECKING:
from poetry.core.packages.project_package import ProjectPackage
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
PEP517_META_BUILD = """\ PEP517_META_BUILD = """\
...@@ -426,7 +430,7 @@ class PackageInfo: ...@@ -426,7 +430,7 @@ class PackageInfo:
) )
@staticmethod @staticmethod
def _get_poetry_package(path: Path) -> Optional[ProjectPackage]: def _get_poetry_package(path: Path) -> Optional["ProjectPackage"]:
# Note: we ignore any setup.py file at this step # Note: we ignore any setup.py file at this step
# TODO: add support for handling non-poetry PEP-517 builds # TODO: add support for handling non-poetry PEP-517 builds
if PyProjectTOML(path.joinpath("pyproject.toml")).is_poetry_project(): if PyProjectTOML(path.joinpath("pyproject.toml")).is_poetry_project():
......
...@@ -7,14 +7,14 @@ from typing import Tuple ...@@ -7,14 +7,14 @@ from typing import Tuple
from packaging.tags import Tag from packaging.tags import Tag
from poetry.core.packages.package import Package
from poetry.core.packages.utils.link import Link
from poetry.utils.env import Env
from poetry.utils.patterns import wheel_file_re from poetry.utils.patterns import wheel_file_re
if TYPE_CHECKING: if TYPE_CHECKING:
from poetry.core.packages.package import Package
from poetry.core.packages.utils.link import Link
from poetry.repositories.pool import Pool from poetry.repositories.pool import Pool
from poetry.utils.env import Env
class InvalidWheelName(Exception): class InvalidWheelName(Exception):
...@@ -44,7 +44,7 @@ class Wheel: ...@@ -44,7 +44,7 @@ class Wheel:
return min(indexes) if indexes else None return min(indexes) if indexes else None
def is_supported_by_environment(self, env: Env) -> bool: def is_supported_by_environment(self, env: "Env") -> bool:
return bool(set(env.supported_tags).intersection(self.tags)) return bool(set(env.supported_tags).intersection(self.tags))
...@@ -53,11 +53,11 @@ class Chooser: ...@@ -53,11 +53,11 @@ class Chooser:
A Chooser chooses an appropriate release archive for packages. A Chooser chooses an appropriate release archive for packages.
""" """
def __init__(self, pool: "Pool", env: Env) -> None: def __init__(self, pool: "Pool", env: "Env") -> None:
self._pool = pool self._pool = pool
self._env = env self._env = env
def choose_for(self, package: Package) -> Link: def choose_for(self, package: "Package") -> "Link":
""" """
Return the url of the selected archive for a given package. Return the url of the selected archive for a given package.
""" """
...@@ -83,7 +83,7 @@ class Chooser: ...@@ -83,7 +83,7 @@ class Chooser:
return chosen return chosen
def _get_links(self, package: Package) -> List[Link]: def _get_links(self, package: "Package") -> List["Link"]:
if not package.source_type: if not package.source_type:
if not self._pool.has_repository("pypi"): if not self._pool.has_repository("pypi"):
repository = self._pool.repositories[0] repository = self._pool.repositories[0]
...@@ -117,7 +117,7 @@ class Chooser: ...@@ -117,7 +117,7 @@ class Chooser:
return selected_links return selected_links
def _sort_key(self, package: Package, link: Link) -> Tuple: def _sort_key(self, package: "Package", link: "Link") -> Tuple:
""" """
Function to pass as the `key` argument to a call to sorted() to sort Function to pass as the `key` argument to a call to sorted() to sort
InstallationCandidates by preference. InstallationCandidates by preference.
...@@ -175,7 +175,9 @@ class Chooser: ...@@ -175,7 +175,9 @@ class Chooser:
pri, pri,
) )
def _is_link_hash_allowed_for_package(self, link: Link, package: Package) -> bool: def _is_link_hash_allowed_for_package(
self, link: "Link", package: "Package"
) -> bool:
if not link.hash: if not link.hash:
return True return True
......
...@@ -17,16 +17,11 @@ from typing import Union ...@@ -17,16 +17,11 @@ from typing import Union
from cleo.io.null_io import NullIO from cleo.io.null_io import NullIO
from poetry.core.packages.file_dependency import FileDependency from poetry.core.packages.file_dependency import FileDependency
from poetry.core.packages.package import Package
from poetry.core.packages.utils.link import Link from poetry.core.packages.utils.link import Link
from poetry.core.packages.utils.utils import url_to_path from poetry.core.packages.utils.utils import url_to_path
from poetry.core.pyproject.toml import PyProjectTOML from poetry.core.pyproject.toml import PyProjectTOML
from poetry.installation.chef import Chef from poetry.installation.chef import Chef
from poetry.installation.chooser import Chooser from poetry.installation.chooser import Chooser
from poetry.installation.operations.install import Install
from poetry.installation.operations.operation import Operation
from poetry.installation.operations.uninstall import Uninstall
from poetry.installation.operations.update import Update
from poetry.utils._compat import decode from poetry.utils._compat import decode
from poetry.utils.authenticator import Authenticator from poetry.utils.authenticator import Authenticator
from poetry.utils.env import EnvCommandError from poetry.utils.env import EnvCommandError
...@@ -39,7 +34,12 @@ if TYPE_CHECKING: ...@@ -39,7 +34,12 @@ if TYPE_CHECKING:
from cleo.io.io import IO from cleo.io.io import IO
from poetry.config.config import Config from poetry.config.config import Config
from poetry.core.packages.package import Package
from poetry.installation.operations import OperationTypes from poetry.installation.operations import OperationTypes
from poetry.installation.operations.install import Install
from poetry.installation.operations.operation import Operation
from poetry.installation.operations.uninstall import Uninstall
from poetry.installation.operations.update import Update
from poetry.repositories import Pool from poetry.repositories import Pool
from poetry.utils.env import Env from poetry.utils.env import Env
...@@ -457,21 +457,21 @@ class Executor: ...@@ -457,21 +457,21 @@ class Executor:
) )
self._io.write_line("") self._io.write_line("")
def _execute_install(self, operation: Union[Install, Update]) -> int: def _execute_install(self, operation: Union["Install", "Update"]) -> int:
status_code = self._install(operation) status_code = self._install(operation)
self._save_url_reference(operation) self._save_url_reference(operation)
return status_code return status_code
def _execute_update(self, operation: Union[Install, Update]) -> int: def _execute_update(self, operation: Union["Install", "Update"]) -> int:
status_code = self._update(operation) status_code = self._update(operation)
self._save_url_reference(operation) self._save_url_reference(operation)
return status_code return status_code
def _execute_uninstall(self, operation: Uninstall) -> int: def _execute_uninstall(self, operation: "Uninstall") -> int:
message = ( message = (
" <fg=blue;options=bold>•</> {message}: <info>Removing...</info>".format( " <fg=blue;options=bold>•</> {message}: <info>Removing...</info>".format(
message=self.get_operation_message(operation), message=self.get_operation_message(operation),
...@@ -481,7 +481,7 @@ class Executor: ...@@ -481,7 +481,7 @@ class Executor:
return self._remove(operation) return self._remove(operation)
def _install(self, operation: Union[Install, Update]) -> int: def _install(self, operation: Union["Install", "Update"]) -> int:
package = operation.package package = operation.package
if package.source_type == "directory": if package.source_type == "directory":
return self._install_directory(operation) return self._install_directory(operation)
...@@ -505,10 +505,10 @@ class Executor: ...@@ -505,10 +505,10 @@ class Executor:
self._write(operation, message) self._write(operation, message)
return self.pip_install(archive, upgrade=operation.job_type == "update") return self.pip_install(archive, upgrade=operation.job_type == "update")
def _update(self, operation: Union[Install, Update]) -> int: def _update(self, operation: Union["Install", "Update"]) -> int:
return self._install(operation) return self._install(operation)
def _remove(self, operation: Uninstall) -> int: def _remove(self, operation: "Uninstall") -> int:
package = operation.package package = operation.package
# If we have a VCS package, remove its source directory # If we have a VCS package, remove its source directory
...@@ -525,7 +525,7 @@ class Executor: ...@@ -525,7 +525,7 @@ class Executor:
raise raise
def _prepare_file(self, operation: Union[Install, Update]) -> Path: def _prepare_file(self, operation: Union["Install", "Update"]) -> Path:
package = operation.package package = operation.package
message = ( message = (
...@@ -543,7 +543,7 @@ class Executor: ...@@ -543,7 +543,7 @@ class Executor:
return archive return archive
def _install_directory(self, operation: Union[Install, Update]) -> int: def _install_directory(self, operation: Union["Install", "Update"]) -> int:
from poetry.factory import Factory from poetry.factory import Factory
package = operation.package package = operation.package
...@@ -603,7 +603,7 @@ class Executor: ...@@ -603,7 +603,7 @@ class Executor:
return self.pip_install(req, upgrade=True) return self.pip_install(req, upgrade=True)
def _install_git(self, operation: Union[Install, Update]) -> int: def _install_git(self, operation: Union["Install", "Update"]) -> int:
from poetry.core.vcs import Git from poetry.core.vcs import Git
package = operation.package package = operation.package
...@@ -641,12 +641,12 @@ class Executor: ...@@ -641,12 +641,12 @@ class Executor:
return status_code return status_code
def _download(self, operation: Union[Install, Update]) -> Link: def _download(self, operation: Union["Install", "Update"]) -> Link:
link = self._chooser.choose_for(operation.package) link = self._chooser.choose_for(operation.package)
return self._download_link(operation, link) return self._download_link(operation, link)
def _download_link(self, operation: Union[Install, Update], link: Link) -> Link: def _download_link(self, operation: Union["Install", "Update"], link: Link) -> Link:
package = operation.package package = operation.package
archive = self._chef.get_cached_archive_for_link(link) archive = self._chef.get_cached_archive_for_link(link)
...@@ -677,7 +677,7 @@ class Executor: ...@@ -677,7 +677,7 @@ class Executor:
return archive return archive
@staticmethod @staticmethod
def _validate_archive_hash(archive: Union[Path, Link], package: Package) -> str: def _validate_archive_hash(archive: Union[Path, Link], package: "Package") -> str:
archive_path = ( archive_path = (
url_to_path(archive.url) if isinstance(archive, Link) else archive url_to_path(archive.url) if isinstance(archive, Link) else archive
) )
...@@ -695,7 +695,9 @@ class Executor: ...@@ -695,7 +695,9 @@ class Executor:
return archive_hash return archive_hash
def _download_archive(self, operation: Union[Install, Update], link: Link) -> Path: def _download_archive(
self, operation: Union["Install", "Update"], link: Link
) -> Path:
response = self._authenticator.request( response = self._authenticator.request(
"get", link.url, stream=True, io=self._sections.get(id(operation), self._io) "get", link.url, stream=True, io=self._sections.get(id(operation), self._io)
) )
...@@ -744,7 +746,7 @@ class Executor: ...@@ -744,7 +746,7 @@ class Executor:
return archive return archive
def _should_write_operation(self, operation: Operation) -> bool: def _should_write_operation(self, operation: "Operation") -> bool:
return not operation.skipped or self._dry_run or self._verbose return not operation.skipped or self._dry_run or self._verbose
def _save_url_reference(self, operation: "OperationTypes") -> None: def _save_url_reference(self, operation: "OperationTypes") -> None:
......
...@@ -5,19 +5,13 @@ from typing import Optional ...@@ -5,19 +5,13 @@ from typing import Optional
from typing import Sequence from typing import Sequence
from typing import Union from typing import Union
from cleo.io.io import IO
from cleo.io.null_io import NullIO from cleo.io.null_io import NullIO
from poetry.config.config import Config
from poetry.core.packages.project_package import ProjectPackage
from poetry.installation.base_installer import BaseInstaller
from poetry.installation.executor import Executor from poetry.installation.executor import Executor
from poetry.installation.operations import Install from poetry.installation.operations import Install
from poetry.installation.operations import Uninstall from poetry.installation.operations import Uninstall
from poetry.installation.operations import Update from poetry.installation.operations import Update
from poetry.installation.operations.operation import Operation
from poetry.installation.pip_installer import PipInstaller from poetry.installation.pip_installer import PipInstaller
from poetry.packages import Locker
from poetry.repositories import Pool from poetry.repositories import Pool
from poetry.repositories import Repository from poetry.repositories import Repository
from poetry.repositories.installed_repository import InstalledRepository from poetry.repositories.installed_repository import InstalledRepository
...@@ -26,19 +20,26 @@ from poetry.utils.helpers import canonicalize_name ...@@ -26,19 +20,26 @@ from poetry.utils.helpers import canonicalize_name
if TYPE_CHECKING: if TYPE_CHECKING:
from cleo.io.io import IO
from poetry.config.config import Config
from poetry.core.packages.project_package import ProjectPackage
from poetry.installation.base_installer import BaseInstaller
from poetry.installation.operations import OperationTypes from poetry.installation.operations import OperationTypes
from poetry.installation.operations.operation import Operation
from poetry.packages import Locker
from poetry.utils.env import Env from poetry.utils.env import Env
class Installer: class Installer:
def __init__( def __init__(
self, self,
io: IO, io: "IO",
env: "Env", env: "Env",
package: ProjectPackage, package: "ProjectPackage",
locker: Locker, locker: "Locker",
pool: Pool, pool: Pool,
config: Config, config: "Config",
installed: Union[Repository, None] = None, installed: Union[Repository, None] = None,
executor: Optional[Executor] = None, executor: Optional[Executor] = None,
): ):
...@@ -81,15 +82,15 @@ class Installer: ...@@ -81,15 +82,15 @@ class Installer:
return self._executor return self._executor
@property @property
def installer(self) -> BaseInstaller: def installer(self) -> "BaseInstaller":
return self._installer return self._installer
def set_package(self, package: ProjectPackage) -> "Installer": def set_package(self, package: "ProjectPackage") -> "Installer":
self._package = package self._package = package
return self return self
def set_locker(self, locker: Locker) -> "Installer": def set_locker(self, locker: "Locker") -> "Installer":
self._locker = locker self._locker = locker
return self return self
...@@ -409,7 +410,7 @@ class Installer: ...@@ -409,7 +410,7 @@ class Installer:
return 0 return 0
def _execute_operation(self, operation: Operation) -> None: def _execute_operation(self, operation: "Operation") -> None:
""" """
Execute a given operation. Execute a given operation.
""" """
...@@ -498,7 +499,7 @@ class Installer: ...@@ -498,7 +499,7 @@ class Installer:
self._installer.remove(operation.package) self._installer.remove(operation.package)
def _populate_local_repo( def _populate_local_repo(
self, local_repo: Repository, ops: Sequence[Operation] self, local_repo: Repository, ops: Sequence["Operation"]
) -> None: ) -> None:
for op in ops: for op in ops:
if isinstance(op, Uninstall): if isinstance(op, Uninstall):
...@@ -513,7 +514,7 @@ class Installer: ...@@ -513,7 +514,7 @@ class Installer:
def _get_operations_from_lock( def _get_operations_from_lock(
self, locked_repository: Repository self, locked_repository: Repository
) -> Sequence[Operation]: ) -> Sequence["Operation"]:
installed_repo = self._installed_repository installed_repo = self._installed_repository
ops = [] ops = []
...@@ -542,7 +543,7 @@ class Installer: ...@@ -542,7 +543,7 @@ class Installer:
return ops return ops
def _filter_operations(self, ops: Sequence[Operation], repo: Repository) -> None: def _filter_operations(self, ops: Sequence["Operation"], repo: Repository) -> None:
extra_packages = self._get_extra_packages(repo) extra_packages = self._get_extra_packages(repo)
for op in ops: for op in ops:
if isinstance(op, Update): if isinstance(op, Update):
...@@ -585,7 +586,7 @@ class Installer: ...@@ -585,7 +586,7 @@ class Installer:
return list(get_extra_package_names(repo.packages, extras, self._extras)) return list(get_extra_package_names(repo.packages, extras, self._extras))
def _get_installer(self) -> BaseInstaller: def _get_installer(self) -> "BaseInstaller":
return PipInstaller(self._env, self._io, self._pool) return PipInstaller(self._env, self._io, self._pool)
def _get_installed(self) -> InstalledRepository: def _get_installed(self) -> InstalledRepository:
......
...@@ -8,24 +8,24 @@ from typing import TYPE_CHECKING ...@@ -8,24 +8,24 @@ from typing import TYPE_CHECKING
from typing import Any from typing import Any
from typing import Union from typing import Union
from cleo.io.io import IO
from poetry.core.pyproject.toml import PyProjectTOML from poetry.core.pyproject.toml import PyProjectTOML
from poetry.installation.base_installer import BaseInstaller from poetry.installation.base_installer import BaseInstaller
from poetry.utils._compat import encode from poetry.utils._compat import encode
from poetry.utils.env import Env
from poetry.utils.helpers import safe_rmtree from poetry.utils.helpers import safe_rmtree
from poetry.utils.pip import pip_editable_install from poetry.utils.pip import pip_editable_install
from poetry.utils.pip import pip_install from poetry.utils.pip import pip_install
if TYPE_CHECKING: if TYPE_CHECKING:
from cleo.io.io import IO
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
from poetry.repositories.pool import Pool from poetry.repositories.pool import Pool
from poetry.utils.env import Env
class PipInstaller(BaseInstaller): class PipInstaller(BaseInstaller):
def __init__(self, env: Env, io: IO, pool: "Pool") -> None: def __init__(self, env: "Env", io: "IO", pool: "Pool") -> None:
self._env = env self._env = env
self._io = io self._io = io
self._pool = pool self._pool = pool
......
...@@ -102,7 +102,7 @@ class Layout: ...@@ -102,7 +102,7 @@ class Layout:
return package return package
def create(self, path: "Path", with_tests: bool = True) -> None: def create(self, path: Path, with_tests: bool = True) -> None:
path.mkdir(parents=True, exist_ok=True) path.mkdir(parents=True, exist_ok=True)
self._create_default(path) self._create_default(path)
...@@ -174,27 +174,27 @@ class Layout: ...@@ -174,27 +174,27 @@ class Layout:
return content return content
def _create_default(self, path: "Path", src: bool = True) -> None: def _create_default(self, path: Path, src: bool = True) -> None:
package_path = path / self.package_path package_path = path / self.package_path
package_path.mkdir(parents=True) package_path.mkdir(parents=True)
package_init = package_path / "__init__.py" package_init = package_path / "__init__.py"
package_init.touch() package_init.touch()
def _create_readme(self, path: "Path") -> "Path": def _create_readme(self, path: Path) -> Path:
readme_file = path.joinpath(f"README.{self._readme_format}") readme_file = path.joinpath(f"README.{self._readme_format}")
readme_file.touch() readme_file.touch()
return readme_file return readme_file
@staticmethod @staticmethod
def _create_tests(path: "Path") -> None: def _create_tests(path: Path) -> None:
tests = path / "tests" tests = path / "tests"
tests.mkdir() tests.mkdir()
tests_init = tests / "__init__.py" tests_init = tests / "__init__.py"
tests_init.touch(exist_ok=False) tests_init.touch(exist_ok=False)
def _write_poetry(self, path: "Path") -> None: def _write_poetry(self, path: Path) -> None:
content = self.generate_poetry_content() content = self.generate_poetry_content()
poetry = path / "pyproject.toml" poetry = path / "pyproject.toml"
......
...@@ -5,5 +5,5 @@ from poetry.layouts.layout import Layout ...@@ -5,5 +5,5 @@ from poetry.layouts.layout import Layout
class SrcLayout(Layout): class SrcLayout(Layout):
@property @property
def basedir(self) -> "Path": def basedir(self) -> Path:
return Path("src") return Path("src")
from typing import TYPE_CHECKING
from typing import Dict from typing import Dict
from typing import List from typing import List
from typing import Optional from typing import Optional
from typing import Tuple from typing import Tuple
from poetry.core.semver.helpers import parse_constraint from poetry.core.semver.helpers import parse_constraint
from poetry.mixology.incompatibility import Incompatibility
from poetry.mixology.incompatibility_cause import ConflictCause from poetry.mixology.incompatibility_cause import ConflictCause
from poetry.mixology.incompatibility_cause import PythonCause from poetry.mixology.incompatibility_cause import PythonCause
if TYPE_CHECKING:
from poetry.mixology.incompatibility import Incompatibility
class SolveFailure(Exception): class SolveFailure(Exception):
def __init__(self, incompatibility: Incompatibility) -> None: def __init__(self, incompatibility: "Incompatibility") -> None:
self._incompatibility = incompatibility self._incompatibility = incompatibility
@property @property
...@@ -22,11 +26,11 @@ class SolveFailure(Exception): ...@@ -22,11 +26,11 @@ class SolveFailure(Exception):
class _Writer: class _Writer:
def __init__(self, root: Incompatibility) -> None: def __init__(self, root: "Incompatibility") -> None:
self._root = root self._root = root
self._derivations: Dict[Incompatibility, int] = {} self._derivations: Dict["Incompatibility", int] = {}
self._lines: List[Tuple[str, Optional[int]]] = [] self._lines: List[Tuple[str, Optional[int]]] = []
self._line_numbers: Dict[Incompatibility, int] = {} self._line_numbers: Dict["Incompatibility", int] = {}
self._count_derivations(self._root) self._count_derivations(self._root)
...@@ -95,7 +99,7 @@ class _Writer: ...@@ -95,7 +99,7 @@ class _Writer:
return "\n".join(buffer) return "\n".join(buffer)
def _write( def _write(
self, incompatibility: Incompatibility, message: str, numbered: bool = False self, incompatibility: "Incompatibility", message: str, numbered: bool = False
) -> None: ) -> None:
if numbered: if numbered:
number = len(self._line_numbers) + 1 number = len(self._line_numbers) + 1
...@@ -106,7 +110,7 @@ class _Writer: ...@@ -106,7 +110,7 @@ class _Writer:
def _visit( def _visit(
self, self,
incompatibility: Incompatibility, incompatibility: "Incompatibility",
details_for_incompatibility: Dict, details_for_incompatibility: Dict,
conclusion: bool = False, conclusion: bool = False,
) -> None: ) -> None:
...@@ -252,7 +256,7 @@ class _Writer: ...@@ -252,7 +256,7 @@ class _Writer:
numbered=numbered, numbered=numbered,
) )
def _is_collapsible(self, incompatibility: Incompatibility) -> bool: def _is_collapsible(self, incompatibility: "Incompatibility") -> bool:
if self._derivations[incompatibility] > 1: if self._derivations[incompatibility] > 1:
return False return False
...@@ -280,7 +284,7 @@ class _Writer: ...@@ -280,7 +284,7 @@ class _Writer:
cause.other.cause, ConflictCause cause.other.cause, ConflictCause
) )
def _count_derivations(self, incompatibility: Incompatibility) -> None: def _count_derivations(self, incompatibility: "Incompatibility") -> None:
if incompatibility in self._derivations: if incompatibility in self._derivations:
self._derivations[incompatibility] += 1 self._derivations[incompatibility] += 1
else: else:
......
from typing import TYPE_CHECKING
from typing import Callable from typing import Callable
from typing import Dict from typing import Dict
from typing import Iterator from typing import Iterator
...@@ -7,17 +8,20 @@ from typing import Union ...@@ -7,17 +8,20 @@ from typing import Union
from poetry.mixology.incompatibility_cause import ConflictCause from poetry.mixology.incompatibility_cause import ConflictCause
from poetry.mixology.incompatibility_cause import DependencyCause from poetry.mixology.incompatibility_cause import DependencyCause
from poetry.mixology.incompatibility_cause import IncompatibilityCause
from poetry.mixology.incompatibility_cause import NoVersionsCause from poetry.mixology.incompatibility_cause import NoVersionsCause
from poetry.mixology.incompatibility_cause import PackageNotFoundCause from poetry.mixology.incompatibility_cause import PackageNotFoundCause
from poetry.mixology.incompatibility_cause import PlatformCause from poetry.mixology.incompatibility_cause import PlatformCause
from poetry.mixology.incompatibility_cause import PythonCause from poetry.mixology.incompatibility_cause import PythonCause
from poetry.mixology.incompatibility_cause import RootCause from poetry.mixology.incompatibility_cause import RootCause
from poetry.mixology.term import Term
if TYPE_CHECKING:
from poetry.mixology.incompatibility_cause import IncompatibilityCause
from poetry.mixology.term import Term
class Incompatibility: class Incompatibility:
def __init__(self, terms: List[Term], cause: IncompatibilityCause) -> None: def __init__(self, terms: List["Term"], cause: "IncompatibilityCause") -> None:
# Remove the root package from generated incompatibilities, since it will # Remove the root package from generated incompatibilities, since it will
# always be satisfied. This makes error reporting clearer, and may also # always be satisfied. This makes error reporting clearer, and may also
# make solving more efficient. # make solving more efficient.
...@@ -42,7 +46,7 @@ class Incompatibility: ...@@ -42,7 +46,7 @@ class Incompatibility:
pass pass
else: else:
# Coalesce multiple terms about the same package if possible. # Coalesce multiple terms about the same package if possible.
by_name: Dict[str, Dict[str, Term]] = {} by_name: Dict[str, Dict[str, "Term"]] = {}
for term in terms: for term in terms:
if term.dependency.complete_name not in by_name: if term.dependency.complete_name not in by_name:
by_name[term.dependency.complete_name] = {} by_name[term.dependency.complete_name] = {}
...@@ -79,7 +83,7 @@ class Incompatibility: ...@@ -79,7 +83,7 @@ class Incompatibility:
self._cause = cause self._cause = cause
@property @property
def terms(self) -> List[Term]: def terms(self) -> List["Term"]:
return self._terms return self._terms
@property @property
...@@ -449,7 +453,7 @@ class Incompatibility: ...@@ -449,7 +453,7 @@ class Incompatibility:
return "".join(buffer) return "".join(buffer)
def _terse(self, term: Term, allow_every: bool = False) -> str: def _terse(self, term: "Term", allow_every: bool = False) -> str:
if allow_every and term.constraint.is_any(): if allow_every and term.constraint.is_any():
return f"every version of {term.dependency.complete_name}" return f"every version of {term.dependency.complete_name}"
...@@ -460,7 +464,9 @@ class Incompatibility: ...@@ -460,7 +464,9 @@ class Incompatibility:
term.dependency.pretty_name, term.dependency.pretty_constraint term.dependency.pretty_name, term.dependency.pretty_constraint
) )
def _single_term_where(self, callable: Callable[[Term], bool]) -> Optional[Term]: def _single_term_where(
self, callable: Callable[["Term"], bool]
) -> Optional["Term"]:
found = None found = None
for term in self._terms: for term in self._terms:
if not callable(term): if not callable(term):
......
...@@ -3,14 +3,14 @@ from typing import Dict ...@@ -3,14 +3,14 @@ from typing import Dict
from typing import List from typing import List
from poetry.mixology.assignment import Assignment from poetry.mixology.assignment import Assignment
from poetry.mixology.incompatibility import Incompatibility
from poetry.mixology.set_relation import SetRelation from poetry.mixology.set_relation import SetRelation
from poetry.mixology.term import Term
if TYPE_CHECKING: if TYPE_CHECKING:
from poetry.core.packages.dependency import Dependency from poetry.core.packages.dependency import Dependency
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
from poetry.mixology.incompatibility import Incompatibility
from poetry.mixology.term import Term
class PartialSolution: class PartialSolution:
...@@ -34,7 +34,7 @@ class PartialSolution: ...@@ -34,7 +34,7 @@ class PartialSolution:
# negative Assignments that refer to that package. # negative Assignments that refer to that package.
# #
# This is derived from self._assignments. # This is derived from self._assignments.
self._positive: Dict[str, Term] = {} self._positive: Dict[str, "Term"] = {}
# The union of all negative Assignments for each package. # The union of all negative Assignments for each package.
# #
...@@ -42,7 +42,7 @@ class PartialSolution: ...@@ -42,7 +42,7 @@ class PartialSolution:
# map. # map.
# #
# This is derived from self._assignments. # This is derived from self._assignments.
self._negative: Dict[str, Dict[str, Term]] = {} self._negative: Dict[str, Dict[str, "Term"]] = {}
# The number of distinct solutions that have been attempted so far. # The number of distinct solutions that have been attempted so far.
self._attempted_solutions = 1 self._attempted_solutions = 1
...@@ -90,7 +90,7 @@ class PartialSolution: ...@@ -90,7 +90,7 @@ class PartialSolution:
) )
def derive( def derive(
self, dependency: "Dependency", is_positive: bool, cause: Incompatibility self, dependency: "Dependency", is_positive: bool, cause: "Incompatibility"
) -> None: ) -> None:
""" """
Adds an assignment of package as a derivation. Adds an assignment of package as a derivation.
...@@ -168,7 +168,7 @@ class PartialSolution: ...@@ -168,7 +168,7 @@ class PartialSolution:
self._negative[name][ref] = term self._negative[name][ref] = term
def satisfier(self, term: Term) -> Assignment: def satisfier(self, term: "Term") -> Assignment:
""" """
Returns the first Assignment in this solution such that the sublist of Returns the first Assignment in this solution such that the sublist of
assignments up to and including that entry collectively satisfies term. assignments up to and including that entry collectively satisfies term.
...@@ -201,10 +201,10 @@ class PartialSolution: ...@@ -201,10 +201,10 @@ class PartialSolution:
raise RuntimeError(f"[BUG] {term} is not satisfied.") raise RuntimeError(f"[BUG] {term} is not satisfied.")
def satisfies(self, term: Term) -> bool: def satisfies(self, term: "Term") -> bool:
return self.relation(term) == SetRelation.SUBSET return self.relation(term) == SetRelation.SUBSET
def relation(self, term: Term) -> int: def relation(self, term: "Term") -> int:
positive = self._positive.get(term.dependency.complete_name) positive = self._positive.get(term.dependency.complete_name)
if positive is not None: if positive is not None:
return positive.relation(term) return positive.relation(term)
......
import re import re
from typing import TYPE_CHECKING
from typing import List from typing import List
from crashtest.contracts.has_solutions_for_exception import HasSolutionsForException from crashtest.contracts.has_solutions_for_exception import HasSolutionsForException
from crashtest.contracts.solution import Solution
if TYPE_CHECKING:
from crashtest.contracts.solution import Solution
class PythonRequirementSolutionProvider(HasSolutionsForException): class PythonRequirementSolutionProvider(HasSolutionsForException):
...@@ -24,7 +28,7 @@ class PythonRequirementSolutionProvider(HasSolutionsForException): ...@@ -24,7 +28,7 @@ class PythonRequirementSolutionProvider(HasSolutionsForException):
return True return True
def get_solutions(self, exception: Exception) -> List[Solution]: def get_solutions(self, exception: Exception) -> List["Solution"]:
from poetry.mixology.solutions.solutions.python_requirement_solution import ( from poetry.mixology.solutions.solutions.python_requirement_solution import (
PythonRequirementSolution, PythonRequirementSolution,
) )
......
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Optional from typing import Optional
from poetry.core.packages.dependency import Dependency
from poetry.mixology.set_relation import SetRelation from poetry.mixology.set_relation import SetRelation
if TYPE_CHECKING: if TYPE_CHECKING:
from poetry.core.packages.dependency import Dependency
from poetry.core.semver.helpers import VersionTypes from poetry.core.semver.helpers import VersionTypes
...@@ -17,7 +17,7 @@ class Term: ...@@ -17,7 +17,7 @@ class Term:
See https://github.com/dart-lang/pub/tree/master/doc/solver.md#term. See https://github.com/dart-lang/pub/tree/master/doc/solver.md#term.
""" """
def __init__(self, dependency: Dependency, is_positive: bool) -> None: def __init__(self, dependency: "Dependency", is_positive: bool) -> None:
self._dependency = dependency self._dependency = dependency
self._positive = is_positive self._positive = is_positive
...@@ -26,7 +26,7 @@ class Term: ...@@ -26,7 +26,7 @@ class Term:
return Term(self._dependency, not self.is_positive()) return Term(self._dependency, not self.is_positive())
@property @property
def dependency(self) -> Dependency: def dependency(self) -> "Dependency":
return self._dependency return self._dependency
@property @property
......
...@@ -8,8 +8,6 @@ from typing import Tuple ...@@ -8,8 +8,6 @@ from typing import Tuple
from typing import Union from typing import Union
from poetry.core.packages.dependency import Dependency from poetry.core.packages.dependency import Dependency
from poetry.core.packages.package import Package
from poetry.core.packages.project_package import ProjectPackage
from poetry.mixology.failure import SolveFailure from poetry.mixology.failure import SolveFailure
from poetry.mixology.incompatibility import Incompatibility from poetry.mixology.incompatibility import Incompatibility
from poetry.mixology.incompatibility_cause import ConflictCause from poetry.mixology.incompatibility_cause import ConflictCause
...@@ -23,6 +21,8 @@ from poetry.mixology.term import Term ...@@ -23,6 +21,8 @@ from poetry.mixology.term import Term
if TYPE_CHECKING: if TYPE_CHECKING:
from poetry.core.packages.package import Package
from poetry.core.packages.project_package import ProjectPackage
from poetry.puzzle.provider import Provider from poetry.puzzle.provider import Provider
...@@ -40,9 +40,9 @@ class VersionSolver: ...@@ -40,9 +40,9 @@ class VersionSolver:
def __init__( def __init__(
self, self,
root: ProjectPackage, root: "ProjectPackage",
provider: "Provider", provider: "Provider",
locked: Dict[str, Package] = None, locked: Dict[str, "Package"] = None,
use_latest: List[str] = None, use_latest: List[str] = None,
): ):
self._root = root self._root = root
...@@ -446,7 +446,7 @@ class VersionSolver: ...@@ -446,7 +446,7 @@ class VersionSolver:
incompatibility incompatibility
) )
def _get_locked(self, dependency: Dependency) -> Optional[Package]: def _get_locked(self, dependency: Dependency) -> Optional["Package"]:
if dependency.name in self._use_latest: if dependency.name in self._use_latest:
return None return None
......
from typing import TYPE_CHECKING
from typing import Any from typing import Any
from typing import List from typing import List
from typing import Union from typing import Union
from poetry.core.packages.dependency import Dependency
from poetry.core.packages.package import Package if TYPE_CHECKING:
from poetry.core.packages.dependency import Dependency
from poetry.core.packages.package import Package
class DependencyPackage: class DependencyPackage:
def __init__(self, dependency: Dependency, package: Package) -> None: def __init__(self, dependency: "Dependency", package: "Package") -> None:
self._dependency = dependency self._dependency = dependency
self._package = package self._package = package
@property @property
def dependency(self) -> Dependency: def dependency(self) -> "Dependency":
return self._dependency return self._dependency
@property @property
def package(self) -> Package: def package(self) -> "Package":
return self._package return self._package
def clone(self) -> "DependencyPackage": def clone(self) -> "DependencyPackage":
...@@ -46,7 +49,7 @@ class DependencyPackage: ...@@ -46,7 +49,7 @@ class DependencyPackage:
def __hash__(self) -> int: def __hash__(self) -> int:
return hash(self._package) return hash(self._package)
def __eq__(self, other: Union[Package, "DependencyPackage"]) -> bool: def __eq__(self, other: Union["Package", "DependencyPackage"]) -> bool:
if isinstance(other, DependencyPackage): if isinstance(other, DependencyPackage):
other = other.package other = other.package
......
from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import List from typing import List
from typing import Optional from typing import Optional
...@@ -9,6 +8,8 @@ from poetry.core.poetry import Poetry as BasePoetry ...@@ -9,6 +8,8 @@ from poetry.core.poetry import Poetry as BasePoetry
if TYPE_CHECKING: if TYPE_CHECKING:
from pathlib import Path
from poetry.config.config import Config from poetry.config.config import Config
from poetry.core.packages.project_package import ProjectPackage from poetry.core.packages.project_package import ProjectPackage
from poetry.packages.locker import Locker from poetry.packages.locker import Locker
...@@ -22,7 +23,7 @@ class Poetry(BasePoetry): ...@@ -22,7 +23,7 @@ class Poetry(BasePoetry):
def __init__( def __init__(
self, self,
file: Path, file: "Path",
local_config: dict, local_config: dict,
package: "ProjectPackage", package: "ProjectPackage",
locker: "Locker", locker: "Locker",
...@@ -35,7 +36,7 @@ class Poetry(BasePoetry): ...@@ -35,7 +36,7 @@ class Poetry(BasePoetry):
self._locker = locker self._locker = locker
self._config = config self._config = config
self._pool = Pool() self._pool = Pool()
self._plugin_manager: Optional[PluginManager] = None self._plugin_manager: Optional["PluginManager"] = None
@property @property
def locker(self) -> "Locker": def locker(self) -> "Locker":
......
import logging import logging
from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import List from typing import List
from typing import Optional from typing import Optional
...@@ -13,6 +12,8 @@ from poetry.utils.helpers import get_client_cert ...@@ -13,6 +12,8 @@ from poetry.utils.helpers import get_client_cert
if TYPE_CHECKING: if TYPE_CHECKING:
from pathlib import Path
from cleo.io import BufferedIO from cleo.io import BufferedIO
from cleo.io import ConsoleIO from cleo.io import ConsoleIO
...@@ -34,7 +35,7 @@ class Publisher: ...@@ -34,7 +35,7 @@ class Publisher:
self._authenticator = Authenticator(poetry.config, self._io) self._authenticator = Authenticator(poetry.config, self._io)
@property @property
def files(self) -> List[Path]: def files(self) -> List["Path"]:
return self._uploader.files return self._uploader.files
def publish( def publish(
...@@ -42,8 +43,8 @@ class Publisher: ...@@ -42,8 +43,8 @@ class Publisher:
repository_name: Optional[str], repository_name: Optional[str],
username: Optional[str], username: Optional[str],
password: Optional[str], password: Optional[str],
cert: Optional[Path] = None, cert: Optional["Path"] = None,
client_cert: Optional[Path] = None, client_cert: Optional["Path"] = None,
dry_run: bool = False, dry_run: bool = False,
) -> None: ) -> None:
if not repository_name: if not repository_name:
......
import hashlib import hashlib
import io import io
from pathlib import Path
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Any from typing import Any
from typing import Dict from typing import Dict
...@@ -29,6 +28,8 @@ from poetry.utils.patterns import wheel_file_re ...@@ -29,6 +28,8 @@ from poetry.utils.patterns import wheel_file_re
if TYPE_CHECKING: if TYPE_CHECKING:
from pathlib import Path
from cleo.io.null_io import NullIO from cleo.io.null_io import NullIO
from poetry.poetry import Poetry from poetry.poetry import Poetry
...@@ -76,7 +77,7 @@ class Uploader: ...@@ -76,7 +77,7 @@ class Uploader:
return adapters.HTTPAdapter(max_retries=retry) return adapters.HTTPAdapter(max_retries=retry)
@property @property
def files(self) -> List[Path]: def files(self) -> List["Path"]:
dist = self._poetry.file.parent / "dist" dist = self._poetry.file.parent / "dist"
version = normalize_version(self._package.version.text) version = normalize_version(self._package.version.text)
...@@ -114,8 +115,8 @@ class Uploader: ...@@ -114,8 +115,8 @@ class Uploader:
def upload( def upload(
self, self,
url: str, url: str,
cert: Optional[Path] = None, cert: Optional["Path"] = None,
client_cert: Optional[Path] = None, client_cert: Optional["Path"] = None,
dry_run: bool = False, dry_run: bool = False,
) -> None: ) -> None:
session = self.make_session() session = self.make_session()
...@@ -131,7 +132,7 @@ class Uploader: ...@@ -131,7 +132,7 @@ class Uploader:
finally: finally:
session.close() session.close()
def post_data(self, file: Path) -> Dict[str, Any]: def post_data(self, file: "Path") -> Dict[str, Any]:
meta = Metadata.from_package(self._package) meta = Metadata.from_package(self._package)
file_type = self._get_type(file) file_type = self._get_type(file)
...@@ -220,7 +221,7 @@ class Uploader: ...@@ -220,7 +221,7 @@ class Uploader:
self, self,
session: requests.Session, session: requests.Session,
url: str, url: str,
file: Path, file: "Path",
dry_run: Optional[bool] = False, dry_run: Optional[bool] = False,
) -> None: ) -> None:
from cleo.ui.progress_bar import ProgressBar from cleo.ui.progress_bar import ProgressBar
...@@ -327,7 +328,7 @@ class Uploader: ...@@ -327,7 +328,7 @@ class Uploader:
return data_to_send return data_to_send
def _get_type(self, file: Path) -> str: def _get_type(self, file: "Path") -> str:
exts = file.suffixes exts = file.suffixes
if exts[-1] == ".whl": if exts[-1] == ".whl":
return "bdist_wheel" return "bdist_wheel"
......
...@@ -8,6 +8,7 @@ import urllib.parse ...@@ -8,6 +8,7 @@ import urllib.parse
from contextlib import contextmanager from contextlib import contextmanager
from pathlib import Path from pathlib import Path
from tempfile import mkdtemp from tempfile import mkdtemp
from typing import TYPE_CHECKING
from typing import Any from typing import Any
from typing import Dict from typing import Dict
from typing import Iterator from typing import Iterator
...@@ -18,13 +19,7 @@ from typing import Union ...@@ -18,13 +19,7 @@ from typing import Union
from cleo.ui.progress_indicator import ProgressIndicator from cleo.ui.progress_indicator import ProgressIndicator
from poetry.core.packages.dependency import Dependency
from poetry.core.packages.directory_dependency import DirectoryDependency
from poetry.core.packages.file_dependency import FileDependency
from poetry.core.packages.package import Package
from poetry.core.packages.url_dependency import URLDependency
from poetry.core.packages.utils.utils import get_python_constraint_from_marker from poetry.core.packages.utils.utils import get_python_constraint_from_marker
from poetry.core.packages.vcs_dependency import VCSDependency
from poetry.core.semver.version import Version from poetry.core.semver.version import Version
from poetry.core.vcs.git import Git from poetry.core.vcs.git import Git
from poetry.core.version.markers import MarkerUnion from poetry.core.version.markers import MarkerUnion
...@@ -37,12 +32,21 @@ from poetry.mixology.term import Term ...@@ -37,12 +32,21 @@ from poetry.mixology.term import Term
from poetry.packages import DependencyPackage from poetry.packages import DependencyPackage
from poetry.packages.package_collection import PackageCollection from poetry.packages.package_collection import PackageCollection
from poetry.puzzle.exceptions import OverrideNeeded from poetry.puzzle.exceptions import OverrideNeeded
from poetry.repositories import Pool
from poetry.utils.env import Env
from poetry.utils.helpers import download_file from poetry.utils.helpers import download_file
from poetry.utils.helpers import safe_rmtree from poetry.utils.helpers import safe_rmtree
if TYPE_CHECKING:
from poetry.core.packages.dependency import Dependency
from poetry.core.packages.directory_dependency import DirectoryDependency
from poetry.core.packages.file_dependency import FileDependency
from poetry.core.packages.package import Package
from poetry.core.packages.url_dependency import URLDependency
from poetry.core.packages.vcs_dependency import VCSDependency
from poetry.repositories import Pool
from poetry.utils.env import Env
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -58,22 +62,22 @@ class Provider: ...@@ -58,22 +62,22 @@ class Provider:
UNSAFE_PACKAGES: Set[str] = set() UNSAFE_PACKAGES: Set[str] = set()
def __init__( def __init__(
self, package: Package, pool: Pool, io: Any, env: Optional[Env] = None self, package: "Package", pool: "Pool", io: Any, env: Optional["Env"] = None
) -> None: ) -> None:
self._package = package self._package = package
self._pool = pool self._pool = pool
self._io = io self._io = io
self._env = env self._env = env
self._python_constraint = package.python_constraint self._python_constraint = package.python_constraint
self._search_for: Dict[Dependency, List[Package]] = {} self._search_for: Dict["Dependency", List["Package"]] = {}
self._is_debugging = self._io.is_debug() or self._io.is_very_verbose() self._is_debugging = self._io.is_debug() or self._io.is_very_verbose()
self._in_progress = False self._in_progress = False
self._overrides: Dict = {} self._overrides: Dict = {}
self._deferred_cache: Dict[Dependency, Package] = {} self._deferred_cache: Dict["Dependency", "Package"] = {}
self._load_deferred = True self._load_deferred = True
@property @property
def pool(self) -> Pool: def pool(self) -> "Pool":
return self._pool return self._pool
def is_debugging(self) -> bool: def is_debugging(self) -> bool:
...@@ -86,7 +90,7 @@ class Provider: ...@@ -86,7 +90,7 @@ class Provider:
self._load_deferred = load_deferred self._load_deferred = load_deferred
@contextmanager @contextmanager
def use_environment(self, env: Env) -> Iterator["Provider"]: def use_environment(self, env: "Env") -> Iterator["Provider"]:
original_env = self._env original_env = self._env
original_python_constraint = self._python_constraint original_python_constraint = self._python_constraint
...@@ -101,13 +105,13 @@ class Provider: ...@@ -101,13 +105,13 @@ class Provider:
def search_for( def search_for(
self, self,
dependency: Union[ dependency: Union[
Dependency, "Dependency",
VCSDependency, "VCSDependency",
FileDependency, "FileDependency",
DirectoryDependency, "DirectoryDependency",
URLDependency, "URLDependency",
], ],
) -> List[DependencyPackage]: ) -> List["DependencyPackage"]:
""" """
Search for the specifications that match the given dependency. Search for the specifications that match the given dependency.
...@@ -162,7 +166,7 @@ class Provider: ...@@ -162,7 +166,7 @@ class Provider:
return PackageCollection(dependency, packages) return PackageCollection(dependency, packages)
def search_for_vcs(self, dependency: VCSDependency) -> List[Package]: def search_for_vcs(self, dependency: "VCSDependency") -> List["Package"]:
""" """
Search for the specifications that match the given VCS dependency. Search for the specifications that match the given VCS dependency.
...@@ -207,7 +211,7 @@ class Provider: ...@@ -207,7 +211,7 @@ class Provider:
tag: Optional[str] = None, tag: Optional[str] = None,
rev: Optional[str] = None, rev: Optional[str] = None,
name: Optional[str] = None, name: Optional[str] = None,
) -> Package: ) -> "Package":
if vcs != "git": if vcs != "git":
raise ValueError(f"Unsupported VCS dependency {vcs}") raise ValueError(f"Unsupported VCS dependency {vcs}")
...@@ -238,7 +242,7 @@ class Provider: ...@@ -238,7 +242,7 @@ class Provider:
return package return package
def search_for_file(self, dependency: FileDependency) -> List[Package]: def search_for_file(self, dependency: "FileDependency") -> List["Package"]:
if dependency in self._deferred_cache: if dependency in self._deferred_cache:
dependency, _package = self._deferred_cache[dependency] dependency, _package = self._deferred_cache[dependency]
...@@ -269,7 +273,7 @@ class Provider: ...@@ -269,7 +273,7 @@ class Provider:
return [package] return [package]
@classmethod @classmethod
def get_package_from_file(cls, file_path: Path) -> Package: def get_package_from_file(cls, file_path: Path) -> "Package":
try: try:
package = PackageInfo.from_path(path=file_path).to_package( package = PackageInfo.from_path(path=file_path).to_package(
root_dir=file_path root_dir=file_path
...@@ -281,7 +285,9 @@ class Provider: ...@@ -281,7 +285,9 @@ class Provider:
return package return package
def search_for_directory(self, dependency: DirectoryDependency) -> List[Package]: def search_for_directory(
self, dependency: "DirectoryDependency"
) -> List["Package"]:
if dependency in self._deferred_cache: if dependency in self._deferred_cache:
dependency, _package = self._deferred_cache[dependency] dependency, _package = self._deferred_cache[dependency]
...@@ -306,7 +312,7 @@ class Provider: ...@@ -306,7 +312,7 @@ class Provider:
@classmethod @classmethod
def get_package_from_directory( def get_package_from_directory(
cls, directory: Path, name: Optional[str] = None cls, directory: Path, name: Optional[str] = None
) -> Package: ) -> "Package":
package = PackageInfo.from_directory(path=directory).to_package( package = PackageInfo.from_directory(path=directory).to_package(
root_dir=directory root_dir=directory
) )
...@@ -321,7 +327,7 @@ class Provider: ...@@ -321,7 +327,7 @@ class Provider:
return package return package
def search_for_url(self, dependency: URLDependency) -> List[Package]: def search_for_url(self, dependency: "URLDependency") -> List["Package"]:
if dependency in self._deferred_cache: if dependency in self._deferred_cache:
return [self._deferred_cache[dependency]] return [self._deferred_cache[dependency]]
...@@ -351,7 +357,7 @@ class Provider: ...@@ -351,7 +357,7 @@ class Provider:
return [package] return [package]
@classmethod @classmethod
def get_package_from_url(cls, url: str) -> Package: def get_package_from_url(cls, url: str) -> "Package":
file_name = os.path.basename(urllib.parse.urlparse(url).path) file_name = os.path.basename(urllib.parse.urlparse(url).path)
with tempfile.TemporaryDirectory() as temp_dir: with tempfile.TemporaryDirectory() as temp_dir:
dest = Path(temp_dir) / file_name dest = Path(temp_dir) / file_name
...@@ -543,7 +549,7 @@ class Provider: ...@@ -543,7 +549,7 @@ class Provider:
# An example of this is: # An example of this is:
# - pypiwin32 (220); sys_platform == "win32" and python_version >= "3.6" # - pypiwin32 (220); sys_platform == "win32" and python_version >= "3.6"
# - pypiwin32 (219); sys_platform == "win32" and python_version < "3.6" # - pypiwin32 (219); sys_platform == "win32" and python_version < "3.6"
duplicates: Dict[str, List[Dependency]] = {} duplicates: Dict[str, List["Dependency"]] = {}
for dep in dependencies: for dep in dependencies:
if dep.complete_name not in duplicates: if dep.complete_name not in duplicates:
duplicates[dep.complete_name] = [] duplicates[dep.complete_name] = []
...@@ -559,7 +565,7 @@ class Provider: ...@@ -559,7 +565,7 @@ class Provider:
self.debug(f"<debug>Duplicate dependencies for {dep_name}</debug>") self.debug(f"<debug>Duplicate dependencies for {dep_name}</debug>")
# Regrouping by constraint # Regrouping by constraint
by_constraint: Dict[str, List[Dependency]] = {} by_constraint: Dict[str, List["Dependency"]] = {}
for dep in deps: for dep in deps:
if dep.constraint not in by_constraint: if dep.constraint not in by_constraint:
by_constraint[dep.constraint] = [] by_constraint[dep.constraint] = []
......
...@@ -13,38 +13,38 @@ from typing import Optional ...@@ -13,38 +13,38 @@ from typing import Optional
from typing import Tuple from typing import Tuple
from typing import Union from typing import Union
from cleo.io.io import IO
from poetry.core.packages.package import Package
from poetry.core.packages.project_package import ProjectPackage
from poetry.mixology import resolve_version from poetry.mixology import resolve_version
from poetry.mixology.failure import SolveFailure from poetry.mixology.failure import SolveFailure
from poetry.packages import DependencyPackage from poetry.packages import DependencyPackage
from poetry.puzzle.exceptions import OverrideNeeded from poetry.puzzle.exceptions import OverrideNeeded
from poetry.puzzle.exceptions import SolverProblemError from poetry.puzzle.exceptions import SolverProblemError
from poetry.puzzle.provider import Provider from poetry.puzzle.provider import Provider
from poetry.repositories import Pool
from poetry.repositories import Repository
from poetry.utils.env import Env
if TYPE_CHECKING: if TYPE_CHECKING:
from cleo.io.io import IO
from poetry.core.packages.dependency import Dependency from poetry.core.packages.dependency import Dependency
from poetry.core.packages.directory_dependency import DirectoryDependency from poetry.core.packages.directory_dependency import DirectoryDependency
from poetry.core.packages.file_dependency import FileDependency from poetry.core.packages.file_dependency import FileDependency
from poetry.core.packages.package import Package
from poetry.core.packages.project_package import ProjectPackage
from poetry.core.packages.url_dependency import URLDependency from poetry.core.packages.url_dependency import URLDependency
from poetry.core.packages.vcs_dependency import VCSDependency from poetry.core.packages.vcs_dependency import VCSDependency
from poetry.puzzle.transaction import Transaction from poetry.puzzle.transaction import Transaction
from poetry.repositories import Pool
from poetry.repositories import Repository
from poetry.utils.env import Env
class Solver: class Solver:
def __init__( def __init__(
self, self,
package: ProjectPackage, package: "ProjectPackage",
pool: Pool, pool: "Pool",
installed: Repository, installed: "Repository",
locked: Repository, locked: "Repository",
io: IO, io: "IO",
provider: Optional[Provider] = None, provider: Optional[Provider] = None,
): ):
self._package = package self._package = package
...@@ -64,7 +64,7 @@ class Solver: ...@@ -64,7 +64,7 @@ class Solver:
return self._provider return self._provider
@contextmanager @contextmanager
def use_environment(self, env: Env) -> Iterator[None]: def use_environment(self, env: "Env") -> Iterator[None]:
with self.provider.use_environment(env): with self.provider.use_environment(env):
yield yield
...@@ -125,7 +125,7 @@ class Solver: ...@@ -125,7 +125,7 @@ class Solver:
return packages, depths return packages, depths
def _solve(self, use_latest: List[str] = None) -> Tuple[List[Package], List[int]]: def _solve(self, use_latest: List[str] = None) -> Tuple[List["Package"], List[int]]:
if self._provider._overrides: if self._provider._overrides:
self._overrides.append(self._provider._overrides) self._overrides.append(self._provider._overrides)
...@@ -205,7 +205,7 @@ class VisitedState(enum.Enum): ...@@ -205,7 +205,7 @@ class VisitedState(enum.Enum):
def depth_first_search( def depth_first_search(
source: "PackageNode", aggregator: Callable source: "PackageNode", aggregator: Callable
) -> List[Tuple[Package, int]]: ) -> List[Tuple["Package", int]]:
back_edges: Dict[DFSNodeID, List["PackageNode"]] = defaultdict(list) back_edges: Dict[DFSNodeID, List["PackageNode"]] = defaultdict(list)
visited: Dict[DFSNodeID, VisitedState] = {} visited: Dict[DFSNodeID, VisitedState] = {}
topo_sorted_nodes: List["PackageNode"] = [] topo_sorted_nodes: List["PackageNode"] = []
...@@ -259,9 +259,9 @@ def dfs_visit( ...@@ -259,9 +259,9 @@ def dfs_visit(
class PackageNode(DFSNode): class PackageNode(DFSNode):
def __init__( def __init__(
self, self,
package: Package, package: "Package",
packages: List[Package], packages: List["Package"],
seen: List[Package], seen: List["Package"],
previous: Optional["PackageNode"] = None, previous: Optional["PackageNode"] = None,
previous_dep: Optional[ previous_dep: Optional[
Union[ Union[
...@@ -377,7 +377,7 @@ class PackageNode(DFSNode): ...@@ -377,7 +377,7 @@ class PackageNode(DFSNode):
def aggregate_package_nodes( def aggregate_package_nodes(
nodes: List[PackageNode], children: List[PackageNode] nodes: List[PackageNode], children: List[PackageNode]
) -> Tuple[Package, int]: ) -> Tuple["Package", int]:
package = nodes[0].package package = nodes[0].package
depth = max(node.depth for node in nodes) depth = max(node.depth for node in nodes)
groups: List[str] = [] groups: List[str] = []
......
...@@ -10,7 +10,7 @@ if TYPE_CHECKING: ...@@ -10,7 +10,7 @@ if TYPE_CHECKING:
class BaseRepository: class BaseRepository:
def __init__(self) -> None: def __init__(self) -> None:
self._packages: List[Package] = [] self._packages: List["Package"] = []
@property @property
def packages(self) -> List["Package"]: def packages(self) -> List["Package"]:
......
...@@ -2,6 +2,7 @@ import itertools ...@@ -2,6 +2,7 @@ import itertools
import json import json
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING
from typing import Set from typing import Set
from typing import Tuple from typing import Tuple
from typing import Union from typing import Union
...@@ -12,7 +13,10 @@ from poetry.core.utils.helpers import canonicalize_name ...@@ -12,7 +13,10 @@ from poetry.core.utils.helpers import canonicalize_name
from poetry.core.utils.helpers import module_name from poetry.core.utils.helpers import module_name
from poetry.repositories.repository import Repository from poetry.repositories.repository import Repository
from poetry.utils._compat import metadata from poetry.utils._compat import metadata
from poetry.utils.env import Env
if TYPE_CHECKING:
from poetry.utils.env import Env
_VENDORS = Path(__file__).parent.parent.joinpath("_vendor") _VENDORS = Path(__file__).parent.parent.joinpath("_vendor")
...@@ -26,7 +30,7 @@ except NameError: ...@@ -26,7 +30,7 @@ except NameError:
class InstalledRepository(Repository): class InstalledRepository(Repository):
@classmethod @classmethod
def get_package_paths(cls, env: Env, name: str) -> Set[Path]: def get_package_paths(cls, env: "Env", name: str) -> Set[Path]:
""" """
Process a .pth file within the site-packages directories, and return any valid Process a .pth file within the site-packages directories, and return any valid
paths. We skip executable .pth files as there is no reliable means to do this paths. We skip executable .pth files as there is no reliable means to do this
...@@ -82,7 +86,7 @@ class InstalledRepository(Repository): ...@@ -82,7 +86,7 @@ class InstalledRepository(Repository):
return "git", url, revision return "git", url, revision
@classmethod @classmethod
def is_vcs_package(cls, package: Union[Path, Package], env: Env) -> bool: def is_vcs_package(cls, package: Union[Path, Package], env: "Env") -> bool:
# A VCS dependency should have been installed # A VCS dependency should have been installed
# in the src directory. # in the src directory.
src = env.path / "src" src = env.path / "src"
...@@ -216,7 +220,7 @@ class InstalledRepository(Repository): ...@@ -216,7 +220,7 @@ class InstalledRepository(Repository):
return package return package
@classmethod @classmethod
def load(cls, env: Env, with_dependencies: bool = False) -> "InstalledRepository": def load(cls, env: "Env", with_dependencies: bool = False) -> "InstalledRepository":
""" """
Load installed packages. Load installed packages.
""" """
......
...@@ -5,25 +5,25 @@ from typing import Optional ...@@ -5,25 +5,25 @@ from typing import Optional
from poetry.repositories.base_repository import BaseRepository from poetry.repositories.base_repository import BaseRepository
from poetry.repositories.exceptions import PackageNotFound from poetry.repositories.exceptions import PackageNotFound
from poetry.repositories.repository import Repository
if TYPE_CHECKING: if TYPE_CHECKING:
from poetry.core.packages.dependency import Dependency from poetry.core.packages.dependency import Dependency
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
from poetry.repositories.repository import Repository
class Pool(BaseRepository): class Pool(BaseRepository):
def __init__( def __init__(
self, self,
repositories: Optional[List[Repository]] = None, repositories: Optional[List["Repository"]] = None,
ignore_repository_names: bool = False, ignore_repository_names: bool = False,
) -> None: ) -> None:
if repositories is None: if repositories is None:
repositories = [] repositories = []
self._lookup: Dict[Optional[str], int] = {} self._lookup: Dict[Optional[str], int] = {}
self._repositories: List[Repository] = [] self._repositories: List["Repository"] = []
self._default = False self._default = False
self._has_primary_repositories = False self._has_primary_repositories = False
self._secondary_start_idx: Optional[int] = None self._secondary_start_idx: Optional[int] = None
...@@ -36,7 +36,7 @@ class Pool(BaseRepository): ...@@ -36,7 +36,7 @@ class Pool(BaseRepository):
super().__init__() super().__init__()
@property @property
def repositories(self) -> List[Repository]: def repositories(self) -> List["Repository"]:
return self._repositories return self._repositories
def has_default(self) -> bool: def has_default(self) -> bool:
...@@ -50,7 +50,7 @@ class Pool(BaseRepository): ...@@ -50,7 +50,7 @@ class Pool(BaseRepository):
return name in self._lookup return name in self._lookup
def repository(self, name: str) -> Repository: def repository(self, name: str) -> "Repository":
if name is not None: if name is not None:
name = name.lower() name = name.lower()
...@@ -60,7 +60,7 @@ class Pool(BaseRepository): ...@@ -60,7 +60,7 @@ class Pool(BaseRepository):
raise ValueError(f'Repository "{name}" does not exist.') raise ValueError(f'Repository "{name}" does not exist.')
def add_repository( def add_repository(
self, repository: Repository, default: bool = False, secondary: bool = False self, repository: "Repository", default: bool = False, secondary: bool = False
) -> "Pool": ) -> "Pool":
""" """
Adds a repository to the pool. Adds a repository to the pool.
......
...@@ -5,7 +5,7 @@ try: ...@@ -5,7 +5,7 @@ try:
from importlib import metadata from importlib import metadata
except ImportError: except ImportError:
# compatibility for python <3.8 # compatibility for python <3.8
import importlib_metadata as metadata # noqa: F401 import importlib_metadata as metadata # noqa: F401, TC002
WINDOWS = sys.platform == "win32" WINDOWS = sys.platform == "win32"
......
...@@ -15,6 +15,7 @@ from contextlib import contextmanager ...@@ -15,6 +15,7 @@ from contextlib import contextmanager
from copy import deepcopy from copy import deepcopy
from pathlib import Path from pathlib import Path
from subprocess import CalledProcessError from subprocess import CalledProcessError
from typing import TYPE_CHECKING
from typing import Any from typing import Any
from typing import ContextManager from typing import ContextManager
from typing import Dict from typing import Dict
...@@ -29,7 +30,6 @@ import packaging.tags ...@@ -29,7 +30,6 @@ import packaging.tags
import tomlkit import tomlkit
import virtualenv import virtualenv
from cleo.io.io import IO
from packaging.tags import Tag from packaging.tags import Tag
from packaging.tags import interpreter_name from packaging.tags import interpreter_name
from packaging.tags import interpreter_version from packaging.tags import interpreter_version
...@@ -39,9 +39,7 @@ from virtualenv.seed.wheels.embed import get_embed_wheel ...@@ -39,9 +39,7 @@ from virtualenv.seed.wheels.embed import get_embed_wheel
from poetry.core.semver.helpers import parse_constraint from poetry.core.semver.helpers import parse_constraint
from poetry.core.semver.version import Version from poetry.core.semver.version import Version
from poetry.core.toml.file import TOMLFile from poetry.core.toml.file import TOMLFile
from poetry.core.version.markers import BaseMarker
from poetry.locations import CACHE_DIR from poetry.locations import CACHE_DIR
from poetry.poetry import Poetry
from poetry.utils._compat import decode from poetry.utils._compat import decode
from poetry.utils._compat import encode from poetry.utils._compat import encode
from poetry.utils._compat import list_to_shell_command from poetry.utils._compat import list_to_shell_command
...@@ -51,6 +49,13 @@ from poetry.utils.helpers import paths_csv ...@@ -51,6 +49,13 @@ from poetry.utils.helpers import paths_csv
from poetry.utils.helpers import temporary_directory from poetry.utils.helpers import temporary_directory
if TYPE_CHECKING:
from cleo.io.io import IO
from poetry.core.version.markers import BaseMarker
from poetry.poetry import Poetry
GET_ENVIRONMENT_INFO = """\ GET_ENVIRONMENT_INFO = """\
import json import json
import os import os
...@@ -453,10 +458,10 @@ class EnvManager: ...@@ -453,10 +458,10 @@ class EnvManager:
ENVS_FILE = "envs.toml" ENVS_FILE = "envs.toml"
def __init__(self, poetry: Poetry) -> None: def __init__(self, poetry: "Poetry") -> None:
self._poetry = poetry self._poetry = poetry
def activate(self, python: str, io: IO) -> "Env": def activate(self, python: str, io: "IO") -> "Env":
venv_path = self._poetry.config.get("virtualenvs.path") venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None: if venv_path is None:
venv_path = Path(CACHE_DIR) / "virtualenvs" venv_path = Path(CACHE_DIR) / "virtualenvs"
...@@ -553,7 +558,7 @@ class EnvManager: ...@@ -553,7 +558,7 @@ class EnvManager:
return self.get(reload=True) return self.get(reload=True)
def deactivate(self, io: IO) -> None: def deactivate(self, io: "IO") -> None:
venv_path = self._poetry.config.get("virtualenvs.path") venv_path = self._poetry.config.get("virtualenvs.path")
if venv_path is None: if venv_path is None:
venv_path = Path(CACHE_DIR) / "virtualenvs" venv_path = Path(CACHE_DIR) / "virtualenvs"
...@@ -763,7 +768,7 @@ class EnvManager: ...@@ -763,7 +768,7 @@ class EnvManager:
def create_venv( def create_venv(
self, self,
io: IO, io: "IO",
name: Optional[str] = None, name: Optional[str] = None,
executable: Optional[str] = None, executable: Optional[str] = None,
force: bool = False, force: bool = False,
...@@ -1301,7 +1306,7 @@ class Env: ...@@ -1301,7 +1306,7 @@ class Env:
def get_paths(self) -> Dict[str, str]: def get_paths(self) -> Dict[str, str]:
raise NotImplementedError() raise NotImplementedError()
def is_valid_for_marker(self, marker: BaseMarker) -> bool: def is_valid_for_marker(self, marker: "BaseMarker") -> bool:
return marker.validate(self.marker_env) return marker.validate(self.marker_env)
def is_sane(self) -> bool: def is_sane(self) -> bool:
......
import urllib.parse import urllib.parse
from pathlib import Path from typing import TYPE_CHECKING
from typing import Optional from typing import Optional
from typing import Sequence from typing import Sequence
from typing import Union from typing import Union
from cleo.io.io import IO
from poetry.core.packages.utils.utils import path_to_url from poetry.core.packages.utils.utils import path_to_url
from poetry.poetry import Poetry
from poetry.utils._compat import decode from poetry.utils._compat import decode
if TYPE_CHECKING:
from pathlib import Path
from cleo.io.io import IO
from poetry.poetry import Poetry
class Exporter: class Exporter:
""" """
Exporter class to export a lock file to alternative formats. Exporter class to export a lock file to alternative formats.
...@@ -22,14 +27,14 @@ class Exporter: ...@@ -22,14 +27,14 @@ class Exporter:
ACCEPTED_FORMATS = (FORMAT_REQUIREMENTS_TXT,) ACCEPTED_FORMATS = (FORMAT_REQUIREMENTS_TXT,)
ALLOWED_HASH_ALGORITHMS = ("sha256", "sha384", "sha512") ALLOWED_HASH_ALGORITHMS = ("sha256", "sha384", "sha512")
def __init__(self, poetry: Poetry) -> None: def __init__(self, poetry: "Poetry") -> None:
self._poetry = poetry self._poetry = poetry
def export( def export(
self, self,
fmt: str, fmt: str,
cwd: Path, cwd: "Path",
output: Union[IO, str], output: Union["IO", str],
with_hashes: bool = True, with_hashes: bool = True,
dev: bool = False, dev: bool = False,
extras: Optional[Union[bool, Sequence[str]]] = None, extras: Optional[Union[bool, Sequence[str]]] = None,
...@@ -51,8 +56,8 @@ class Exporter: ...@@ -51,8 +56,8 @@ class Exporter:
def _export_requirements_txt( def _export_requirements_txt(
self, self,
cwd: Path, cwd: "Path",
output: Union[IO, str], output: Union["IO", str],
with_hashes: bool = True, with_hashes: bool = True,
dev: bool = False, dev: bool = False,
extras: Optional[Union[bool, Sequence[str]]] = None, extras: Optional[Union[bool, Sequence[str]]] = None,
...@@ -161,7 +166,7 @@ class Exporter: ...@@ -161,7 +166,7 @@ class Exporter:
self._output(content, cwd, output) self._output(content, cwd, output)
def _output(self, content: str, cwd: Path, output: Union[IO, str]) -> None: def _output(self, content: str, cwd: "Path", output: Union["IO", str]) -> None:
decoded = decode(content) decoded = decode(content)
try: try:
output.write(decoded) output.write(decoded)
......
...@@ -15,12 +15,11 @@ from typing import Iterator ...@@ -15,12 +15,11 @@ from typing import Iterator
from typing import List from typing import List
from typing import Optional from typing import Optional
from poetry.config.config import Config
if TYPE_CHECKING: if TYPE_CHECKING:
from requests import Session from requests import Session
from poetry.config.config import Config
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
...@@ -49,7 +48,7 @@ def temporary_directory(*args: Any, **kwargs: Any) -> Iterator[str]: ...@@ -49,7 +48,7 @@ def temporary_directory(*args: Any, **kwargs: Any) -> Iterator[str]:
shutil.rmtree(name, onerror=_del_ro) shutil.rmtree(name, onerror=_del_ro)
def get_cert(config: Config, repository_name: str) -> Optional[Path]: def get_cert(config: "Config", repository_name: str) -> Optional[Path]:
cert = config.get(f"certificates.{repository_name}.cert") cert = config.get(f"certificates.{repository_name}.cert")
if cert: if cert:
return Path(cert) return Path(cert)
...@@ -57,7 +56,7 @@ def get_cert(config: Config, repository_name: str) -> Optional[Path]: ...@@ -57,7 +56,7 @@ def get_cert(config: Config, repository_name: str) -> Optional[Path]:
return None return None
def get_client_cert(config: Config, repository_name: str) -> Optional[Path]: def get_client_cert(config: "Config", repository_name: str) -> Optional[Path]:
client_cert = config.get(f"certificates.{repository_name}.client-cert") client_cert = config.get(f"certificates.{repository_name}.client-cert")
if client_cert: if client_cert:
return Path(client_cert) return Path(client_cert)
......
import os import os
import sys import sys
from pathlib import Path from typing import TYPE_CHECKING
from typing import Union from typing import Union
from poetry.core.packages.utils.link import Link from poetry.core.packages.utils.link import Link
from poetry.core.packages.utils.utils import url_to_path from poetry.core.packages.utils.utils import url_to_path
from poetry.exceptions import PoetryException from poetry.exceptions import PoetryException
from poetry.utils.env import Env
from poetry.utils.env import EnvCommandError from poetry.utils.env import EnvCommandError
from poetry.utils.env import ephemeral_environment from poetry.utils.env import ephemeral_environment
if TYPE_CHECKING:
from pathlib import Path
from poetry.utils.env import Env
def pip_install( def pip_install(
path: Union[Path, Link], path: Union["Path", Link],
environment: Env, environment: "Env",
editable: bool = False, editable: bool = False,
deps: bool = False, deps: bool = False,
upgrade: bool = False, upgrade: bool = False,
...@@ -63,7 +68,7 @@ def pip_install( ...@@ -63,7 +68,7 @@ def pip_install(
def pip_editable_install( def pip_editable_install(
directory: Union[Path, Link], environment: Env directory: Union["Path", Link], environment: "Env"
) -> Union[int, str]: ) -> Union[int, str]:
return pip_install( return pip_install(
path=directory, environment=environment, editable=True, deps=False, upgrade=True path=directory, environment=environment, editable=True, deps=False, upgrade=True
......
...@@ -3,6 +3,7 @@ import signal ...@@ -3,6 +3,7 @@ import signal
import sys import sys
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any from typing import Any
from typing import Optional from typing import Optional
...@@ -13,7 +14,10 @@ from shellingham import ShellDetectionFailure ...@@ -13,7 +14,10 @@ from shellingham import ShellDetectionFailure
from shellingham import detect_shell from shellingham import detect_shell
from poetry.utils._compat import WINDOWS from poetry.utils._compat import WINDOWS
from poetry.utils.env import VirtualEnv
if TYPE_CHECKING:
from poetry.utils.env import VirtualEnv
class Shell: class Shell:
...@@ -62,7 +66,7 @@ class Shell: ...@@ -62,7 +66,7 @@ class Shell:
return cls._shell return cls._shell
def activate(self, env: VirtualEnv) -> Optional[int]: def activate(self, env: "VirtualEnv") -> Optional[int]:
if WINDOWS: if WINDOWS:
return env.execute(self.path) return env.execute(self.path)
......
...@@ -2,11 +2,11 @@ from typing import TYPE_CHECKING ...@@ -2,11 +2,11 @@ from typing import TYPE_CHECKING
from typing import Optional from typing import Optional
from typing import Union from typing import Union
from poetry.core.packages.package import Package
from poetry.core.semver.version import Version from poetry.core.semver.version import Version
if TYPE_CHECKING: if TYPE_CHECKING:
from poetry.core.packages.package import Package
from poetry.repositories import Pool from poetry.repositories import Pool
...@@ -20,7 +20,7 @@ class VersionSelector: ...@@ -20,7 +20,7 @@ class VersionSelector:
target_package_version: Optional[str] = None, target_package_version: Optional[str] = None,
allow_prereleases: bool = False, allow_prereleases: bool = False,
source: Optional[str] = None, source: Optional[str] = None,
) -> Union[Package, bool]: ) -> Union["Package", bool]:
""" """
Given a package name and optional version, Given a package name and optional version,
returns the latest Package that matches returns the latest Package that matches
...@@ -58,7 +58,7 @@ class VersionSelector: ...@@ -58,7 +58,7 @@ class VersionSelector:
return False return False
return package return package
def find_recommended_require_version(self, package: Package) -> str: def find_recommended_require_version(self, package: "Package") -> str:
version = package.version version = package.version
return self._transform_version(version.text, package.pretty_version) return self._transform_version(version.text, package.pretty_version)
......
try: try:
import zipp import zipp
except ImportError: except ImportError:
import zipfile as zipp # noqa: F401 import zipfile as zipp # noqa: F401, TC002
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING
from typing import Optional from typing import Optional
import pytest import pytest
from poetry.factory import Factory from poetry.factory import Factory
from poetry.poetry import Poetry
if TYPE_CHECKING:
from poetry.poetry import Poetry
@pytest.fixture @pytest.fixture
...@@ -14,7 +18,7 @@ def tester(command_tester_factory): ...@@ -14,7 +18,7 @@ def tester(command_tester_factory):
def verify_project_directory( def verify_project_directory(
path: Path, package_name: str, package_path: str, include_from: Optional[str] = None path: Path, package_name: str, package_path: str, include_from: Optional[str] = None
) -> Poetry: ) -> "Poetry":
package_path = Path(package_path) package_path = Path(package_path)
assert path.is_dir() assert path.is_dir()
......
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING
from typing import Optional from typing import Optional
import pytest import pytest
from pytest_mock.plugin import MockerFixture
from poetry.core.packages.package import Package
from poetry.repositories.installed_repository import InstalledRepository from poetry.repositories.installed_repository import InstalledRepository
from poetry.utils._compat import metadata from poetry.utils._compat import metadata
from poetry.utils.env import MockEnv as BaseMockEnv from poetry.utils.env import MockEnv as BaseMockEnv
from tests.compat import zipp from tests.compat import zipp
if TYPE_CHECKING:
from pytest_mock.plugin import MockerFixture
from poetry.core.packages.package import Package
FIXTURES_DIR = Path(__file__).parent / "fixtures" FIXTURES_DIR = Path(__file__).parent / "fixtures"
ENV_DIR = (FIXTURES_DIR / "installed").resolve() ENV_DIR = (FIXTURES_DIR / "installed").resolve()
SITE_PURELIB = ENV_DIR / "lib" / "python3.7" / "site-packages" SITE_PURELIB = ENV_DIR / "lib" / "python3.7" / "site-packages"
...@@ -59,7 +62,7 @@ def env() -> MockEnv: ...@@ -59,7 +62,7 @@ def env() -> MockEnv:
@pytest.fixture @pytest.fixture
def repository(mocker: MockerFixture, env: MockEnv) -> InstalledRepository: def repository(mocker: "MockerFixture", env: MockEnv) -> InstalledRepository:
mocker.patch( mocker.patch(
"poetry.utils._compat.metadata.Distribution.discover", "poetry.utils._compat.metadata.Distribution.discover",
return_value=INSTALLED_RESULTS, return_value=INSTALLED_RESULTS,
...@@ -81,7 +84,7 @@ def repository(mocker: MockerFixture, env: MockEnv) -> InstalledRepository: ...@@ -81,7 +84,7 @@ def repository(mocker: MockerFixture, env: MockEnv) -> InstalledRepository:
def get_package_from_repository( def get_package_from_repository(
name: str, repository: InstalledRepository name: str, repository: InstalledRepository
) -> Optional[Package]: ) -> Optional["Package"]:
for pkg in repository.packages: for pkg in repository.packages:
if pkg.name == name: if pkg.name == name:
return pkg return pkg
......
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