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