From 1346497b2bb8c1d1353243a153f6a85b41a57728 Mon Sep 17 00:00:00 2001 From: finswimmer Date: Fri, 30 Oct 2020 23:03:19 +0100 Subject: [PATCH] fix and add several type hints --- poetry/config/config.py | 10 +- poetry/config/file_config_source.py | 5 +- poetry/console/__init__.py | 2 +- poetry/console/application.py | 10 +- poetry/console/commands/about.py | 2 +- poetry/console/commands/add.py | 2 +- poetry/console/commands/build.py | 2 +- poetry/console/commands/cache/cache.py | 2 +- poetry/console/commands/cache/clear.py | 2 +- poetry/console/commands/cache/list.py | 4 +- poetry/console/commands/check.py | 2 +- poetry/console/commands/command.py | 8 +- poetry/console/commands/config.py | 25 ++++- poetry/console/commands/debug/info.py | 2 +- poetry/console/commands/debug/resolve.py | 4 +- poetry/console/commands/env/info.py | 11 ++- poetry/console/commands/env/list.py | 2 +- poetry/console/commands/env/remove.py | 2 +- poetry/console/commands/env/use.py | 2 +- poetry/console/commands/env_command.py | 12 ++- poetry/console/commands/export.py | 2 +- poetry/console/commands/init.py | 15 +-- poetry/console/commands/install.py | 2 +- poetry/console/commands/installer_command.py | 4 +- poetry/console/commands/lock.py | 2 +- poetry/console/commands/new.py | 2 +- poetry/console/commands/publish.py | 3 +- poetry/console/commands/remove.py | 2 +- poetry/console/commands/run.py | 7 +- poetry/console/commands/search.py | 2 +- poetry/console/commands/self/self.py | 2 +- poetry/console/commands/self/update.py | 32 ++++--- poetry/console/commands/shell.py | 2 +- poetry/console/commands/show.py | 48 +++++++--- poetry/console/commands/update.py | 2 +- poetry/console/commands/version.py | 4 +- poetry/console/config/application_config.py | 2 +- poetry/console/logging/io_formatter.py | 8 +- poetry/console/logging/io_handler.py | 12 ++- poetry/factory.py | 2 +- poetry/inspection/info.py | 4 +- poetry/installation/base_installer.py | 13 ++- poetry/installation/chooser.py | 5 +- poetry/installation/executor.py | 72 ++++++++++----- poetry/installation/installer.py | 32 ++++--- poetry/installation/noop_installer.py | 21 +++-- poetry/installation/operations/__init__.py | 5 + poetry/installation/operations/install.py | 19 +++- poetry/installation/operations/operation.py | 17 ++-- poetry/installation/operations/uninstall.py | 19 +++- poetry/installation/operations/update.py | 23 +++-- poetry/installation/pip_installer.py | 23 +++-- poetry/io/null_io.py | 4 +- poetry/layouts/layout.py | 34 +++---- poetry/layouts/src.py | 7 +- poetry/layouts/standard.py | 6 +- poetry/masonry/builders/editable.py | 26 ++++-- poetry/mixology/__init__.py | 16 +++- poetry/mixology/assignment.py | 20 +++- poetry/mixology/failure.py | 11 ++- poetry/mixology/incompatibility.py | 30 +++--- poetry/mixology/incompatibility_cause.py | 31 ++++--- poetry/mixology/partial_solution.py | 24 +++-- poetry/mixology/result.py | 17 +++- .../solutions/python_requirement_solution.py | 15 ++- poetry/mixology/term.py | 23 +++-- poetry/mixology/version_solver.py | 12 +-- poetry/packages/dependency_package.py | 16 ++-- poetry/packages/locker.py | 20 ++-- poetry/packages/package_collection.py | 15 ++- poetry/publishing/publisher.py | 16 +++- poetry/publishing/uploader.py | 26 ++++-- poetry/puzzle/exceptions.py | 12 ++- poetry/puzzle/provider.py | 17 ++-- poetry/puzzle/solver.py | 64 +++++++++---- poetry/repositories/base_repository.py | 24 +++-- poetry/repositories/legacy_repository.py | 26 ++++-- poetry/repositories/pool.py | 13 ++- poetry/repositories/pypi_repository.py | 12 ++- poetry/repositories/repository.py | 34 +++++-- poetry/utils/appdirs.py | 24 +++-- poetry/utils/env.py | 91 +++++++++++-------- poetry/utils/extras.py | 3 +- poetry/utils/helpers.py | 14 ++- poetry/utils/password_manager.py | 39 +++++--- poetry/utils/setup_reader.py | 4 +- poetry/utils/shell.py | 7 +- poetry/version/version_selector.py | 16 +++- 88 files changed, 859 insertions(+), 429 deletions(-) diff --git a/poetry/config/config.py b/poetry/config/config.py index 6be9457cffe..79c7a75e95a 100644 --- a/poetry/config/config.py +++ b/poetry/config/config.py @@ -19,11 +19,11 @@ _NOT_SET = object() -def boolean_validator(val): +def boolean_validator(val): # type: (str) -> bool return val in {"true", "false", "1", "0"} -def boolean_normalizer(val): +def boolean_normalizer(val): # type: (str) -> bool return val in ["true", "1"] @@ -51,11 +51,11 @@ def __init__( self._auth_config_source = DictConfigSource() @property - def name(self): + def name(self): # type: () -> str return str(self._file.path) @property - def config(self): + def config(self): # type: () -> Dict return self._config @property @@ -82,7 +82,7 @@ def merge(self, config): # type: (Dict[str, Any]) -> None merge_dicts(self._config, config) def all(self): # type: () -> Dict[str, Any] - def _all(config, parent_key=""): + def _all(config, parent_key=""): # type: (Dict, str) -> Dict all_ = {} for key in config: diff --git a/poetry/config/file_config_source.py b/poetry/config/file_config_source.py index ed4e3a8522e..3e7cf71a5d9 100644 --- a/poetry/config/file_config_source.py +++ b/poetry/config/file_config_source.py @@ -1,6 +1,7 @@ from contextlib import contextmanager from typing import TYPE_CHECKING from typing import Any +from typing import Generator from tomlkit import document from tomlkit import table @@ -9,6 +10,8 @@ if TYPE_CHECKING: + from tomlkit.toml_document import TOMLDocument # noqa + from poetry.core.toml.file import TOMLFile # noqa @@ -56,7 +59,7 @@ def remove_property(self, key): # type: (str) -> None current_config = current_config[key] @contextmanager - def secure(self): + def secure(self): # type: () -> Generator["TOMLDocument"] if self.file.exists(): initial_config = self.file.read() config = self.file.read() diff --git a/poetry/console/__init__.py b/poetry/console/__init__.py index c0c25738482..56adf27e2ee 100644 --- a/poetry/console/__init__.py +++ b/poetry/console/__init__.py @@ -1,5 +1,5 @@ from .application import Application -def main(): +def main(): # type: () -> int return Application().run() diff --git a/poetry/console/application.py b/poetry/console/application.py index 027fec85776..1fd9dbc0bc3 100644 --- a/poetry/console/application.py +++ b/poetry/console/application.py @@ -1,5 +1,7 @@ import sys +from typing import TYPE_CHECKING + from cleo import Application as BaseApplication from poetry.__version__ import __version__ @@ -29,8 +31,12 @@ from .config import ApplicationConfig +if TYPE_CHECKING: + from poetry.poetry import Poetry # noqa + + class Application(BaseApplication): - def __init__(self): + def __init__(self): # type: () -> None super(Application, self).__init__( "poetry", __version__, config=ApplicationConfig("poetry", __version__) ) @@ -59,7 +65,7 @@ def __init__(self): self._preliminary_io.error_line("{}\n".format(message)) @property - def poetry(self): + def poetry(self): # type: () -> "Poetry" from pathlib import Path from poetry.factory import Factory diff --git a/poetry/console/commands/about.py b/poetry/console/commands/about.py index a84a2b6fec6..c4415591814 100644 --- a/poetry/console/commands/about.py +++ b/poetry/console/commands/about.py @@ -7,7 +7,7 @@ class AboutCommand(Command): description = "Shows information about Poetry." - def handle(self): + def handle(self): # type: () -> None self.line( """Poetry - Package Management for Python diff --git a/poetry/console/commands/add.py b/poetry/console/commands/add.py index 72ddeb015c1..a3868b4bff8 100644 --- a/poetry/console/commands/add.py +++ b/poetry/console/commands/add.py @@ -68,7 +68,7 @@ class AddCommand(InstallerCommand, InitCommand): loggers = ["poetry.repositories.pypi_repository", "poetry.inspection.info"] - def handle(self): + def handle(self): # type: () -> int from tomlkit import inline_table from poetry.core.semver import parse_constraint diff --git a/poetry/console/commands/build.py b/poetry/console/commands/build.py index 72b7319fcd5..bd938764726 100644 --- a/poetry/console/commands/build.py +++ b/poetry/console/commands/build.py @@ -18,7 +18,7 @@ class BuildCommand(EnvCommand): "poetry.core.masonry.builders.wheel", ] - def handle(self): + def handle(self): # type: () -> None from poetry.core.masonry import Builder fmt = "all" diff --git a/poetry/console/commands/cache/cache.py b/poetry/console/commands/cache/cache.py index 695e27e0af7..ff04fecb041 100644 --- a/poetry/console/commands/cache/cache.py +++ b/poetry/console/commands/cache/cache.py @@ -11,5 +11,5 @@ class CacheCommand(Command): commands = [CacheClearCommand(), CacheListCommand()] - def handle(self): + def handle(self): # type: () -> int return self.call("help", self._config.name) diff --git a/poetry/console/commands/cache/clear.py b/poetry/console/commands/cache/clear.py index 42e71091526..9969ebbaa1c 100644 --- a/poetry/console/commands/cache/clear.py +++ b/poetry/console/commands/cache/clear.py @@ -14,7 +14,7 @@ class CacheClearCommand(Command): arguments = [argument("cache", description="The name of the cache to clear.")] options = [option("all", description="Clear all entries in the cache.")] - def handle(self): + def handle(self): # type: () -> int from cachy import CacheManager from poetry.locations import REPOSITORY_CACHE_DIR diff --git a/poetry/console/commands/cache/list.py b/poetry/console/commands/cache/list.py index 6a030fa2eba..090cba601df 100644 --- a/poetry/console/commands/cache/list.py +++ b/poetry/console/commands/cache/list.py @@ -1,5 +1,7 @@ import os +from typing import Optional + from ..command import Command @@ -8,7 +10,7 @@ class CacheListCommand(Command): name = "list" description = "List Poetry's caches." - def handle(self): + def handle(self): # type: () -> Optional[int] from poetry.locations import REPOSITORY_CACHE_DIR if os.path.exists(str(REPOSITORY_CACHE_DIR)): diff --git a/poetry/console/commands/check.py b/poetry/console/commands/check.py index 72c7ca4d947..62af8379163 100644 --- a/poetry/console/commands/check.py +++ b/poetry/console/commands/check.py @@ -11,7 +11,7 @@ class CheckCommand(Command): name = "check" description = "Checks the validity of the pyproject.toml file." - def handle(self): + def handle(self): # type: () -> int # Load poetry config and display errors, if any poetry_file = Factory.locate(Path.cwd()) config = PyProjectTOML(poetry_file).poetry_config diff --git a/poetry/console/commands/command.py b/poetry/console/commands/command.py index 1e22142341a..a575f46044a 100644 --- a/poetry/console/commands/command.py +++ b/poetry/console/commands/command.py @@ -1,12 +1,18 @@ +from typing import TYPE_CHECKING + from cleo import Command as BaseCommand +if TYPE_CHECKING: + from poetry.poetry import Poetry # noqa + + class Command(BaseCommand): loggers = [] @property - def poetry(self): + def poetry(self): # type: () -> "Poetry" return self.application.poetry def reset_poetry(self): # type: () -> None diff --git a/poetry/console/commands/config.py b/poetry/console/commands/config.py index 310524d4ee2..5b35eb5a26d 100644 --- a/poetry/console/commands/config.py +++ b/poetry/console/commands/config.py @@ -1,6 +1,13 @@ import json import re +from typing import TYPE_CHECKING +from typing import Any +from typing import Dict +from typing import List +from typing import Optional +from typing import Tuple + from cleo import argument from cleo import option @@ -11,6 +18,10 @@ from .command import Command +if TYPE_CHECKING: + from poetry.config.config_source import ConfigSource # noqa + + class ConfigCommand(Command): name = "config" @@ -40,7 +51,7 @@ class ConfigCommand(Command): LIST_PROHIBITED_SETTINGS = {"http-basic", "pypi-token"} @property - def unique_config_values(self): + def unique_config_values(self): # type: () -> Dict[str, Tuple[Any, Any, Any]] from pathlib import Path from poetry.config.config import boolean_normalizer @@ -75,7 +86,7 @@ def unique_config_values(self): return unique_config_values - def handle(self): + def handle(self): # type: () -> Optional[int] from pathlib import Path from poetry.config.file_config_source import FileConfigSource @@ -253,7 +264,9 @@ def handle(self): raise ValueError("Setting {} does not exist".format(self.argument("key"))) - def _handle_single_value(self, source, key, callbacks, values): + def _handle_single_value( + self, source, key, callbacks, values + ): # type: ("ConfigSource", str, Tuple[Any, Any, Any], List[Any]) -> int validator, normalizer, _ = callbacks if len(values) > 1: @@ -267,7 +280,7 @@ def _handle_single_value(self, source, key, callbacks, values): return 0 - def _list_configuration(self, config, raw, k=""): + def _list_configuration(self, config, raw, k=""): # type: (Dict, Dict, str) -> None orig_k = k for key, value in sorted(config.items()): if k + key in self.LIST_PROHIBITED_SETTINGS: @@ -301,7 +314,9 @@ def _list_configuration(self, config, raw, k=""): self.line(message) - def _get_setting(self, contents, setting=None, k=None, default=None): + def _get_setting( + self, contents, setting=None, k=None, default=None + ): # type: (Dict, Optional[str], Optional[str], Optional[Any]) -> List[Tuple[str, str]] orig_k = k if setting and setting.split(".")[0] not in contents: diff --git a/poetry/console/commands/debug/info.py b/poetry/console/commands/debug/info.py index 81096a6ffc8..8950a3e5710 100644 --- a/poetry/console/commands/debug/info.py +++ b/poetry/console/commands/debug/info.py @@ -10,7 +10,7 @@ class DebugInfoCommand(Command): name = "info" description = "Shows debug information." - def handle(self): + def handle(self): # type: () -> int poetry_python_version = ".".join(str(s) for s in sys.version_info[:3]) self.line("") diff --git a/poetry/console/commands/debug/resolve.py b/poetry/console/commands/debug/resolve.py index 52ae1951b21..743ef1d7443 100644 --- a/poetry/console/commands/debug/resolve.py +++ b/poetry/console/commands/debug/resolve.py @@ -1,3 +1,5 @@ +from typing import Optional + from cleo import argument from cleo import option @@ -27,7 +29,7 @@ class DebugResolveCommand(InitCommand): loggers = ["poetry.repositories.pypi_repository", "poetry.inspection.info"] - def handle(self): + def handle(self): # type: () -> Optional[int] from poetry.core.packages.project_package import ProjectPackage from poetry.factory import Factory from poetry.io.null_io import NullIO diff --git a/poetry/console/commands/env/info.py b/poetry/console/commands/env/info.py index 301d88f9520..fc0e4a75936 100644 --- a/poetry/console/commands/env/info.py +++ b/poetry/console/commands/env/info.py @@ -1,8 +1,15 @@ +from typing import TYPE_CHECKING +from typing import Optional + from cleo import option from ..command import Command +if TYPE_CHECKING: + from poetry.utils.env import Env # noqa + + class EnvInfoCommand(Command): name = "info" @@ -10,7 +17,7 @@ class EnvInfoCommand(Command): options = [option("path", "p", "Only display the environment's path.")] - def handle(self): + def handle(self): # type: () -> Optional[int] from poetry.utils.env import EnvManager env = EnvManager(self.poetry).get() @@ -25,7 +32,7 @@ def handle(self): self._display_complete_info(env) - def _display_complete_info(self, env): + def _display_complete_info(self, env): # type: ("Env") -> None env_python_version = ".".join(str(s) for s in env.version_info[:3]) self.line("") self.line("Virtualenv") diff --git a/poetry/console/commands/env/list.py b/poetry/console/commands/env/list.py index 272a853b976..46423d142c7 100644 --- a/poetry/console/commands/env/list.py +++ b/poetry/console/commands/env/list.py @@ -10,7 +10,7 @@ class EnvListCommand(Command): options = [option("full-path", None, "Output the full paths of the virtualenvs.")] - def handle(self): + def handle(self): # type: () -> None from poetry.utils.env import EnvManager manager = EnvManager(self.poetry) diff --git a/poetry/console/commands/env/remove.py b/poetry/console/commands/env/remove.py index 5f208851deb..4b4bca29c9d 100644 --- a/poetry/console/commands/env/remove.py +++ b/poetry/console/commands/env/remove.py @@ -12,7 +12,7 @@ class EnvRemoveCommand(Command): argument("python", "The python executable to remove the virtualenv for.") ] - def handle(self): + def handle(self): # type: () -> None from poetry.utils.env import EnvManager manager = EnvManager(self.poetry) diff --git a/poetry/console/commands/env/use.py b/poetry/console/commands/env/use.py index ef9cf3def6b..57db24c97bd 100644 --- a/poetry/console/commands/env/use.py +++ b/poetry/console/commands/env/use.py @@ -10,7 +10,7 @@ class EnvUseCommand(Command): arguments = [argument("python", "The python executable to use.")] - def handle(self): + def handle(self): # type: () -> None from poetry.utils.env import EnvManager manager = EnvManager(self.poetry) diff --git a/poetry/console/commands/env_command.py b/poetry/console/commands/env_command.py index 2fb298d7bb2..a7ae5e7bdda 100644 --- a/poetry/console/commands/env_command.py +++ b/poetry/console/commands/env_command.py @@ -1,15 +1,21 @@ +from typing import TYPE_CHECKING + from .command import Command +if TYPE_CHECKING: + from poetry.utils.env import VirtualEnv # noqa + + class EnvCommand(Command): - def __init__(self): + def __init__(self): # type: () -> None self._env = None super(EnvCommand, self).__init__() @property - def env(self): + def env(self): # type: () -> "VirtualEnv" return self._env - def set_env(self, env): + def set_env(self, env): # type: ("VirtualEnv") -> None self._env = env diff --git a/poetry/console/commands/export.py b/poetry/console/commands/export.py index 126b657b937..11ef2a37377 100644 --- a/poetry/console/commands/export.py +++ b/poetry/console/commands/export.py @@ -31,7 +31,7 @@ class ExportCommand(Command): option("with-credentials", None, "Include credentials for extra indices."), ] - def handle(self): + def handle(self): # type: () -> None fmt = self.option("format") if fmt not in Exporter.ACCEPTED_FORMATS: diff --git a/poetry/console/commands/init.py b/poetry/console/commands/init.py index ef56484abd1..92870cb614a 100644 --- a/poetry/console/commands/init.py +++ b/poetry/console/commands/init.py @@ -9,6 +9,7 @@ from pathlib import Path from typing import Dict from typing import List +from typing import Optional from typing import Tuple from typing import Union @@ -56,12 +57,12 @@ class InitCommand(Command): The init command creates a basic pyproject.toml file in the current directory. """ - def __init__(self): + def __init__(self): # type: () -> None super(InitCommand, self).__init__() self._pool = None - def handle(self): + def handle(self): # type: () -> int from pathlib import Path from poetry.core.vcs.git import GitConfig @@ -227,7 +228,7 @@ def handle(self): def _determine_requirements( self, requires, allow_prereleases=False, source=None - ): # type: (List[str], bool) -> List[Dict[str, str]] + ): # type: (List[str], bool, Optional[str]) -> List[Dict[str, Union[str, List[str]]]] if not requires: requires = [] @@ -354,7 +355,7 @@ def _determine_requirements( def _find_best_version_for_package( self, name, required_version=None, allow_prereleases=False, source=None - ): # type: (...) -> Tuple[str, str] + ): # type: (str, Optional[str], bool, Optional[str]) -> Tuple[str, str] from poetry.version.version_selector import VersionSelector selector = VersionSelector(self._get_pool()) @@ -505,7 +506,7 @@ def _format_requirements( return requires - def _validate_author(self, author, default): + def _validate_author(self, author, default): # type: (str, str) -> Optional[str] from poetry.core.packages.package import AUTHOR_REGEX author = author or default @@ -522,7 +523,7 @@ def _validate_author(self, author, default): return author - def _validate_license(self, license): + def _validate_license(self, license): # type: (str) -> str from poetry.core.spdx import license_by_id if license: @@ -530,7 +531,7 @@ def _validate_license(self, license): return license - def _get_pool(self): + def _get_pool(self): # type: () -> "Pool" from poetry.repositories import Pool from poetry.repositories.pypi_repository import PyPiRepository diff --git a/poetry/console/commands/install.py b/poetry/console/commands/install.py index 6a9ef2cb41d..96e2dca0ad6 100644 --- a/poetry/console/commands/install.py +++ b/poetry/console/commands/install.py @@ -47,7 +47,7 @@ class InstallCommand(InstallerCommand): _loggers = ["poetry.repositories.pypi_repository", "poetry.inspection.info"] - def handle(self): + def handle(self): # type: () -> int from poetry.core.masonry.utils.module import ModuleOrPackageNotFound from poetry.masonry.builders import EditableBuilder diff --git a/poetry/console/commands/installer_command.py b/poetry/console/commands/installer_command.py index 51647eff471..dd8ca1a8842 100644 --- a/poetry/console/commands/installer_command.py +++ b/poetry/console/commands/installer_command.py @@ -9,12 +9,12 @@ class InstallerCommand(EnvCommand): - def __init__(self): + def __init__(self): # type: () -> None self._installer = None # type: Optional[Installer] super(InstallerCommand, self).__init__() - def reset_poetry(self): + def reset_poetry(self): # type: () -> None super(InstallerCommand, self).reset_poetry() self._installer.set_package(self.poetry.package) diff --git a/poetry/console/commands/lock.py b/poetry/console/commands/lock.py index 4157c02c5cc..59beb1386e2 100644 --- a/poetry/console/commands/lock.py +++ b/poetry/console/commands/lock.py @@ -24,7 +24,7 @@ class LockCommand(InstallerCommand): loggers = ["poetry.repositories.pypi_repository"] - def handle(self): + def handle(self): # type: () -> int self._installer.use_executor( self.poetry.config.get("experimental.new-installer", False) ) diff --git a/poetry/console/commands/new.py b/poetry/console/commands/new.py index 4856ff69c96..8d709fb6c4a 100644 --- a/poetry/console/commands/new.py +++ b/poetry/console/commands/new.py @@ -19,7 +19,7 @@ class NewCommand(Command): option("src", None, "Use the src layout for the project."), ] - def handle(self): + def handle(self): # type: () -> None from pathlib import Path from poetry.core.semver import parse_constraint diff --git a/poetry/console/commands/publish.py b/poetry/console/commands/publish.py index 98d4165fd8d..cedbca85468 100644 --- a/poetry/console/commands/publish.py +++ b/poetry/console/commands/publish.py @@ -1,4 +1,5 @@ from pathlib import Path +from typing import Optional from cleo import option @@ -40,7 +41,7 @@ class PublishCommand(Command): loggers = ["poetry.masonry.publishing.publisher"] - def handle(self): + def handle(self): # type: () -> Optional[int] from poetry.publishing.publisher import Publisher publisher = Publisher(self.poetry, self.io) diff --git a/poetry/console/commands/remove.py b/poetry/console/commands/remove.py index d9a289cba7f..3fb42713ced 100644 --- a/poetry/console/commands/remove.py +++ b/poetry/console/commands/remove.py @@ -27,7 +27,7 @@ class RemoveCommand(InstallerCommand): loggers = ["poetry.repositories.pypi_repository", "poetry.inspection.info"] - def handle(self): + def handle(self): # type: () -> int packages = self.argument("packages") is_dev = self.option("dev") diff --git a/poetry/console/commands/run.py b/poetry/console/commands/run.py index 46202c52c37..bafa5ce2cea 100644 --- a/poetry/console/commands/run.py +++ b/poetry/console/commands/run.py @@ -1,3 +1,6 @@ +from typing import Any +from typing import Union + from cleo import argument from .env_command import EnvCommand @@ -19,7 +22,7 @@ def __init__(self): # type: () -> None self.config.set_args_parser(RunArgsParser()) - def handle(self): + def handle(self): # type: () -> Any args = self.argument("args") script = args[0] scripts = self.poetry.local_config.get("scripts") @@ -29,7 +32,7 @@ def handle(self): return self.env.execute(*args) - def run_script(self, script, args): + def run_script(self, script, args): # type: (Union[str, dict], str) -> Any if isinstance(script, dict): script = script["callable"] diff --git a/poetry/console/commands/search.py b/poetry/console/commands/search.py index 299dee6a96a..3ca8ac8e94d 100644 --- a/poetry/console/commands/search.py +++ b/poetry/console/commands/search.py @@ -10,7 +10,7 @@ class SearchCommand(Command): arguments = [argument("tokens", "The tokens to search for.", multiple=True)] - def handle(self): + def handle(self): # type: () -> None from poetry.repositories.pypi_repository import PyPiRepository results = PyPiRepository().search(self.argument("tokens")) diff --git a/poetry/console/commands/self/self.py b/poetry/console/commands/self/self.py index 3e5cafa9180..29a0214c230 100644 --- a/poetry/console/commands/self/self.py +++ b/poetry/console/commands/self/self.py @@ -9,5 +9,5 @@ class SelfCommand(Command): commands = [SelfUpdateCommand()] - def handle(self): + def handle(self): # type: () -> int return self.call("help", self._config.name) diff --git a/poetry/console/commands/self/update.py b/poetry/console/commands/self/update.py index 7d477ddce16..279de274188 100644 --- a/poetry/console/commands/self/update.py +++ b/poetry/console/commands/self/update.py @@ -11,6 +11,8 @@ from functools import cmp_to_key from gzip import GzipFile +from typing import TYPE_CHECKING +from typing import Any from cleo import argument from cleo import option @@ -20,6 +22,12 @@ from ..command import Command +if TYPE_CHECKING: + from poetry.core.packages import Package # noqa + from poetry.core.semver import Version + from poetry.utils._compat import Path + + try: from urllib.error import HTTPError from urllib.request import urlopen @@ -61,24 +69,24 @@ class SelfUpdateCommand(Command): BASE_URL = REPOSITORY_URL + "/releases/download" @property - def home(self): + def home(self): # type: () -> Path from pathlib import Path return Path(os.environ.get("POETRY_HOME", "~/.poetry")).expanduser() @property - def bin(self): + def bin(self): # type: () -> Path return self.home / "bin" @property - def lib(self): + def lib(self): # type: () -> Path return self.home / "lib" @property - def lib_backup(self): + def lib_backup(self): # type: () -> Path return self.home / "lib-backup" - def handle(self): + def handle(self): # type: () -> None from poetry.__version__ import __version__ from poetry.core.semver import Version from poetry.repositories.pypi_repository import PyPiRepository @@ -129,7 +137,7 @@ def handle(self): self.update(release) - def update(self, release): + def update(self, release): # type: ("Package") -> None version = release.version self.line("Updating to {}".format(version)) @@ -165,7 +173,7 @@ def update(self, release): ) ) - def _update(self, version): + def _update(self, version): # type: ("Version") -> None from poetry.utils.helpers import temporary_directory release_name = self._get_release_name(version) @@ -235,10 +243,10 @@ def _update(self, version): finally: gz.close() - def process(self, *args): + def process(self, *args): # type: (*Any) -> str return subprocess.check_output(list(args), stderr=subprocess.STDOUT) - def _check_recommended_installation(self): + def _check_recommended_installation(self): # type: () -> None from pathlib import Path current = Path(__file__) @@ -250,14 +258,14 @@ def _check_recommended_installation(self): "Cannot update automatically." ) - def _get_release_name(self, version): + def _get_release_name(self, version): # type: ("Version") -> str platform = sys.platform if platform == "linux2": platform = "linux" return "poetry-{}-{}".format(version, platform) - def make_bin(self): + def make_bin(self): # type: () -> None from poetry.utils._compat import WINDOWS self.bin.mkdir(0o755, parents=True, exist_ok=True) @@ -286,7 +294,7 @@ def make_bin(self): st = os.stat(str(self.bin.joinpath("poetry"))) os.chmod(str(self.bin.joinpath("poetry")), st.st_mode | stat.S_IEXEC) - def _which_python(self): + def _which_python(self): # type: () -> str """ Decides which python executable we'll embed in the launcher script. """ diff --git a/poetry/console/commands/shell.py b/poetry/console/commands/shell.py index 033ab207e31..35269d38d3d 100644 --- a/poetry/console/commands/shell.py +++ b/poetry/console/commands/shell.py @@ -16,7 +16,7 @@ class ShellCommand(EnvCommand): If one doesn't exist yet, it will be created. """ - def handle(self): + def handle(self): # type: () -> None from poetry.utils.shell import Shell # Check if it's already activated or doesn't exist and won't be created diff --git a/poetry/console/commands/show.py b/poetry/console/commands/show.py index 86be1ae7a36..545717be8ee 100644 --- a/poetry/console/commands/show.py +++ b/poetry/console/commands/show.py @@ -1,10 +1,24 @@ # -*- coding: utf-8 -*- +from typing import TYPE_CHECKING +from typing import List +from typing import Optional +from typing import Union + from cleo import argument from cleo import option from .env_command import EnvCommand +if TYPE_CHECKING: + from clikit.api.io import IO # noqa + + from poetry.core.packages import Dependency # noqa + from poetry.core.packages import Package # noqa + from poetry.repositories import Repository + from poetry.repositories.installed_repository import InstalledRepository + + class ShowCommand(EnvCommand): name = "show" @@ -32,7 +46,7 @@ class ShowCommand(EnvCommand): colors = ["cyan", "yellow", "green", "magenta", "blue"] - def handle(self): + def handle(self): # type: () -> Optional[int] from clikit.utils.terminal import Terminal from poetry.io.null_io import NullIO @@ -257,7 +271,9 @@ def handle(self): self.line(line) - def display_package_tree(self, io, package, installed_repo): + def display_package_tree( + self, io, package, installed_repo + ): # type: ("IO", "Package", "Repository") -> None io.write("{}".format(package.pretty_name)) description = "" if package.description: @@ -294,13 +310,13 @@ def display_package_tree(self, io, package, installed_repo): def _display_tree( self, - io, - dependency, - installed_repo, - packages_in_tree, - previous_tree_bar="├", - level=1, - ): + io, # type: "IO" + dependency, # type: "Dependency" + installed_repo, # type: "Repository" + packages_in_tree, # type: List[str] + previous_tree_bar="├", # type: str + level=1, # type: int + ): # type: (...) -> None previous_tree_bar = previous_tree_bar.replace("├", "│") dependencies = [] @@ -345,7 +361,7 @@ def _display_tree( io, dependency, installed_repo, current_tree, tree_bar, level + 1 ) - def _write_tree_line(self, io, line): + def _write_tree_line(self, io, line): # type: ("IO", str) -> None if not io.output.supports_ansi(): line = line.replace("└", "`-") line = line.replace("├", "|-") @@ -354,7 +370,7 @@ def _write_tree_line(self, io, line): io.write_line(line) - def init_styles(self, io): + def init_styles(self, io): # type: ("IO") -> None from clikit.api.formatter import Style for color in self.colors: @@ -362,7 +378,9 @@ def init_styles(self, io): io.output.formatter.add_style(style) io.error_output.formatter.add_style(style) - def find_latest_package(self, package, include_dev): + def find_latest_package( + self, package, include_dev + ): # type: ("Package", bool) -> Union["Package", bool] from clikit.io import NullIO from poetry.puzzle.provider import Provider @@ -390,7 +408,7 @@ def find_latest_package(self, package, include_dev): return selector.find_best_candidate(name, ">={}".format(package.pretty_version)) - def get_update_status(self, latest, package): + def get_update_status(self, latest, package): # type: ("Package", "Package") -> str from poetry.core.semver import parse_constraint if latest.full_pretty_version == package.full_pretty_version: @@ -405,7 +423,9 @@ def get_update_status(self, latest, package): # it needs an upgrade but has potential BC breaks so is not urgent return "update-possible" - def get_installed_status(self, locked, installed_repo): + def get_installed_status( + self, locked, installed_repo + ): # type: ("Package", "InstalledRepository") -> str for package in installed_repo.packages: if locked.name == package.name: return "installed" diff --git a/poetry/console/commands/update.py b/poetry/console/commands/update.py index 9e18feb78b6..77c0adf52cc 100644 --- a/poetry/console/commands/update.py +++ b/poetry/console/commands/update.py @@ -27,7 +27,7 @@ class UpdateCommand(InstallerCommand): loggers = ["poetry.repositories.pypi_repository"] - def handle(self): + def handle(self): # type: () -> int packages = self.argument("packages") self._installer.use_executor( diff --git a/poetry/console/commands/version.py b/poetry/console/commands/version.py index 5ac5c666afb..403c357390a 100644 --- a/poetry/console/commands/version.py +++ b/poetry/console/commands/version.py @@ -40,7 +40,7 @@ class VersionCommand(Command): "prerelease", } - def handle(self): + def handle(self): # type: () -> None version = self.argument("version") if version: @@ -72,7 +72,7 @@ def handle(self): ) ) - def increment_version(self, version, rule): + def increment_version(self, version, rule): # type: (str, str) -> "Version" from poetry.core.semver import Version try: diff --git a/poetry/console/config/application_config.py b/poetry/console/config/application_config.py index 492a2137259..563e6b55db0 100644 --- a/poetry/console/config/application_config.py +++ b/poetry/console/config/application_config.py @@ -34,7 +34,7 @@ class ApplicationConfig(BaseApplicationConfig): - def configure(self): + def configure(self): # type: () -> None super(ApplicationConfig, self).configure() self.add_style(Style("c1").fg("cyan")) diff --git a/poetry/console/logging/io_formatter.py b/poetry/console/logging/io_formatter.py index 9ff57fec761..68d15691edd 100644 --- a/poetry/console/logging/io_formatter.py +++ b/poetry/console/logging/io_formatter.py @@ -1,8 +1,14 @@ import logging +from typing import TYPE_CHECKING + from .formatters import FORMATTERS +if TYPE_CHECKING: + from logging import LogRecord # noqa + + class IOFormatter(logging.Formatter): _colors = { @@ -12,7 +18,7 @@ class IOFormatter(logging.Formatter): "info": "fg=blue", } - def format(self, record): + def format(self, record): # type: ("LogRecord") -> str if not record.exc_info: level = record.levelname.lower() msg = record.msg diff --git a/poetry/console/logging/io_handler.py b/poetry/console/logging/io_handler.py index 14fd176986c..03d9607c8e5 100644 --- a/poetry/console/logging/io_handler.py +++ b/poetry/console/logging/io_handler.py @@ -1,13 +1,21 @@ import logging +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from logging import LogRecord # noqa + + from clikit.api.io import IO # noqa + class IOHandler(logging.Handler): - def __init__(self, io): + def __init__(self, io): # type: ("IO") -> None self._io = io super(IOHandler, self).__init__() - def emit(self, record): + def emit(self, record): # type: ("LogRecord") -> None try: msg = self.format(record) level = record.levelname.lower() diff --git a/poetry/factory.py b/poetry/factory.py index b38f6da25ae..0e3ef0f6046 100644 --- a/poetry/factory.py +++ b/poetry/factory.py @@ -137,7 +137,7 @@ def create_config(cls, io=None): # type: (Optional[IO]) -> Config def create_legacy_repository( self, source, auth_config - ): # type: (Dict[str, str], Config) -> LegacyRepository + ): # type: (Dict[str, str], Config) -> "LegacyRepository" from .repositories.legacy_repository import LegacyRepository from .utils.helpers import get_cert from .utils.helpers import get_client_cert diff --git a/poetry/inspection/info.py b/poetry/inspection/info.py index 94ac097aeac..495a62ca3c0 100644 --- a/poetry/inspection/info.py +++ b/poetry/inspection/info.py @@ -120,7 +120,7 @@ def load( return cls(cache_version=cache_version, **data) @classmethod - def _log(cls, msg, level="info"): + def _log(cls, msg, level="info"): # type: (str, str) -> None """Internal helper method to log information.""" getattr(logger, level)("{}: {}".format(cls.__name__, msg)) @@ -436,7 +436,7 @@ def _get_poetry_package(path): # type: (Path) -> Optional[ProjectPackage] return Factory().create_poetry(path).package @classmethod - def _pep517_metadata(cls, path): # type (Path) -> PackageInfo + def _pep517_metadata(cls, path): # type: (Path) -> PackageInfo """ Helper method to use PEP-517 library to build and read package metadata. diff --git a/poetry/installation/base_installer.py b/poetry/installation/base_installer.py index 1e068d076cd..4f600e880d4 100644 --- a/poetry/installation/base_installer.py +++ b/poetry/installation/base_installer.py @@ -1,9 +1,16 @@ +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from poetry.core.packages import Package # noqa + + class BaseInstaller: - def install(self, package): + def install(self, package): # type: ("Package") -> None raise NotImplementedError - def update(self, source, target): + def update(self, source, target): # type: ("Package", "Package") -> None raise NotImplementedError - def remove(self, package): + def remove(self, package): # type: ("Package") -> None raise NotImplementedError diff --git a/poetry/installation/chooser.py b/poetry/installation/chooser.py index 6d9e92e0b1f..1762f2ce546 100644 --- a/poetry/installation/chooser.py +++ b/poetry/installation/chooser.py @@ -1,6 +1,7 @@ import re from typing import List +from typing import Optional from typing import Tuple from packaging.tags import Tag @@ -34,12 +35,12 @@ def __init__(self, filename): # type: (str) -> None Tag(x, y, z) for x in self.pyversions for y in self.abis for z in self.plats } - def get_minimum_supported_index(self, tags): + def get_minimum_supported_index(self, tags): # type: (List[Tag]) -> Optional[int] indexes = [tags.index(t) for t in self.tags if t in tags] return min(indexes) if indexes else None - def is_supported_by_environment(self, env): + def is_supported_by_environment(self, env): # type: (Env) -> bool return bool(set(env.supported_tags).intersection(self.tags)) diff --git a/poetry/installation/executor.py b/poetry/installation/executor.py index 5523ed2813f..8123c2d6956 100644 --- a/poetry/installation/executor.py +++ b/poetry/installation/executor.py @@ -9,6 +9,10 @@ from concurrent.futures import wait from pathlib import Path from subprocess import CalledProcessError +from typing import TYPE_CHECKING +from typing import Any +from typing import List +from typing import Union from poetry.core.packages.file_dependency import FileDependency from poetry.core.packages.utils.link import Link @@ -27,8 +31,20 @@ from .operations.update import Update +if TYPE_CHECKING: + from clikit.api.io import IO # noqa + + from poetry.config.config import Config # noqa + from poetry.repositories import Pool # noqa + from poetry.utils.env import Env # noqa + + from .operations import OperationTypes # noqa + + class Executor(object): - def __init__(self, env, pool, config, io, parallel=None): + def __init__( + self, env, pool, config, io, parallel=None + ): # type: ("Env", "Pool", "Config", "IO", bool) -> None self._env = env self._io = io self._dry_run = False @@ -77,22 +93,22 @@ def removals_count(self): # type: () -> int def supports_fancy_output(self): # type: () -> bool return self._io.supports_ansi() and not self._dry_run - def disable(self): + def disable(self): # type: () -> "Executor" self._enabled = False return self - def dry_run(self, dry_run=True): + def dry_run(self, dry_run=True): # type: (bool) -> Executor self._dry_run = dry_run return self - def verbose(self, verbose=True): + def verbose(self, verbose=True): # type: (bool) -> Executor self._verbose = verbose return self - def execute(self, operations): # type: (Operation) -> int + def execute(self, operations): # type: (List["OperationTypes"]) -> int self._total_operations = len(operations) for job_type in self._executed: self._executed[job_type] = 0 @@ -145,7 +161,7 @@ def execute(self, operations): # type: (Operation) -> int return 1 if self._shutdown else 0 - def _write(self, operation, line): + def _write(self, operation, line): # type: ("OperationTypes", str) -> None if not self.supports_fancy_output() or not self._should_write_operation( operation ): @@ -163,7 +179,7 @@ def _write(self, operation, line): section.output.clear() section.write(line) - def _execute_operation(self, operation): + def _execute_operation(self, operation): # type: ("OperationTypes") -> None try: if self.supports_fancy_output(): if id(operation) not in self._sections: @@ -240,7 +256,7 @@ def _execute_operation(self, operation): with self._lock: self._shutdown = True - def _do_execute_operation(self, operation): + def _do_execute_operation(self, operation): # type: ("OperationTypes") -> int method = operation.job_type operation_message = self.get_operation_message(operation) @@ -283,7 +299,9 @@ def _do_execute_operation(self, operation): return result - def _increment_operations_count(self, operation, executed): + def _increment_operations_count( + self, operation, executed + ): # type: ("OperationTypes", bool) -> None with self._lock: if executed: self._executed_operations += 1 @@ -291,7 +309,7 @@ def _increment_operations_count(self, operation, executed): else: self._skipped[operation.job_type] += 1 - def run_pip(self, *args, **kwargs): # type: (...) -> int + def run_pip(self, *args, **kwargs): # type: (*Any, **Any) -> int try: self._env.run_pip(*args, **kwargs) except EnvCommandError as e: @@ -306,7 +324,9 @@ def run_pip(self, *args, **kwargs): # type: (...) -> int return 0 - def get_operation_message(self, operation, done=False, error=False, warning=False): + def get_operation_message( + self, operation, done=False, error=False, warning=False + ): # type: ("OperationTypes", bool, bool, bool) -> str base_tag = "fg=default" operation_color = "c2" source_operation_color = "c2" @@ -360,7 +380,7 @@ def get_operation_message(self, operation, done=False, error=False, warning=Fals return "" - def _display_summary(self, operations): + def _display_summary(self, operations): # type: (List["OperationTypes"]) -> None installs = 0 updates = 0 uninstalls = 0 @@ -403,13 +423,13 @@ def _display_summary(self, operations): ) self._io.write_line("") - def _execute_install(self, operation): # type: (Install) -> None + def _execute_install(self, operation): # type: (Union[Install, Update]) -> int return self._install(operation) - def _execute_update(self, operation): # type: (Update) -> None + def _execute_update(self, operation): # type: (Union[Install, Update]) -> int return self._update(operation) - def _execute_uninstall(self, operation): # type: (Uninstall) -> None + def _execute_uninstall(self, operation): # type: (Uninstall) -> int message = " • {message}: Removing...".format( message=self.get_operation_message(operation), ) @@ -417,7 +437,7 @@ def _execute_uninstall(self, operation): # type: (Uninstall) -> None return self._remove(operation) - def _install(self, operation): + def _install(self, operation): # type: (Union[Install, Update]) -> int package = operation.package if package.source_type == "directory": return self._install_directory(operation) @@ -444,10 +464,10 @@ def _install(self, operation): return self.run_pip(*args) - def _update(self, operation): + def _update(self, operation): # type: (Union[Install, Update]) -> int return self._install(operation) - def _remove(self, operation): + def _remove(self, operation): # type: (Uninstall) -> int package = operation.package # If we have a VCS package, remove its source directory @@ -464,7 +484,7 @@ def _remove(self, operation): raise - def _prepare_file(self, operation): + def _prepare_file(self, operation): # type: (Union[Install, Update]) -> Path package = operation.package message = " • {message}: Preparing...".format( @@ -480,7 +500,7 @@ def _prepare_file(self, operation): return archive - def _install_directory(self, operation): + def _install_directory(self, operation): # type: (Union[Install, Update]) -> int from poetry.factory import Factory package = operation.package @@ -544,7 +564,7 @@ def _install_directory(self, operation): return self.run_pip(*args) - def _install_git(self, operation): + def _install_git(self, operation): # type: (Union[Install, Update]) -> int from poetry.core.vcs import Git package = operation.package @@ -570,12 +590,14 @@ def _install_git(self, operation): return self._install_directory(operation) - def _download(self, operation): # type: (Operation) -> Path + def _download(self, operation): # type: (Union[Install, Update]) -> Link link = self._chooser.choose_for(operation.package) return self._download_link(operation, link) - def _download_link(self, operation, link): + def _download_link( + self, operation, link + ): # type: (Union[Install, Update], Link) -> Link package = operation.package archive = self._chef.get_cached_archive_for_link(link) @@ -607,7 +629,9 @@ def _download_link(self, operation, link): return archive - def _download_archive(self, operation, link): # type: (Operation, Link) -> Path + def _download_archive( + self, operation, link + ): # type: (Union[Install, Update], Link) -> Path response = self._authenticator.request( "get", link.url, stream=True, io=self._sections.get(id(operation), self._io) ) diff --git a/poetry/installation/installer.py b/poetry/installation/installer.py index 2164d39f4b1..f7eea2cdcd0 100644 --- a/poetry/installation/installer.py +++ b/poetry/installation/installer.py @@ -1,3 +1,5 @@ +from typing import TYPE_CHECKING +from typing import Iterable from typing import List from typing import Optional from typing import Union @@ -23,11 +25,17 @@ from .pip_installer import PipInstaller +if TYPE_CHECKING: + from poetry.utils.env import Env # noqa + + from .operations import OperationTypes # noqa + + class Installer: def __init__( self, io, # type: IO - env, + env, # type: "Env" package, # type: ProjectPackage locker, # type: Locker pool, # type: Pool @@ -67,11 +75,11 @@ def __init__( self._installed_repository = installed @property - def executor(self): + def executor(self): # type: () -> Executor return self._executor @property - def installer(self): + def installer(self): # type: () -> BaseInstaller return self._installer def set_package(self, package): # type: (ProjectPackage) -> Installer @@ -84,7 +92,7 @@ def set_locker(self, locker): # type: (Locker) -> Installer return self - def run(self): + def run(self): # type: () -> int # Check if refresh if not self._update and self._lock and self._locker.is_locked(): return self._do_refresh() @@ -162,7 +170,7 @@ def execute_operations(self, execute=True): # type: (bool) -> Installer return self - def whitelist(self, packages): # type: (dict) -> Installer + def whitelist(self, packages): # type: (Iterable[str]) -> Installer self._whitelist = [canonicalize_name(p) for p in packages] return self @@ -177,7 +185,7 @@ def use_executor(self, use_executor=True): # type: (bool) -> Installer return self - def _do_refresh(self): + def _do_refresh(self): # type: () -> int from poetry.puzzle import Solver # Checking extras @@ -203,7 +211,7 @@ def _do_refresh(self): return 0 - def _do_install(self, local_repo): + def _do_install(self, local_repo): # type: (Repository) -> int from poetry.puzzle import Solver locked_repository = Repository() @@ -323,7 +331,7 @@ def _write_lock_file(self, repo, force=True): # type: (Repository, bool) -> Non self._io.write_line("") self._io.write_line("Writing lock file") - def _execute(self, operations): + def _execute(self, operations): # type: (List["OperationTypes"]) -> int if self._use_executor: return self._executor.execute(operations) @@ -459,7 +467,9 @@ def _execute_uninstall(self, operation): # type: (Uninstall) -> None self._installer.remove(operation.package) - def _populate_local_repo(self, local_repo, ops): + def _populate_local_repo( + self, local_repo, ops + ): # type: (Repository, List[Operation]) -> None for op in ops: if isinstance(op, Uninstall): continue @@ -472,8 +482,8 @@ def _populate_local_repo(self, local_repo, ops): local_repo.add_package(package) def _get_operations_from_lock( - self, locked_repository # type: Repository - ): # type: (...) -> List[Operation] + self, locked_repository + ): # type: (Repository) -> List[Operation] installed_repo = self._installed_repository ops = [] diff --git a/poetry/installation/noop_installer.py b/poetry/installation/noop_installer.py index 0f0c6cda007..8b39543671f 100644 --- a/poetry/installation/noop_installer.py +++ b/poetry/installation/noop_installer.py @@ -1,29 +1,36 @@ +from typing import TYPE_CHECKING +from typing import List + from .base_installer import BaseInstaller +if TYPE_CHECKING: + from poetry.core.packages import Package # noqa + + class NoopInstaller(BaseInstaller): - def __init__(self): + def __init__(self): # type: () -> None self._installs = [] self._updates = [] self._removals = [] @property - def installs(self): + def installs(self): # type: () -> List["Package"] return self._installs @property - def updates(self): + def updates(self): # type: () -> List["Package"] return self._updates @property - def removals(self): + def removals(self): # type: () -> List["Package"] return self._removals - def install(self, package): + def install(self, package): # type: ("Package") -> None self._installs.append(package) - def update(self, source, target): + def update(self, source, target): # type: ("Package", "Package") -> None self._updates.append((source, target)) - def remove(self, package): + def remove(self, package): # type: ("Package") -> None self._removals.append(package) diff --git a/poetry/installation/operations/__init__.py b/poetry/installation/operations/__init__.py index 42573c10e8e..d7b27fe2a20 100644 --- a/poetry/installation/operations/__init__.py +++ b/poetry/installation/operations/__init__.py @@ -1,3 +1,8 @@ +from typing import Union + from .install import Install from .uninstall import Uninstall from .update import Update + + +OperationTypes = Union[Install, Uninstall, Update] diff --git a/poetry/installation/operations/install.py b/poetry/installation/operations/install.py index 48097c7c6ce..381f8f48f30 100644 --- a/poetry/installation/operations/install.py +++ b/poetry/installation/operations/install.py @@ -1,26 +1,35 @@ +from typing import TYPE_CHECKING +from typing import Optional + from .operation import Operation +if TYPE_CHECKING: + from poetry.core.packages import Package # noqa + + class Install(Operation): - def __init__(self, package, reason=None, priority=0): + def __init__( + self, package, reason=None, priority=0 + ): # type: ("Package", Optional[str], int) -> None super(Install, self).__init__(reason, priority=priority) self._package = package @property - def package(self): + def package(self): # type: () -> "Package" return self._package @property - def job_type(self): + def job_type(self): # type: () -> str return "install" - def __str__(self): + def __str__(self): # type: () -> str return "Installing {} ({})".format( self.package.pretty_name, self.format_version(self.package) ) - def __repr__(self): + def __repr__(self): # type: () -> str return "".format( self.package.pretty_name, self.format_version(self.package) ) diff --git a/poetry/installation/operations/operation.py b/poetry/installation/operations/operation.py index 0c72cc8c044..847510c80f8 100644 --- a/poetry/installation/operations/operation.py +++ b/poetry/installation/operations/operation.py @@ -1,12 +1,15 @@ # -*- coding: utf-8 -*- -from typing import Union +from typing import TYPE_CHECKING +from typing import Optional + + +if TYPE_CHECKING: + from poetry.core.packages import Package # noqa class Operation(object): - def __init__( - self, reason=None, priority=0 - ): # type: (Union[str, None], int) -> None + def __init__(self, reason=None, priority=0): # type: (Optional[str], int) -> None self._reason = reason self._skipped = False @@ -26,7 +29,7 @@ def skipped(self): # type: () -> bool return self._skipped @property - def skip_reason(self): # type: () -> Union[str, None] + def skip_reason(self): # type: () -> Optional[str] return self._skip_reason @property @@ -34,10 +37,10 @@ def priority(self): # type: () -> int return self._priority @property - def package(self): + def package(self): # type: () -> "Package" raise NotImplementedError() - def format_version(self, package): # type: (...) -> str + def format_version(self, package): # type: ("Package") -> str return package.full_pretty_version def skip(self, reason): # type: (str) -> Operation diff --git a/poetry/installation/operations/uninstall.py b/poetry/installation/operations/uninstall.py index b7e40bc606e..32c6e4e3583 100644 --- a/poetry/installation/operations/uninstall.py +++ b/poetry/installation/operations/uninstall.py @@ -1,26 +1,35 @@ +from typing import TYPE_CHECKING +from typing import Optional + from .operation import Operation +if TYPE_CHECKING: + from poetry.core.packages import Package # noqa + + class Uninstall(Operation): - def __init__(self, package, reason=None, priority=float("inf")): + def __init__( + self, package, reason=None, priority=float("inf") + ): # type: ("Package", Optional[str], int) -> None super(Uninstall, self).__init__(reason, priority=priority) self._package = package @property - def package(self): + def package(self): # type: () -> "Package" return self._package @property - def job_type(self): + def job_type(self): # type: () -> str return "uninstall" - def __str__(self): + def __str__(self): # type: () -> str return "Uninstalling {} ({})".format( self.package.pretty_name, self.format_version(self._package) ) - def __repr__(self): + def __repr__(self): # type: () -> str return "".format( self.package.pretty_name, self.format_version(self.package) ) diff --git a/poetry/installation/operations/update.py b/poetry/installation/operations/update.py index 87803fd7a23..02cd86ccfb8 100644 --- a/poetry/installation/operations/update.py +++ b/poetry/installation/operations/update.py @@ -1,30 +1,39 @@ +from typing import TYPE_CHECKING +from typing import Optional + from .operation import Operation +if TYPE_CHECKING: + from poetry.core.packages import Package # noqa + + class Update(Operation): - def __init__(self, initial, target, reason=None, priority=0): + def __init__( + self, initial, target, reason=None, priority=0 + ): # type: ("Package", "Package", Optional[str], int) -> None self._initial_package = initial self._target_package = target super(Update, self).__init__(reason, priority=priority) @property - def initial_package(self): + def initial_package(self): # type: () -> "Package" return self._initial_package @property - def target_package(self): + def target_package(self): # type: () -> "Package" return self._target_package @property - def package(self): + def package(self): # type: () -> "Package" return self._target_package @property - def job_type(self): + def job_type(self): # type: () -> str return "update" - def __str__(self): + def __str__(self): # type: () -> str return "Updating {} ({}) to {} ({})".format( self.initial_package.pretty_name, self.format_version(self.initial_package), @@ -32,7 +41,7 @@ def __str__(self): self.format_version(self.target_package), ) - def __repr__(self): + def __repr__(self): # type: () -> str return "".format( self.initial_package.pretty_name, self.format_version(self.initial_package), diff --git a/poetry/installation/pip_installer.py b/poetry/installation/pip_installer.py index df1249737a1..e4a89349d0a 100644 --- a/poetry/installation/pip_installer.py +++ b/poetry/installation/pip_installer.py @@ -3,6 +3,9 @@ import urllib.parse from subprocess import CalledProcessError +from typing import TYPE_CHECKING +from typing import Any +from typing import Union from clikit.api.io import IO @@ -15,13 +18,17 @@ from .base_installer import BaseInstaller +if TYPE_CHECKING: + from poetry.core.packages import Package # noqa + + class PipInstaller(BaseInstaller): def __init__(self, env, io, pool): # type: (Env, IO, Pool) -> None self._env = env self._io = io self._pool = pool - def install(self, package, update=False): + def install(self, package, update=False): # type: ("Package", bool) -> None if package.source_type == "directory": self.install_directory(package) @@ -90,7 +97,7 @@ def install(self, package, update=False): self.run(*args) - def update(self, package, target): + def update(self, package, target): # type: ("Package", "Package") -> None if package.source_type != target.source_type: # If the source type has changed, we remove the current # package to avoid perpetual updates in some cases @@ -98,7 +105,7 @@ def update(self, package, target): self.install(target, update=True) - def remove(self, package): + def remove(self, package): # type: ("Package") -> None try: self.run("uninstall", package.name, "-y") except CalledProcessError as e: @@ -120,10 +127,10 @@ def remove(self, package): if src_dir.exists(): safe_rmtree(str(src_dir)) - def run(self, *args, **kwargs): # type: (...) -> str + def run(self, *args, **kwargs): # type: (*Any,**Any) -> str return self._env.run_pip(*args, **kwargs) - def requirement(self, package, formatted=False): + def requirement(self, package, formatted=False): # type: ("Package", bool) -> str if formatted and not package.source_type: req = "{}=={}".format(package.name, package.version) for f in package.files: @@ -164,7 +171,7 @@ def requirement(self, package, formatted=False): return "{}=={}".format(package.name, package.version) - def create_temporary_requirement(self, package): + def create_temporary_requirement(self, package): # type: ("Package") -> str fd, name = tempfile.mkstemp( "reqs.txt", "{}-{}".format(package.name, package.version) ) @@ -176,7 +183,7 @@ def create_temporary_requirement(self, package): return name - def install_directory(self, package): + def install_directory(self, package): # type: ("Package") -> Union[str, int] from poetry.factory import Factory from poetry.io.null_io import NullIO @@ -233,7 +240,7 @@ def install_directory(self, package): return self.run(*args) - def install_git(self, package): + def install_git(self, package): # type: ("Package") -> None from poetry.core.packages import Package from poetry.core.vcs import Git diff --git a/poetry/io/null_io.py b/poetry/io/null_io.py index d81cd595527..786b188a4e2 100644 --- a/poetry/io/null_io.py +++ b/poetry/io/null_io.py @@ -1,3 +1,5 @@ +from typing import Any + from cleo.io.io_mixin import IOMixin from clikit.io import NullIO as BaseNullIO @@ -7,5 +9,5 @@ class NullIO(IOMixin, BaseNullIO): A wrapper around CliKit's NullIO. """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs): # type: (*Any, **Any) -> None super(NullIO, self).__init__(*args, **kwargs) diff --git a/poetry/layouts/layout.py b/poetry/layouts/layout.py index 8a74060f06e..af5b48ad746 100644 --- a/poetry/layouts/layout.py +++ b/poetry/layouts/layout.py @@ -1,4 +1,5 @@ from typing import TYPE_CHECKING +from typing import Dict from typing import Optional from tomlkit import dumps @@ -9,7 +10,8 @@ if TYPE_CHECKING: - from poetry.core.pyproject.toml import PyProjectTOML + from poetry.core.pyproject.toml import PyProjectTOML # noqa + from poetry.utils._compat import Path # noqa TESTS_DEFAULT = u"""from {package_name} import __version__ @@ -45,21 +47,21 @@ def test_version(): """ BUILD_SYSTEM_MIN_VERSION = "1.0.0" -BUILD_SYSTEM_MAX_VERSION = None +BUILD_SYSTEM_MAX_VERSION = None # type: Optional[str] class Layout(object): def __init__( self, - project, - version="0.1.0", - description="", - readme_format="md", - author=None, - license=None, - python="*", - dependencies=None, - dev_dependencies=None, + project, # type: str + version="0.1.0", # type: str + description="", # type: str + readme_format="md", # type: str + author=None, # type: Optional[str] + license=None, # type: Optional[str] + python="*", # type: str + dependencies=None, # type: Optional[Dict[str, str]] + dev_dependencies=None, # type: Optional[Dict[str, str]] ): self._project = project self._package_name = module_name(project) @@ -76,7 +78,7 @@ def __init__( self._author = author - def create(self, path, with_tests=True): + def create(self, path, with_tests=True): # type: (Path, bool) -> None path.mkdir(parents=True, exist_ok=True) self._create_default(path) @@ -129,10 +131,10 @@ def generate_poetry_content( return content - def _create_default(self, path, src=True): + def _create_default(self, path, src=True): # type: (Path, bool) -> None raise NotImplementedError() - def _create_readme(self, path): + def _create_readme(self, path): # type: (Path) -> None if self._readme_format == "rst": readme_file = path / "README.rst" else: @@ -140,7 +142,7 @@ def _create_readme(self, path): readme_file.touch() - def _create_tests(self, path): + def _create_tests(self, path): # type: (Path) -> None tests = path / "tests" tests_init = tests / "__init__.py" tests_default = tests / "test_{}.py".format(self._package_name) @@ -155,7 +157,7 @@ def _create_tests(self, path): ) ) - def _write_poetry(self, path): + def _write_poetry(self, path): # type: ("Path") -> None content = self.generate_poetry_content() poetry = path / "pyproject.toml" diff --git a/poetry/layouts/src.py b/poetry/layouts/src.py index 06db7a71f92..a703ed2f2c2 100644 --- a/poetry/layouts/src.py +++ b/poetry/layouts/src.py @@ -1,14 +1,19 @@ # -*- coding: utf-8 -*- +from typing import TYPE_CHECKING + from .layout import Layout +if TYPE_CHECKING: + from poetry.utils._compat import Path # noqa + DEFAULT = u"""__version__ = '{version}' """ class SrcLayout(Layout): - def _create_default(self, path): + def _create_default(self, path): # type: ("Path") -> None package_path = path / "src" / self._package_name package_init = package_path / "__init__.py" diff --git a/poetry/layouts/standard.py b/poetry/layouts/standard.py index eca4c435c40..4372d71d6b1 100644 --- a/poetry/layouts/standard.py +++ b/poetry/layouts/standard.py @@ -1,14 +1,18 @@ # -*- coding: utf-8 -*- +from typing import TYPE_CHECKING + from .layout import Layout +if TYPE_CHECKING: + from poetry.utils._compat import Path # noqa DEFAULT = u"""__version__ = '{version}' """ class StandardLayout(Layout): - def _create_default(self, path): + def _create_default(self, path): # type: ("Path") -> None package_path = path / self._package_name package_init = package_path / "__init__.py" diff --git a/poetry/masonry/builders/editable.py b/poetry/masonry/builders/editable.py index dc4be9af4cc..4f4c059ce10 100644 --- a/poetry/masonry/builders/editable.py +++ b/poetry/masonry/builders/editable.py @@ -6,6 +6,8 @@ from base64 import urlsafe_b64encode from pathlib import Path +from typing import TYPE_CHECKING +from typing import List from poetry.core.masonry.builders.builder import Builder from poetry.core.masonry.builders.sdist import SdistBuilder @@ -16,6 +18,12 @@ from poetry.utils.helpers import is_dir_writable +if TYPE_CHECKING: + from clikit.api.io import IO # noqa + + from poetry.core.poetry import Poetry # noqa + from poetry.utils.env import Env # noqa + SCRIPT_TEMPLATE = """\ #!{python} from {module} import {callable_holder} @@ -30,13 +38,13 @@ class EditableBuilder(Builder): - def __init__(self, poetry, env, io): + def __init__(self, poetry, env, io): # type: ("Poetry", "Env", "IO") -> None super(EditableBuilder, self).__init__(poetry) self._env = env self._io = io - def build(self): + def build(self): # type: () -> None self._debug( " - Building package {} in editable mode".format( self._package.name @@ -58,11 +66,11 @@ def build(self): added_files += self._add_scripts() self._add_dist_info(added_files) - def _run_build_script(self, build_script): + def _run_build_script(self, build_script): # type: (Path) -> None self._debug(" - Executing build script: {}".format(build_script)) self._env.run("python", str(self._path.joinpath(build_script)), call=True) - def _setup_build(self): + def _setup_build(self): # type: () -> None builder = SdistBuilder(self._poetry) setup = self._path / "setup.py" has_setup = setup.exists() @@ -94,7 +102,7 @@ def _setup_build(self): if not has_setup: os.remove(str(setup)) - def _add_pth(self): + def _add_pth(self): # type: () -> List[Path] paths = set() for include in self._module.includes: if isinstance(include, PackageInclude) and ( @@ -126,7 +134,7 @@ def _add_pth(self): ) return [] - def _add_scripts(self): + def _add_scripts(self): # type: () -> List[Path] added = [] entry_points = self.convert_entry_points() @@ -185,7 +193,7 @@ def _add_scripts(self): return added - def _add_dist_info(self, added_files): + def _add_dist_info(self, added_files): # type: (List[Path]) -> None from poetry.core.masonry.builders.wheel import WheelBuilder added_files = added_files[:] @@ -239,7 +247,7 @@ def _add_dist_info(self, added_files): # RECORD itself is recorded with no hash or size f.write("{},,\n".format(dist_info.joinpath("RECORD"))) - def _get_file_hash(self, filepath): + def _get_file_hash(self, filepath): # type: (Path) -> str hashsum = hashlib.sha256() with filepath.open("rb") as src: while True: @@ -252,6 +260,6 @@ def _get_file_hash(self, filepath): return urlsafe_b64encode(hashsum.digest()).decode("ascii").rstrip("=") - def _debug(self, msg): + def _debug(self, msg): # type: (str) -> None if self._io.is_debug(): self._io.write_line(msg) diff --git a/poetry/mixology/__init__.py b/poetry/mixology/__init__.py index 50fbffb27cb..8dd76488438 100644 --- a/poetry/mixology/__init__.py +++ b/poetry/mixology/__init__.py @@ -1,7 +1,21 @@ +from typing import TYPE_CHECKING +from typing import Dict +from typing import List + from .version_solver import VersionSolver -def resolve_version(root, provider, locked=None, use_latest=None): +if TYPE_CHECKING: + from poetry.core.packages import DependencyPackage # noqa + from poetry.core.packages import ProjectPackage # noqa + from poetry.puzzle.provider import Provider # noqa + + from .result import SolverResult # noqa + + +def resolve_version( + root, provider, locked=None, use_latest=None +): # type: ("ProjectPackage", "Provider", Dict[str, "DependencyPackage"],List[str]) -> "SolverResult" solver = VersionSolver(root, provider, locked=locked, use_latest=use_latest) return solver.solve() diff --git a/poetry/mixology/assignment.py b/poetry/mixology/assignment.py index e288c5da520..21765a22fe5 100644 --- a/poetry/mixology/assignment.py +++ b/poetry/mixology/assignment.py @@ -1,15 +1,25 @@ +from typing import TYPE_CHECKING from typing import Any +from typing import Optional -from .incompatibility import Incompatibility from .term import Term +if TYPE_CHECKING: + from poetry.core.packages import Dependency # noqa + from poetry.core.packages import Package # noqa + + from .incompatibility import Incompatibility # noqa + + class Assignment(Term): """ A term in a PartialSolution that tracks some additional metadata. """ - def __init__(self, dependency, is_positive, decision_level, index, cause=None): + def __init__( + self, dependency, is_positive, decision_level, index, cause=None + ): # type: ("Dependency", bool, int, int, Optional["Incompatibility"]) -> None super(Assignment, self).__init__(dependency, is_positive) self._decision_level = decision_level @@ -25,19 +35,19 @@ def index(self): # type: () -> int return self._index @property - def cause(self): # type: () -> Incompatibility + def cause(self): # type: () -> "Incompatibility" return self._cause @classmethod def decision( cls, package, decision_level, index - ): # type: (Any, int, int) -> Assignment + ): # type: ("Package", int, int) -> Assignment return cls(package.to_dependency(), True, decision_level, index) @classmethod def derivation( cls, dependency, is_positive, cause, decision_level, index - ): # type: (Any, bool, Incompatibility, int, int) -> Assignment + ): # type: (Any, bool, "Incompatibility", int, int) -> "Assignment" return cls(dependency, is_positive, decision_level, index, cause) def is_decision(self): # type: () -> bool diff --git a/poetry/mixology/failure.py b/poetry/mixology/failure.py index afa332085b3..daffd12b94b 100644 --- a/poetry/mixology/failure.py +++ b/poetry/mixology/failure.py @@ -1,5 +1,6 @@ from typing import Dict from typing import List +from typing import Optional from typing import Tuple from poetry.core.semver import parse_constraint @@ -14,10 +15,10 @@ def __init__(self, incompatibility): # type: (Incompatibility) -> None self._incompatibility = incompatibility @property - def message(self): + def message(self): # type: () -> str return str(self) - def __str__(self): + def __str__(self): # type: () -> str return _Writer(self._incompatibility).write() @@ -25,12 +26,12 @@ class _Writer: def __init__(self, root): # type: (Incompatibility) -> None self._root = root self._derivations = {} # type: Dict[Incompatibility, int] - self._lines = [] # type: List[Tuple[str, int]] + self._lines = [] # type: List[Tuple[str, Optional[int]]] self._line_numbers = {} # type: Dict[Incompatibility, int] self._count_derivations(self._root) - def write(self): + def write(self): # type: () -> str buffer = [] required_python_version_notification = False @@ -113,7 +114,7 @@ def _visit( conjunction = "So," if conclusion or incompatibility == self._root else "And" incompatibility_string = str(incompatibility) - cause = incompatibility.cause # type: ConflictCause + cause = incompatibility.cause details_for_cause = {} if isinstance(cause.conflict.cause, ConflictCause) and isinstance( cause.other.cause, ConflictCause diff --git a/poetry/mixology/incompatibility.py b/poetry/mixology/incompatibility.py index a5be2dadbdf..1e9a20440f3 100644 --- a/poetry/mixology/incompatibility.py +++ b/poetry/mixology/incompatibility.py @@ -1,6 +1,8 @@ from typing import Dict from typing import Generator from typing import List +from typing import Optional +from typing import Union from .incompatibility_cause import ConflictCause from .incompatibility_cause import DependencyCause @@ -82,11 +84,15 @@ def terms(self): # type: () -> List[Term] return self._terms @property - def cause(self): # type: () -> IncompatibilityCause + def cause( + self, + ): # type: () -> Union[RootCause, NoVersionsCause, DependencyCause, ConflictCause, PythonCause, PlatformCause, PackageNotFoundCause] return self._cause @property - def external_incompatibilities(self): # type: () -> Generator[Incompatibility] + def external_incompatibilities( + self, + ): # type: () -> Generator[Union[ConflictCause, Incompatibility]] """ Returns all external incompatibilities in this incompatibility's derivation graph. @@ -106,7 +112,7 @@ def is_failure(self): # type: () -> bool len(self._terms) == 1 and self._terms[0].dependency.is_root ) - def __str__(self): + def __str__(self): # type: () -> str if isinstance(self._cause, DependencyCause): assert len(self._terms) == 2 @@ -222,7 +228,7 @@ def __str__(self): def and_to_string( self, other, details, this_line, other_line - ): # type: (Incompatibility, dict, int, int) -> str + ): # type: (Incompatibility, dict, Optional[int], Optional[int]) -> str requires_both = self._try_requires_both(other, details, this_line, other_line) if requires_both is not None: return requires_both @@ -241,18 +247,18 @@ def and_to_string( buffer = [str(self)] if this_line is not None: - buffer.append(" " + this_line) + buffer.append(" " + str(this_line)) buffer.append(" and {}".format(str(other))) if other_line is not None: - buffer.append(" " + other_line) + buffer.append(" " + str(other_line)) return "\n".join(buffer) def _try_requires_both( self, other, details, this_line, other_line - ): # type: (Incompatibility, dict, int, int) -> str + ): # type: (Incompatibility, dict, Optional[int], Optional[int]) -> Optional[str] if len(self._terms) == 1 or len(other.terms) == 1: return @@ -298,7 +304,7 @@ def _try_requires_both( def _try_requires_through( self, other, details, this_line, other_line - ): # type: (Incompatibility, dict, int, int) -> str + ): # type: (Incompatibility, dict, int, int) -> Optional[str] if len(self._terms) == 1 or len(other.terms) == 1: return @@ -376,7 +382,7 @@ def _try_requires_through( def _try_requires_forbidden( self, other, details, this_line, other_line - ): # type: (Incompatibility, dict, int, int) -> str + ): # type: (Incompatibility, dict, int, int) -> Optional[str] if len(self._terms) != 1 and len(other.terms) != 1: return None @@ -430,13 +436,13 @@ def _try_requires_forbidden( return "".join(buffer) - def _terse(self, term, allow_every=False): + def _terse(self, term, allow_every=False): # type: (Term, bool) -> str if allow_every and term.constraint.is_any(): return "every version of {}".format(term.dependency.complete_name) return str(term.dependency) - def _single_term_where(self, callable): # type: (callable) -> Term + def _single_term_where(self, callable): # type: (callable) -> Optional[Term] found = None for term in self._terms: if not callable(term): @@ -449,5 +455,5 @@ def _single_term_where(self, callable): # type: (callable) -> Term return found - def __repr__(self): + def __repr__(self): # type: () -> str return "".format(str(self)) diff --git a/poetry/mixology/incompatibility_cause.py b/poetry/mixology/incompatibility_cause.py index 8156b4fa42b..227b9dd0e81 100644 --- a/poetry/mixology/incompatibility_cause.py +++ b/poetry/mixology/incompatibility_cause.py @@ -1,3 +1,10 @@ +from typing import TYPE_CHECKING + + +if TYPE_CHECKING: + from poetry.mixology.incompatibility import Incompatibility # noqa + + class IncompatibilityCause(Exception): """ The reason and Incompatibility's terms are incompatible. @@ -25,19 +32,21 @@ class ConflictCause(IncompatibilityCause): during conflict resolution. """ - def __init__(self, conflict, other): + def __init__( + self, conflict, other + ): # type: ("Incompatibility", "Incompatibility") -> None self._conflict = conflict self._other = other @property - def conflict(self): + def conflict(self): # type: () -> "Incompatibility" return self._conflict @property - def other(self): + def other(self): # type: () -> "Incompatibility" return self._other - def __str__(self): + def __str__(self): # type: () -> str return str(self._conflict) @@ -48,16 +57,16 @@ class PythonCause(IncompatibilityCause): with the current python version. """ - def __init__(self, python_version, root_python_version): + def __init__(self, python_version, root_python_version): # type: (str, str) -> None self._python_version = python_version self._root_python_version = root_python_version @property - def python_version(self): + def python_version(self): # type: () -> str return self._python_version @property - def root_python_version(self): + def root_python_version(self): # type: () -> str return self._root_python_version @@ -67,11 +76,11 @@ class PlatformCause(IncompatibilityCause): (OS most likely) being incompatible with the current platform. """ - def __init__(self, platform): + def __init__(self, platform): # type: (str) -> None self._platform = platform @property - def platform(self): + def platform(self): # type: () -> str return self._platform @@ -81,9 +90,9 @@ class PackageNotFoundCause(IncompatibilityCause): source. """ - def __init__(self, error): + def __init__(self, error): # type: (Exception) -> None self._error = error @property - def error(self): + def error(self): # type: () -> Exception return self._error diff --git a/poetry/mixology/partial_solution.py b/poetry/mixology/partial_solution.py index 55230425ce8..93a6f73a2fb 100644 --- a/poetry/mixology/partial_solution.py +++ b/poetry/mixology/partial_solution.py @@ -1,15 +1,19 @@ +from typing import TYPE_CHECKING from typing import Dict from typing import List -from poetry.core.packages import Dependency -from poetry.core.packages import Package - from .assignment import Assignment from .incompatibility import Incompatibility from .set_relation import SetRelation from .term import Term +if TYPE_CHECKING: + from poetry.core.packages import Dependency # noqa + from poetry.core.packages import Package # noqa + from poetry.packages import DependencyPackage # noqa + + class PartialSolution: """ # A list of Assignments that represent the solver's current best guess about @@ -19,13 +23,13 @@ class PartialSolution: # See https://github.com/dart-lang/mixology/tree/master/doc/solver.md#partial-solution. """ - def __init__(self): + def __init__(self): # type: () -> None # The assignments that have been made so far, in the order they were # assigned. self._assignments = [] # type: List[Assignment] # The decisions made for each package. - self._decisions = dict() # type: Dict[str, Package] + self._decisions = dict() # type: Dict[str, "Package"] # The intersection of all positive Assignments for each package, minus any # negative Assignments that refer to that package. @@ -48,7 +52,7 @@ def __init__(self): self._backtracking = False @property - def decisions(self): # type: () -> List[Package] + def decisions(self): # type: () -> List["Package"] return list(self._decisions.values()) @property @@ -60,14 +64,14 @@ def attempted_solutions(self): # type: () -> int return self._attempted_solutions @property - def unsatisfied(self): # type: () -> List[Dependency] + def unsatisfied(self): # type: () -> List["Dependency"] return [ term.dependency for term in self._positive.values() if term.dependency.complete_name not in self._decisions ] - def decide(self, package): # type: (Package) -> None + def decide(self, package): # type: ("Package") -> None """ Adds an assignment of package as a decision and increments the decision level. @@ -88,7 +92,7 @@ def decide(self, package): # type: (Package) -> None def derive( self, dependency, is_positive, cause - ): # type: (Dependency, bool, Incompatibility) -> None + ): # type: ("Dependency", bool, Incompatibility) -> None """ Adds an assignment of package as a derivation. """ @@ -170,7 +174,7 @@ def satisfier(self, term): # type: (Term) -> Assignment Returns the first Assignment in this solution such that the sublist of assignments up to and including that entry collectively satisfies term. """ - assigned_term = None # type: Term + assigned_term = None for assignment in self._assignments: if assignment.dependency.complete_name != term.dependency.complete_name: diff --git a/poetry/mixology/result.py b/poetry/mixology/result.py index 5eadeb75ddc..62a5029e5e3 100644 --- a/poetry/mixology/result.py +++ b/poetry/mixology/result.py @@ -1,13 +1,24 @@ +from typing import TYPE_CHECKING +from typing import List + + +if TYPE_CHECKING: + from poetry.core.packages import Package # noqa + from poetry.core.packages import ProjectPackage # noqa + + class SolverResult: - def __init__(self, root, packages, attempted_solutions): + def __init__( + self, root, packages, attempted_solutions + ): # type: ("ProjectPackage", List["Package"], int) -> None self._root = root self._packages = packages self._attempted_solutions = attempted_solutions @property - def packages(self): + def packages(self): # type: () -> List["Package"] return self._packages @property - def attempted_solutions(self): + def attempted_solutions(self): # type: () -> int return self._attempted_solutions diff --git a/poetry/mixology/solutions/solutions/python_requirement_solution.py b/poetry/mixology/solutions/solutions/python_requirement_solution.py index 9ec7cf22301..b24f7f09915 100644 --- a/poetry/mixology/solutions/solutions/python_requirement_solution.py +++ b/poetry/mixology/solutions/solutions/python_requirement_solution.py @@ -1,8 +1,15 @@ +from typing import TYPE_CHECKING +from typing import List + from crashtest.contracts.solution import Solution +if TYPE_CHECKING: + from poetry.mixology.incompatibility_cause import PackageNotFoundCause # noqa + + class PythonRequirementSolution(Solution): - def __init__(self, exception): + def __init__(self, exception): # type: ("PackageNotFoundCause") -> None from poetry.core.semver import parse_constraint from poetry.mixology.incompatibility_cause import PythonCause @@ -37,15 +44,15 @@ def __init__(self, exception): self._description = description @property - def solution_title(self) -> str: + def solution_title(self): # type: () -> str return self._title @property - def solution_description(self): + def solution_description(self): # type: () -> str return self._description @property - def documentation_links(self): + def documentation_links(self): # type: () -> List[str] return [ "https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies", "https://python-poetry.org/docs/dependency-specification/#using-environment-markers", diff --git a/poetry/mixology/term.py b/poetry/mixology/term.py index 0889e984a3b..b232e268af0 100644 --- a/poetry/mixology/term.py +++ b/poetry/mixology/term.py @@ -1,11 +1,16 @@ # -*- coding: utf-8 -*- -from typing import Union +from typing import TYPE_CHECKING +from typing import Optional from poetry.core.packages import Dependency from .set_relation import SetRelation +if TYPE_CHECKING: + from poetry.core.semver import VersionTypes # noqa + + class Term(object): """ A statement about a package which is true or false for a given selection of @@ -23,11 +28,11 @@ def inverse(self): # type: () -> Term return Term(self._dependency, not self.is_positive()) @property - def dependency(self): + def dependency(self): # type: () -> Dependency return self._dependency @property - def constraint(self): + def constraint(self): # type: () -> "VersionTypes" return self._dependency.constraint def is_positive(self): # type: () -> bool @@ -106,7 +111,7 @@ def relation(self, other): # type: (Term) -> int # not foo ^1.5.0 is a superset of not foo ^1.0.0 return SetRelation.OVERLAPPING - def intersect(self, other): # type: (Term) -> Union[Term, None] + def intersect(self, other): # type: (Term) -> Optional[Term] """ Returns a Term that represents the packages allowed by both this term and another @@ -147,21 +152,23 @@ def difference(self, other): # type: (Term) -> Term """ return self.intersect(other.inverse) - def _compatible_dependency(self, other): + def _compatible_dependency(self, other): # type: (Term) -> bool return ( self.dependency.is_root or other.is_root or other.is_same_package_as(self.dependency) ) - def _non_empty_term(self, constraint, is_positive): + def _non_empty_term( + self, constraint, is_positive + ): # type: ("VersionTypes", bool) -> Optional[Term] if constraint.is_empty(): return return Term(self.dependency.with_constraint(constraint), is_positive) - def __str__(self): + def __str__(self): # type: () -> str return "{}{}".format("not " if not self.is_positive() else "", self._dependency) - def __repr__(self): + def __repr__(self): # type: () -> str return "".format(str(self)) diff --git a/poetry/mixology/version_solver.py b/poetry/mixology/version_solver.py index 8d70a0df288..1d1d19d2d55 100644 --- a/poetry/mixology/version_solver.py +++ b/poetry/mixology/version_solver.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING from typing import Dict from typing import List -from typing import Union +from typing import Optional from poetry.core.packages import Dependency from poetry.core.packages import Package @@ -130,7 +130,7 @@ def _propagate(self, package): # type: (str) -> None def _propagate_incompatibility( self, incompatibility - ): # type: (Incompatibility) -> Union[str, _conflict, None] + ): # type: (Incompatibility) -> Optional[str, _conflict] """ If incompatibility is almost satisfied by _solution, adds the negation of the unsatisfied term to _solution. @@ -317,7 +317,7 @@ def _resolve_conflict( raise SolveFailure(incompatibility) - def _choose_package_version(self): # type: () -> Union[str, None] + def _choose_package_version(self): # type: () -> Optional[str] """ Tries to select a version of a required package. @@ -331,7 +331,7 @@ def _choose_package_version(self): # type: () -> Union[str, None] # Prefer packages with as few remaining versions as possible, # so that if a conflict is necessary it's forced quickly. - def _get_min(dependency): + def _get_min(dependency): # type: (Dependency) -> int if dependency.name in self._use_latest: # If we're forced to use the latest version of a package, it effectively # only has one version to choose from. @@ -447,7 +447,7 @@ def _add_incompatibility(self, incompatibility): # type: (Incompatibility) -> N incompatibility ) - def _get_locked(self, dependency): # type: (Dependency) -> Union[Package, None] + def _get_locked(self, dependency): # type: (Dependency) -> Optional[Package] if dependency.name in self._use_latest: return @@ -460,5 +460,5 @@ def _get_locked(self, dependency): # type: (Dependency) -> Union[Package, None] return locked - def _log(self, text): + def _log(self, text): # type: (str) -> None self._provider.debug(text, self._solution.attempted_solutions) diff --git a/poetry/packages/dependency_package.py b/poetry/packages/dependency_package.py index 60c51007ed8..e375118a5b8 100644 --- a/poetry/packages/dependency_package.py +++ b/poetry/packages/dependency_package.py @@ -1,4 +1,6 @@ +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 @@ -17,7 +19,7 @@ def dependency(self): # type: () -> Dependency def package(self): # type: () -> Package return self._package - def clone(self): # type: () -> DependencyPackage + def clone(self): # type: () -> "DependencyPackage" return self.__class__(self._dependency, self._package.clone()) def with_features(self, features): # type: (List[str]) -> "DependencyPackage" @@ -26,25 +28,25 @@ def with_features(self, features): # type: (List[str]) -> "DependencyPackage" def without_features(self): # type: () -> "DependencyPackage" return self.with_features([]) - def __getattr__(self, name): + def __getattr__(self, name): # type: (str) -> Any return getattr(self._package, name) - def __setattr__(self, key, value): + def __setattr__(self, key, value): # type: (str, Any) -> None if key in {"_dependency", "_package"}: return super(DependencyPackage, self).__setattr__(key, value) setattr(self._package, key, value) - def __str__(self): + def __str__(self): # type: () -> str return str(self._package) - def __repr__(self): + def __repr__(self): # type: () -> str return repr(self._package) - def __hash__(self): + def __hash__(self): # type: () -> int return hash(self._package) - def __eq__(self, other): + def __eq__(self, other): # type: (Union[Package, "DependencyPackage"]) -> bool if isinstance(other, DependencyPackage): other = other.package diff --git a/poetry/packages/locker.py b/poetry/packages/locker.py index 8cb6d91f916..80350f66fe4 100644 --- a/poetry/packages/locker.py +++ b/poetry/packages/locker.py @@ -6,6 +6,7 @@ from copy import deepcopy from hashlib import sha256 from pathlib import Path +from typing import TYPE_CHECKING from typing import Dict from typing import Iterable from typing import Iterator @@ -26,7 +27,7 @@ import poetry.repositories from poetry.core.packages import dependency_from_pep_508 -from poetry.core.packages.package import Dependency +from poetry.core.packages.dependency import Dependency from poetry.core.packages.package import Package from poetry.core.semver import parse_constraint from poetry.core.semver.version import Version @@ -37,6 +38,9 @@ from poetry.utils.extras import get_extra_package_names +if TYPE_CHECKING: + from ptomlkit.toml_document import TOMLDocument # noqa + logger = logging.getLogger(__name__) @@ -46,7 +50,7 @@ class Locker(object): _relevant_keys = ["dependencies", "dev-dependencies", "source", "extras"] - def __init__(self, lock, local_config): # type: (Path, dict) -> None + def __init__(self, lock, local_config): # type: (Union[str, Path], dict) -> None self._lock = TOMLFile(lock) self._local_config = local_config self._lock_data = None @@ -57,7 +61,7 @@ def lock(self): # type: () -> TOMLFile return self._lock @property - def lock_data(self): + def lock_data(self): # type: () -> TOMLDocument if self._lock_data is None: self._lock_data = self._get_lock_data() @@ -382,7 +386,7 @@ def get_project_dependency_packages( yield DependencyPackage(dependency=dependency, package=package) - def set_lock_data(self, root, packages): # type: (...) -> bool + def set_lock_data(self, root, packages): # type: (Package, List[Package]) -> bool files = table() packages = self._lock_packages(packages) # Retrieving hashes @@ -427,7 +431,7 @@ def set_lock_data(self, root, packages): # type: (...) -> bool return False - def _write_lock_data(self, data): + def _write_lock_data(self, data): # type: ("TOMLDocument") -> None self.lock.write(data) # Checking lock file data consistency @@ -452,7 +456,7 @@ def _get_content_hash(self): # type: () -> str return content_hash - def _get_lock_data(self): # type: () -> dict + def _get_lock_data(self): # type: () -> "TOMLDocument" if not self._lock.exists(): raise RuntimeError("No lockfile found. Unable to read locked packages") @@ -484,9 +488,7 @@ def _get_lock_data(self): # type: () -> dict return lock_data - def _lock_packages( - self, packages - ): # type: (List['poetry.packages.Package']) -> list + def _lock_packages(self, packages): # type: (List[Package]) -> list locked = [] for package in sorted(packages, key=lambda x: x.name): diff --git a/poetry/packages/package_collection.py b/poetry/packages/package_collection.py index e10ea635bca..e572dcbfdeb 100644 --- a/poetry/packages/package_collection.py +++ b/poetry/packages/package_collection.py @@ -1,8 +1,19 @@ +from typing import TYPE_CHECKING +from typing import List +from typing import Union + from .dependency_package import DependencyPackage +if TYPE_CHECKING: + from poetry.core.packages import Dependency # noqa + from poetry.core.packages import Package # noqa + + class PackageCollection(list): - def __init__(self, dependency, packages=None): + def __init__( + self, dependency, packages=None + ): # type: (Dependency, List[Union["Package", DependencyPackage]]) -> None self._dependency = dependency if packages is None: @@ -13,7 +24,7 @@ def __init__(self, dependency, packages=None): for package in packages: self.append(package) - def append(self, package): + def append(self, package): # type: (Union["Package", DependencyPackage]) -> None if isinstance(package, DependencyPackage): package = package.package diff --git a/poetry/publishing/publisher.py b/poetry/publishing/publisher.py index 5cec7eca2fe..c6855deee2d 100644 --- a/poetry/publishing/publisher.py +++ b/poetry/publishing/publisher.py @@ -1,7 +1,10 @@ import logging from pathlib import Path +from typing import TYPE_CHECKING +from typing import List from typing import Optional +from typing import Union from poetry.utils.helpers import get_cert from poetry.utils.helpers import get_client_cert @@ -10,6 +13,13 @@ from .uploader import Uploader +if TYPE_CHECKING: + from cleo.io import BufferedIO # noqa + from cleo.io import ConsoleIO # noqa + from clikit.io import NullIO # noqa + + from ..poetry import Poetry # noqa + logger = logging.getLogger(__name__) @@ -18,7 +28,9 @@ class Publisher: Registers and publishes packages to remote repositories. """ - def __init__(self, poetry, io): + def __init__( + self, poetry, io + ): # type: ("Poetry", Union["ConsoleIO", "BufferedIO", "NullIO"]) -> None self._poetry = poetry self._package = poetry.package self._io = io @@ -26,7 +38,7 @@ def __init__(self, poetry, io): self._password_manager = PasswordManager(poetry.config) @property - def files(self): + def files(self): # type: () -> List[Path] return self._uploader.files def publish( diff --git a/poetry/publishing/uploader.py b/poetry/publishing/uploader.py index bb1673e3bff..43f4589b383 100644 --- a/poetry/publishing/uploader.py +++ b/poetry/publishing/uploader.py @@ -2,10 +2,12 @@ import io from pathlib import Path +from typing import TYPE_CHECKING from typing import Any from typing import Dict from typing import List from typing import Optional +from typing import Tuple from typing import Union import requests @@ -26,11 +28,17 @@ from poetry.utils.patterns import wheel_file_re +if TYPE_CHECKING: + from cleo.io import ConsoleIO # noqa + from clikit.io import NullIO # noqa + + from poetry.poetry import Poetry # noqa + _has_blake2 = hasattr(hashlib, "blake2b") class UploadError(Exception): - def __init__(self, error): # type: (Union[ConnectionError, HTTPError]) -> None + def __init__(self, error): # type: (Union[ConnectionError, HTTPError, str]) -> None if isinstance(error, HTTPError): message = "HTTP Error {}: {}".format( error.response.status_code, error.response.reason @@ -46,7 +54,9 @@ def __init__(self, error): # type: (Union[ConnectionError, HTTPError]) -> None class Uploader: - def __init__(self, poetry, io): + def __init__( + self, poetry, io + ): # type: ("Poetry", Union["ConsoleIO", "NullIO"]) -> None self._poetry = poetry self._package = poetry.package self._io = io @@ -54,11 +64,11 @@ def __init__(self, poetry, io): self._password = None @property - def user_agent(self): + def user_agent(self): # type: () -> str return user_agent("poetry", __version__) @property - def adapter(self): + def adapter(self): # type: () -> adapters.HTTPAdapter retry = util.Retry( connect=5, total=10, @@ -86,7 +96,7 @@ def files(self): # type: () -> List[Path] return sorted(wheels + tars) - def auth(self, username, password): + def auth(self, username, password): # type: (str, str) -> None self._username = username self._password = password @@ -101,7 +111,7 @@ def make_session(self): # type: () -> requests.Session return session - def is_authenticated(self): + def is_authenticated(self): # type: () -> bool return self._username is not None and self._password is not None def upload( @@ -326,7 +336,7 @@ def _register( return resp - def _prepare_data(self, data): + def _prepare_data(self, data): # type: (Dict) -> List[Tuple[str, str]] data_to_send = [] for key, value in data.items(): if not isinstance(value, (list, tuple)): @@ -337,7 +347,7 @@ def _prepare_data(self, data): return data_to_send - def _get_type(self, file): + def _get_type(self, file): # type: (Path) -> str exts = file.suffixes if exts[-1] == ".whl": return "bdist_wheel" diff --git a/poetry/puzzle/exceptions.py b/poetry/puzzle/exceptions.py index e2e0b0dcce7..8ae381a88ba 100644 --- a/poetry/puzzle/exceptions.py +++ b/poetry/puzzle/exceptions.py @@ -1,18 +1,22 @@ +from typing import Dict +from typing import Tuple + + class SolverProblemError(Exception): - def __init__(self, error): + def __init__(self, error): # type: (Exception) -> None self._error = error super(SolverProblemError, self).__init__(str(error)) @property - def error(self): + def error(self): # type: () -> Exception return self._error class OverrideNeeded(Exception): - def __init__(self, *overrides): + def __init__(self, *overrides): # type: (*Dict) -> None self._overrides = overrides @property - def overrides(self): + def overrides(self): # type: () -> Tuple[Dict] return self._overrides diff --git a/poetry/puzzle/provider.py b/poetry/puzzle/provider.py index e9719a924d9..43d6ed63df3 100644 --- a/poetry/puzzle/provider.py +++ b/poetry/puzzle/provider.py @@ -7,8 +7,11 @@ from pathlib import Path from tempfile import mkdtemp from typing import Any +from typing import Dict +from typing import Iterator from typing import List from typing import Optional +from typing import Union from clikit.ui.components import ProgressIndicator @@ -68,10 +71,10 @@ def __init__( def pool(self): # type: () -> Pool return self._pool - def is_debugging(self): + def is_debugging(self): # type: () -> bool return self._is_debugging - def set_overrides(self, overrides): + def set_overrides(self, overrides): # type: (Dict) -> None self._overrides = overrides def load_deferred(self, load_deferred): # type: (bool) -> None @@ -90,7 +93,9 @@ def use_environment(self, env): # type: (Env) -> Provider self._env = original_env self._python_constraint = original_python_constraint - def search_for(self, dependency): # type: (Dependency) -> List[Package] + def search_for( + self, dependency + ): # type: (Union[Dependency, VCSDependency, FileDependency, DirectoryDependency, URLDependency]) -> List[DependencyPackage] """ Search for the specifications that match the given dependency. @@ -175,7 +180,7 @@ def search_for_vcs(self, dependency): # type: (VCSDependency) -> List[Package] @classmethod def get_package_from_vcs( cls, vcs, url, branch=None, tag=None, rev=None, name=None - ): # type: (str, str, Optional[str], Optional[str]) -> Package + ): # type: (str, str, Optional[str], Optional[str], Optional[str], Optional[str]) -> Package if vcs != "git": raise ValueError("Unsupported VCS dependency {}".format(vcs)) @@ -684,7 +689,7 @@ def complete_package( return package - def debug(self, message, depth=0): + def debug(self, message, depth=0): # type: (str, int) -> None if not (self._io.is_very_verbose() or self._io.is_debug()): return @@ -771,7 +776,7 @@ def debug(self, message, depth=0): self._io.write(debug_info) @contextmanager - def progress(self): + def progress(self): # type: () -> Iterator[None] if not self._io.output.supports_ansi() or self.is_debugging(): self._io.write_line("Resolving dependencies...") yield diff --git a/poetry/puzzle/solver.py b/poetry/puzzle/solver.py index 31858bb3a1d..47e3e8153d6 100644 --- a/poetry/puzzle/solver.py +++ b/poetry/puzzle/solver.py @@ -3,17 +3,21 @@ from collections import defaultdict from contextlib import contextmanager +from typing import TYPE_CHECKING +from typing import Callable +from typing import Dict from typing import List from typing import Optional +from typing import Tuple +from typing import Union -from clikit.io import ConsoleIO +from clikit.api.io import IO from poetry.core.packages import Package from poetry.core.packages.project_package import ProjectPackage 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.mixology import resolve_version from poetry.mixology.failure import SolveFailure from poetry.packages import DependencyPackage @@ -26,6 +30,15 @@ from .provider import Provider +if TYPE_CHECKING: + from poetry.core.packages import Dependency # noqa + from poetry.core.packages import DirectoryDependency # noqa + from poetry.core.packages import FileDependency # noqa + from poetry.core.packages import URLDependency # noqa + from poetry.core.packages import VCSDependency # noqa + from poetry.installation.operations import OperationTypes # noqa + + class Solver: def __init__( self, @@ -33,7 +46,7 @@ def __init__( pool, # type: Pool installed, # type: Repository locked, # type: Repository - io, # type: ConsoleIO + io, # type: IO remove_untracked=False, # type: bool provider=None, # type: Optional[Provider] ): @@ -59,7 +72,7 @@ def use_environment(self, env): # type: (Env) -> None with self.provider.use_environment(env): yield - def solve(self, use_latest=None): # type: (...) -> List[Operation] + def solve(self, use_latest=None): # type: (List[str]) -> List["OperationTypes"] with self._provider.progress(): start = time.time() packages, depths = self._solve(use_latest=use_latest) @@ -191,7 +204,9 @@ def solve(self, use_latest=None): # type: (...) -> List[Operation] operations, key=lambda o: (-o.priority, o.package.name, o.package.version,), ) - def solve_in_compatibility_mode(self, overrides, use_latest=None): + def solve_in_compatibility_mode( + self, overrides, use_latest=None + ): # type: (Tuple[Dict], List[str]) -> Tuple[List["Package"], List[int]] locked = {} for package in self._locked.packages: locked[package.name] = DependencyPackage(package.to_dependency(), package) @@ -221,7 +236,9 @@ def solve_in_compatibility_mode(self, overrides, use_latest=None): return packages, depths - def _solve(self, use_latest=None): + def _solve( + self, use_latest=None + ): # type: (List[str]) -> Tuple[List[Package], List[int]] if self._provider._overrides: self._overrides.append(self._provider._overrides) @@ -274,18 +291,20 @@ def _solve(self, use_latest=None): class DFSNode(object): - def __init__(self, id, name, base_name): + def __init__( + self, id, name, base_name + ): # type: (Tuple[str, str, bool], str, str) -> None self.id = id self.name = name self.base_name = base_name - def reachable(self): + def reachable(self): # type: () -> List return [] - def visit(self, parents): + def visit(self, parents): # type: (List[PackageNode]) -> None pass - def __str__(self): + def __str__(self): # type: () -> str return str(self.id) @@ -295,7 +314,9 @@ class VisitedState(enum.Enum): Visited = 2 -def depth_first_search(source, aggregator): +def depth_first_search( + source, aggregator +): # type: (PackageNode, Callable) -> List[Tuple[Package, int]] back_edges = defaultdict(list) visited = {} topo_sorted_nodes = [] @@ -322,7 +343,9 @@ def depth_first_search(source, aggregator): return results -def dfs_visit(node, back_edges, visited, sorted_nodes): +def dfs_visit( + node, back_edges, visited, sorted_nodes +): # type: (PackageNode, Dict[str, List[PackageNode]], Dict[str, VisitedState], List[PackageNode]) -> bool if visited.get(node.id, VisitedState.Unvisited) == VisitedState.Visited: return True if visited.get(node.id, VisitedState.Unvisited) == VisitedState.PartiallyVisited: @@ -343,8 +366,13 @@ def dfs_visit(node, back_edges, visited, sorted_nodes): class PackageNode(DFSNode): def __init__( - self, package, packages, previous=None, previous_dep=None, dep=None, - ): + self, + package, # type: Package + packages, # type: List[Package] + previous=None, # type: Optional[PackageNode] + previous_dep=None, # type: Optional[Union["DirectoryDependency", "FileDependency", "URLDependency", "VCSDependency", "Dependency"]] + dep=None, # type: Optional[Union["DirectoryDependency", "FileDependency", "URLDependency", "VCSDependency", "Dependency"]] + ): # type: (...) -> None self.package = package self.packages = packages @@ -366,7 +394,7 @@ def __init__( package.name, ) - def reachable(self): + def reachable(self): # type: () -> List[PackageNode] children = [] # type: List[PackageNode] if ( @@ -413,7 +441,7 @@ def reachable(self): return children - def visit(self, parents): + def visit(self, parents): # type: (PackageNode) -> None # The root package, which has no parents, is defined as having depth -1 # So that the root package's top-level dependencies have depth 0. self.depth = 1 + max( @@ -425,7 +453,9 @@ def visit(self, parents): ) -def aggregate_package_nodes(nodes, children): +def aggregate_package_nodes( + nodes, children +): # type: (List[PackageNode], List[PackageNode]) -> Tuple[Package, int] package = nodes[0].package depth = max(node.depth for node in nodes) category = ( diff --git a/poetry/repositories/base_repository.py b/poetry/repositories/base_repository.py index 46422ca0edc..801056661a1 100644 --- a/poetry/repositories/base_repository.py +++ b/poetry/repositories/base_repository.py @@ -1,19 +1,31 @@ +from typing import TYPE_CHECKING +from typing import List +from typing import Optional + + +if TYPE_CHECKING: + from poetry.core.packages import Dependency # noqa + from poetry.core.packages import Package # noqa + + class BaseRepository(object): - def __init__(self): + def __init__(self): # type: () -> None self._packages = [] @property - def packages(self): + def packages(self): # type: () -> List["Package"] return self._packages - def has_package(self, package): + def has_package(self, package): # type: ("Package") -> None raise NotImplementedError() - def package(self, name, version, extras=None): + def package( + self, name, version, extras=None + ): # type: (str, str, Optional[List[str]]) -> None raise NotImplementedError() - def find_packages(self, dependency): + def find_packages(self, dependency): # type: ("Dependency") -> None raise NotImplementedError() - def search(self, query): + def search(self, query): # type: (str) -> None raise NotImplementedError() diff --git a/poetry/repositories/legacy_repository.py b/poetry/repositories/legacy_repository.py index 94e1dbf4d7b..aa870562e8b 100644 --- a/poetry/repositories/legacy_repository.py +++ b/poetry/repositories/legacy_repository.py @@ -5,9 +5,12 @@ from collections import defaultdict from pathlib import Path +from typing import TYPE_CHECKING +from typing import Any +from typing import Dict from typing import Generator +from typing import List from typing import Optional -from typing import Union import requests import requests.auth @@ -34,6 +37,9 @@ from .pypi_repository import PyPiRepository +if TYPE_CHECKING: + from poetry.core.packages import Dependency # noqa + try: from html import unescape except ImportError: @@ -69,7 +75,9 @@ class Page: ".tar", ] - def __init__(self, url, content, headers): + def __init__( + self, url, content, headers + ): # type: (str, str, Dict[str, Any]) -> None if not url.endswith("/"): url += "/" @@ -127,7 +135,7 @@ def links_for_version(self, version): # type: (Version) -> Generator[Link] if self.link_version(link) == version: yield link - def link_version(self, link): # type: (Link) -> Union[Version, None] + def link_version(self, link): # type: (Link) -> Optional[Version] m = wheel_file_re.match(link.filename) if m: version = m.group("ver") @@ -148,7 +156,7 @@ def link_version(self, link): # type: (Link) -> Union[Version, None] _clean_re = re.compile(r"[^a-z0-9$&+,/:;=?@.#%_\\|-]", re.I) - def clean_link(self, url): + def clean_link(self, url): # type: (str) -> str """Makes sure a link is fully encoded. That is, if a ' ' shows up in the link, it will be rewritten to %20 (while not over-quoting % or other characters).""" @@ -225,7 +233,7 @@ def authenticated_url(self): # type: () -> str path=parsed.path, ) - def find_packages(self, dependency): + def find_packages(self, dependency): # type: ("Dependency") -> List[Package] packages = [] constraint = dependency.constraint @@ -296,7 +304,9 @@ def find_packages(self, dependency): return packages - def package(self, name, version, extras=None): # type: (...) -> Package + def package( + self, name, version, extras=None + ): # type: (str, str, Optional[List[str]]) -> Package """ Retrieve the release information. @@ -320,7 +330,7 @@ def package(self, name, version, extras=None): # type: (...) -> Package return package - def find_links_for_package(self, package): + def find_links_for_package(self, package): # type: (Package) -> List[Link] page = self._get("/{}/".format(package.name.replace(".", "-"))) if page is None: return [] @@ -375,7 +385,7 @@ def _get_release_info(self, name, version): # type: (str, str) -> dict return data.asdict() - def _get(self, endpoint): # type: (str) -> Union[Page, None] + def _get(self, endpoint): # type: (str) -> Optional[Page] url = self._url + endpoint try: response = self.session.get(url) diff --git a/poetry/repositories/pool.py b/poetry/repositories/pool.py index ac712831d3a..d8181ba06c0 100644 --- a/poetry/repositories/pool.py +++ b/poetry/repositories/pool.py @@ -9,7 +9,8 @@ if TYPE_CHECKING: - from poetry.core.packages import Package + from poetry.core.packages import Dependency # noqa + from poetry.core.packages import Package # noqa class Pool(BaseRepository): @@ -108,12 +109,12 @@ def remove_repository(self, repository_name): # type: (str) -> Pool return self - def has_package(self, package): + def has_package(self, package): # type: ("Package") -> bool raise NotImplementedError() def package( self, name, version, extras=None, repository=None - ): # type: (str, str, List[str], str) -> Package + ): # type: (str, str, List[str], str) -> "Package" if repository is not None: repository = repository.lower() @@ -143,9 +144,7 @@ def package( raise PackageNotFound("Package {} ({}) not found.".format(name, version)) - def find_packages( - self, dependency, - ): + def find_packages(self, dependency): # type: ("Dependency") -> List["Package"] repository = dependency.source_name if repository is not None: repository = repository.lower() @@ -166,7 +165,7 @@ def find_packages( return packages - def search(self, query): + def search(self, query): # type: (str) -> List["Package"] from .legacy_repository import LegacyRepository results = [] diff --git a/poetry/repositories/pypi_repository.py b/poetry/repositories/pypi_repository.py index 715ba557379..951f305dbfc 100644 --- a/poetry/repositories/pypi_repository.py +++ b/poetry/repositories/pypi_repository.py @@ -45,7 +45,9 @@ class PyPiRepository(RemoteRepository): CACHE_VERSION = parse_constraint("1.0.0") - def __init__(self, url="https://pypi.org/", disable_cache=False, fallback=True): + def __init__( + self, url="https://pypi.org/", disable_cache=False, fallback=True + ): # type: (str, bool, bool) -> None super(PyPiRepository, self).__init__(url.rstrip("/") + "/simple/") self._base_url = url @@ -72,7 +74,7 @@ def __init__(self, url="https://pypi.org/", disable_cache=False, fallback=True): self._name = "PyPI" @property - def session(self): + def session(self): # type: () -> CacheControl return self._session def find_packages(self, dependency): # type: (Dependency) -> List[Package] @@ -156,7 +158,7 @@ def package( ): # type: (...) -> Package return self.get_release_info(name, version).to_package(name=name, extras=extras) - def search(self, query): + def search(self, query): # type: (str) -> List[Package] results = [] search = {"q": query} @@ -236,7 +238,7 @@ def get_release_info(self, name, version): # type: (str, str) -> PackageInfo return PackageInfo.load(cached) - def find_links_for_package(self, package): + def find_links_for_package(self, package): # type: (Package) -> List[Link] json_data = self._get("pypi/{}/{}/json".format(package.name, package.version)) if json_data is None: return [] @@ -452,5 +454,5 @@ def _get_info_from_sdist(self, url): # type: (str) -> PackageInfo def _download(self, url, dest): # type: (str, str) -> None return download_file(url, dest, session=self.session) - def _log(self, msg, level="info"): + def _log(self, msg, level="info"): # type: (str, str) -> None getattr(logger, level)("{}: {}".format(self._name, msg)) diff --git a/poetry/repositories/repository.py b/poetry/repositories/repository.py index 1ebe702bb9c..f65e44bafc8 100644 --- a/poetry/repositories/repository.py +++ b/poetry/repositories/repository.py @@ -1,3 +1,7 @@ +from typing import TYPE_CHECKING +from typing import List +from typing import Optional + from poetry.core.semver import VersionConstraint from poetry.core.semver import VersionRange from poetry.core.semver import parse_constraint @@ -5,8 +9,16 @@ from .base_repository import BaseRepository +if TYPE_CHECKING: + from poetry.core.packages import Dependency # noqa + from poetry.core.packages import Link # noqa + from poetry.core.packages import Package # noqa + + class Repository(BaseRepository): - def __init__(self, packages=None, name=None): + def __init__( + self, packages=None, name=None + ): # type: (List["Package"], str) -> None super(Repository, self).__init__() self._name = name @@ -18,17 +30,19 @@ def __init__(self, packages=None, name=None): self.add_package(package) @property - def name(self): + def name(self): # type: () -> str return self._name - def package(self, name, version, extras=None): + def package( + self, name, version, extras=None + ): # type: (str, str, Optional[List[str]]) -> "Package" name = name.lower() for package in self.packages: if name == package.name and package.version.text == version: return package.clone() - def find_packages(self, dependency): + def find_packages(self, dependency): # type: ("Dependency") -> List["Package"] constraint = dependency.constraint packages = [] ignored_pre_release_packages = [] @@ -71,7 +85,7 @@ def find_packages(self, dependency): return packages or ignored_pre_release_packages - def has_package(self, package): + def has_package(self, package): # type: ("Package") -> bool package_id = package.unique_name for repo_package in self.packages: @@ -80,10 +94,10 @@ def has_package(self, package): return False - def add_package(self, package): + def add_package(self, package): # type: ("Package") -> None self._packages.append(package) - def remove_package(self, package): + def remove_package(self, package): # type: ("Package") -> None package_id = package.unique_name index = None @@ -95,10 +109,10 @@ def remove_package(self, package): if index is not None: del self._packages[index] - def find_links_for_package(self, package): + def find_links_for_package(self, package): # type: ("Package") -> List["Link"] return [] - def search(self, query): + def search(self, query): # type: (str) -> List["Package"] results = [] for package in self.packages: @@ -107,5 +121,5 @@ def search(self, query): return results - def __len__(self): + def __len__(self): # type: () -> int return len(self._packages) diff --git a/poetry/utils/appdirs.py b/poetry/utils/appdirs.py index ab99506a028..aac3ad36076 100644 --- a/poetry/utils/appdirs.py +++ b/poetry/utils/appdirs.py @@ -5,11 +5,19 @@ import os import sys +from typing import TYPE_CHECKING +from typing import List +from typing import Union + + +if TYPE_CHECKING: + from poetry.utils._compat import Path # noqa + WINDOWS = sys.platform.startswith("win") or (sys.platform == "cli" and os.name == "nt") -def expanduser(path): +def expanduser(path): # type: (Union[str, "Path"]) -> str """ Expand ~ and ~user constructions. @@ -21,7 +29,7 @@ def expanduser(path): return expanded -def user_cache_dir(appname): +def user_cache_dir(appname): # type: (str) -> str r""" Return full path to the user-specific cache dir for this application. @@ -64,7 +72,7 @@ def user_cache_dir(appname): return path -def user_data_dir(appname, roaming=False): +def user_data_dir(appname, roaming=False): # type: (str, bool) -> str r""" Return full path to the user-specific data dir for this application. @@ -104,7 +112,7 @@ def user_data_dir(appname, roaming=False): return path -def user_config_dir(appname, roaming=True): +def user_config_dir(appname, roaming=True): # type: (str, bool) -> str """Return full path to the user-specific config dir for this application. "appname" is the name of application. @@ -137,7 +145,7 @@ def user_config_dir(appname, roaming=True): # for the discussion regarding site_config_dirs locations # see -def site_config_dirs(appname): +def site_config_dirs(appname): # type: (str) -> List[str] r"""Return a list of potential user-shared config dirs for this application. "appname" is the name of application. @@ -178,7 +186,7 @@ def site_config_dirs(appname): # -- Windows support functions -- -def _get_win_folder_from_registry(csidl_name): +def _get_win_folder_from_registry(csidl_name): # type: (str) -> str """ This is a fallback technique at best. I'm not sure if using the registry for this guarantees us the correct answer for all CSIDL_* @@ -200,7 +208,7 @@ def _get_win_folder_from_registry(csidl_name): return directory -def _get_win_folder_with_ctypes(csidl_name): +def _get_win_folder_with_ctypes(csidl_name): # type: (str) -> str csidl_const = { "CSIDL_APPDATA": 26, "CSIDL_COMMON_APPDATA": 35, @@ -234,7 +242,7 @@ def _get_win_folder_with_ctypes(csidl_name): _get_win_folder = _get_win_folder_from_registry -def _win_path_to_bytes(path): +def _win_path_to_bytes(path): # type: (str) -> Union[str, bytes] """Encode Windows paths to bytes. Only used on Python 2. Motivation is to be consistent with other operating systems where paths diff --git a/poetry/utils/env.py b/poetry/utils/env.py index 22db246911e..77a185130d5 100644 --- a/poetry/utils/env.py +++ b/poetry/utils/env.py @@ -15,6 +15,7 @@ from subprocess import CalledProcessError from typing import Any from typing import Dict +from typing import Iterator from typing import List from typing import Optional from typing import Tuple @@ -252,7 +253,7 @@ def find(self, path, writable_only=False): # type: (Path, bool) -> List[Path] if value[-1] is True ] - def __getattr__(self, item): + def __getattr__(self, item): # type: (str) -> Any try: return super(SitePackages, self).__getattribute__(item) except AttributeError: @@ -265,7 +266,9 @@ class EnvError(Exception): class EnvCommandError(EnvError): - def __init__(self, e, input=None): # type: (CalledProcessError) -> None + def __init__( + self, e, input=None + ): # type: (CalledProcessError, Optional[str]) -> None self.e = e message = "Command {} errored with the following return code {}, and output: \n{}".format( @@ -277,7 +280,7 @@ def __init__(self, e, input=None): # type: (CalledProcessError) -> None class NoCompatiblePythonVersionFound(EnvError): - def __init__(self, expected, given=None): + def __init__(self, expected, given=None): # type: (str, Optional[str]) -> None if given: message = ( "The specified Python version ({}) " @@ -618,7 +621,7 @@ def remove(self, python): # type: (str) -> Env def create_venv( self, io, name=None, executable=None, force=False - ): # type: (IO, Optional[str], Optional[str], bool) -> Env + ): # type: (IO, Optional[str], Optional[str], bool) -> VirtualEnv if self._env is not None and not force: return self._env @@ -849,12 +852,12 @@ def remove_venv(cls, path): # type: (Union[Path,str]) -> None def get_base_prefix(self): # type: () -> Path if hasattr(sys, "real_prefix"): - return sys.real_prefix + return Path(sys.real_prefix) if hasattr(sys, "base_prefix"): - return sys.base_prefix + return Path(sys.base_prefix) - return sys.prefix + return Path(sys.prefix) @classmethod def generate_env_name(cls, name, cwd): # type: (str, str) -> str @@ -913,7 +916,7 @@ def python(self): # type: () -> str return self._bin("python") @property - def marker_env(self): + def marker_env(self): # type: () -> Dict[str, Any] if self._marker_env is None: self._marker_env = self.get_marker_env() @@ -935,7 +938,7 @@ def os(self): # type: () -> str return os.name @property - def pip_version(self): + def pip_version(self): # type: () -> Version if self._pip_version is None: self._pip_version = self.get_pip_version() @@ -1009,12 +1012,12 @@ def supported_tags(self): # type: () -> List[Tag] @classmethod def get_base_prefix(cls): # type: () -> Path if hasattr(sys, "real_prefix"): - return sys.real_prefix + return Path(sys.real_prefix) if hasattr(sys, "base_prefix"): - return sys.base_prefix + return Path(sys.base_prefix) - return sys.prefix + return Path(sys.prefix) def get_version_info(self): # type: () -> Tuple[int] raise NotImplementedError() @@ -1046,17 +1049,17 @@ def is_sane(self): # type: () -> bool """ return True - def run(self, bin, *args, **kwargs): + def run(self, bin, *args, **kwargs): # type: (str, *str, **Any) -> Union[str, int] bin = self._bin(bin) cmd = [bin] + list(args) return self._run(cmd, **kwargs) - def run_pip(self, *args, **kwargs): + def run_pip(self, *args, **kwargs): # type: (*str, **Any) -> Union[int, str] pip = self.get_pip_command() cmd = pip + list(args) return self._run(cmd, **kwargs) - def _run(self, cmd, **kwargs): + def _run(self, cmd, **kwargs): # type: (List[str], **Any) -> Union[int, str] """ Run a command inside the Python environment. """ @@ -1077,7 +1080,7 @@ def _run(self, cmd, **kwargs): stderr=subprocess.STDOUT, input=encode(input_), check=True, - **kwargs + **kwargs, ).stdout elif call: return subprocess.call(cmd, stderr=subprocess.STDOUT, **kwargs) @@ -1090,7 +1093,9 @@ def _run(self, cmd, **kwargs): return decode(output) - def execute(self, bin, *args, **kwargs): + def execute( + self, bin, *args, **kwargs + ): # type: (str, *str, **Any) -> Optional[int] bin = self._bin(bin) if not self._is_windows: @@ -1145,7 +1150,7 @@ def _bin(self, bin): # type: (str) -> str def __eq__(self, other): # type: (Env) -> bool return other.__class__ == self.__class__ and other.path == self.path - def __repr__(self): + def __repr__(self): # type: () -> str return '{}("{}")'.format(self.__class__.__name__, self._path) @@ -1332,11 +1337,11 @@ def get_paths(self): # type: () -> Dict[str, str] def is_venv(self): # type: () -> bool return True - def is_sane(self): + def is_sane(self): # type: () -> bool # A virtualenv is considered sane if both "python" and "pip" exist. return os.path.exists(self.python) and os.path.exists(self._bin("pip")) - def _run(self, cmd, **kwargs): + def _run(self, cmd, **kwargs): # type: (List[str], **Any) -> Optional[int] with self.temp_environ(): os.environ["PATH"] = self._updated_path() os.environ["VIRTUAL_ENV"] = str(self._path) @@ -1346,7 +1351,9 @@ def _run(self, cmd, **kwargs): return super(VirtualEnv, self)._run(cmd, **kwargs) - def execute(self, bin, *args, **kwargs): + def execute( + self, bin, *args, **kwargs + ): # type: (str, *str, **Any) -> Optional[int] with self.temp_environ(): os.environ["PATH"] = self._updated_path() os.environ["VIRTUAL_ENV"] = str(self._path) @@ -1357,7 +1364,7 @@ def execute(self, bin, *args, **kwargs): return super(VirtualEnv, self).execute(bin, *args, **kwargs) @contextmanager - def temp_environ(self): + def temp_environ(self): # type: () -> Iterator[None] environ = dict(os.environ) try: yield @@ -1365,16 +1372,18 @@ def temp_environ(self): os.environ.clear() os.environ.update(environ) - def unset_env(self, key): + def unset_env(self, key): # type: (str) -> None if key in os.environ: del os.environ[key] - def _updated_path(self): + def _updated_path(self): # type: () -> str return os.pathsep.join([str(self._bin_dir), os.environ.get("PATH", "")]) class NullEnv(SystemEnv): - def __init__(self, path=None, base=None, execute=False): + def __init__( + self, path=None, base=None, execute=False + ): # type: (Path, Optional[Path], bool) -> None if path is None: path = Path(sys.prefix) @@ -1386,35 +1395,37 @@ def __init__(self, path=None, base=None, execute=False): def get_pip_command(self): # type: () -> List[str] return [self._bin("python"), "-m", "pip"] - def _run(self, cmd, **kwargs): + def _run(self, cmd, **kwargs): # type: (List[str], **Any) -> int self.executed.append(cmd) if self._execute: return super(NullEnv, self)._run(cmd, **kwargs) - def execute(self, bin, *args, **kwargs): + def execute( + self, bin, *args, **kwargs + ): # type: (str, *str, **Any) -> Optional[int] self.executed.append([bin] + list(args)) if self._execute: return super(NullEnv, self).execute(bin, *args, **kwargs) - def _bin(self, bin): + def _bin(self, bin): # type: (str) -> str return bin class MockEnv(NullEnv): def __init__( self, - version_info=(3, 7, 0), - python_implementation="CPython", - platform="darwin", - os_name="posix", - is_venv=False, - pip_version="19.1", - sys_path=None, - marker_env=None, - supported_tags=None, - **kwargs + version_info=(3, 7, 0), # type: Tuple[int, int, int] + python_implementation="CPython", # type: str + platform="darwin", # type: str + os_name="posix", # type: str + is_venv=False, # type: bool + pip_version="19.1", # type: str + sys_path=None, # type: Optional[List[str]] + marker_env=None, # type: Dict[str, Any] + supported_tags=None, # type: List[Tag] + **kwargs, # type: Any ): super(MockEnv, self).__init__(**kwargs) @@ -1437,11 +1448,11 @@ def os(self): # type: () -> str return self._os_name @property - def pip_version(self): + def pip_version(self): # type: () -> Version return self._pip_version @property - def sys_path(self): + def sys_path(self): # type: () -> List[str] if self._sys_path is None: return super(MockEnv, self).sys_path diff --git a/poetry/utils/extras.py b/poetry/utils/extras.py index c97d6ee79e5..cff3f5a1ff6 100644 --- a/poetry/utils/extras.py +++ b/poetry/utils/extras.py @@ -1,3 +1,4 @@ +from typing import Iterable from typing import Iterator from typing import List from typing import Mapping @@ -36,7 +37,7 @@ def get_extra_package_names( # keep record of packages seen during recursion in order to avoid recursion error seen_package_names = set() - def _extra_packages(package_names): + def _extra_packages(package_names): # type: (Iterable[str]) -> Iterator[str] """Recursively find dependencies for packages names""" # for each extra pacakge name for package_name in package_names: diff --git a/poetry/utils/helpers.py b/poetry/utils/helpers.py index 909ec3c1438..b7bc0429045 100644 --- a/poetry/utils/helpers.py +++ b/poetry/utils/helpers.py @@ -6,6 +6,10 @@ from contextlib import contextmanager from pathlib import Path +from typing import Any +from typing import Callable +from typing import Dict +from typing import Iterator from typing import List from typing import Optional @@ -37,13 +41,13 @@ def normalize_version(version): # type: (str) -> str return str(Version(version)) -def _del_ro(action, name, exc): +def _del_ro(action, name, exc): # type: (Callable, str, Exception) -> None os.chmod(name, stat.S_IWRITE) os.remove(name) @contextmanager -def temporary_directory(*args, **kwargs): +def temporary_directory(*args, **kwargs): # type: (*Any, **Any) -> Iterator[str] name = tempfile.mkdtemp(*args, **kwargs) yield name @@ -67,7 +71,7 @@ def get_client_cert(config, repository_name): # type: (Config, str) -> Optional return None -def _on_rm_error(func, path, exc_info): +def _on_rm_error(func, path, exc_info): # type: (Callable, str, Exception) -> None if not os.path.exists(path): return @@ -75,14 +79,14 @@ def _on_rm_error(func, path, exc_info): func(path) -def safe_rmtree(path): +def safe_rmtree(path): # type: (str) -> None if Path(path).is_symlink(): return os.unlink(str(path)) shutil.rmtree(path, onerror=_on_rm_error) -def merge_dicts(d1, d2): +def merge_dicts(d1, d2): # type: (Dict, Dict) -> None for k, v in d2.items(): if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], Mapping): merge_dicts(d1[k], d2[k]) diff --git a/poetry/utils/password_manager.py b/poetry/utils/password_manager.py index 6c993840282..e6cc11d65e2 100644 --- a/poetry/utils/password_manager.py +++ b/poetry/utils/password_manager.py @@ -1,5 +1,12 @@ import logging +from typing import TYPE_CHECKING +from typing import Dict +from typing import Optional + + +if TYPE_CHECKING: + from poetry.config.config import Config # noqa logger = logging.getLogger(__name__) @@ -15,16 +22,16 @@ class KeyRingError(Exception): class KeyRing: - def __init__(self, namespace): + def __init__(self, namespace): # type: (str) -> None self._namespace = namespace self._is_available = True self._check() - def is_available(self): + def is_available(self): # type: () -> bool return self._is_available - def get_password(self, name, username): + def get_password(self, name, username): # type: (str, str) -> Optional[str] if not self.is_available(): return @@ -40,7 +47,7 @@ def get_password(self, name, username): "Unable to retrieve the password for {} from the key ring".format(name) ) - def set_password(self, name, username, password): + def set_password(self, name, username, password): # type: (str, str, str) -> None if not self.is_available(): return @@ -58,7 +65,7 @@ def set_password(self, name, username, password): ) ) - def delete_password(self, name, username): + def delete_password(self, name, username): # type: (str, str) -> None if not self.is_available(): return @@ -74,10 +81,10 @@ def delete_password(self, name, username): "Unable to delete the password for {} from the key ring".format(name) ) - def get_entry_name(self, name): + def get_entry_name(self, name): # type: (str) -> str return "{}-{}".format(self._namespace, name) - def _check(self): + def _check(self): # type: () -> None try: import keyring except Exception as e: @@ -113,12 +120,12 @@ def _check(self): class PasswordManager: - def __init__(self, config): + def __init__(self, config): # type: ("Config") -> None self._config = config self._keyring = None @property - def keyring(self): + def keyring(self): # type: () -> KeyRing if self._keyring is None: self._keyring = KeyRing("poetry-repository") if not self._keyring.is_available(): @@ -128,7 +135,7 @@ def keyring(self): return self._keyring - def set_pypi_token(self, name, token): + def set_pypi_token(self, name, token): # type: (str, str) -> None if not self.keyring.is_available(): self._config.auth_config_source.add_property( "pypi-token.{}".format(name), token @@ -136,13 +143,13 @@ def set_pypi_token(self, name, token): else: self.keyring.set_password(name, "__token__", token) - def get_pypi_token(self, name): + def get_pypi_token(self, name): # type: (str) -> str if not self.keyring.is_available(): return self._config.get("pypi-token.{}".format(name)) return self.keyring.get_password(name, "__token__") - def delete_pypi_token(self, name): + def delete_pypi_token(self, name): # type: (str) -> None if not self.keyring.is_available(): return self._config.auth_config_source.remove_property( "pypi-token.{}".format(name) @@ -150,7 +157,7 @@ def delete_pypi_token(self, name): self.keyring.delete_password(name, "__token__") - def get_http_auth(self, name): + def get_http_auth(self, name): # type: (str) -> Optional[Dict[str, str]] auth = self._config.get("http-basic.{}".format(name)) if not auth: username = self._config.get("http-basic.{}.username".format(name)) @@ -167,7 +174,9 @@ def get_http_auth(self, name): "password": password, } - def set_http_password(self, name, username, password): + def set_http_password( + self, name, username, password + ): # type: (str, str, str) -> None auth = {"username": username} if not self.keyring.is_available(): @@ -177,7 +186,7 @@ def set_http_password(self, name, username, password): self._config.auth_config_source.add_property("http-basic.{}".format(name), auth) - def delete_http_password(self, name): + def delete_http_password(self, name): # type: (str) -> None auth = self.get_http_auth(name) if not auth or "username" not in auth: return diff --git a/poetry/utils/setup_reader.py b/poetry/utils/setup_reader.py index 498210f45f5..48d511f9252 100644 --- a/poetry/utils/setup_reader.py +++ b/poetry/utils/setup_reader.py @@ -356,7 +356,9 @@ def _find_variable_in_body( if target.id == name: return elem.value - def _find_in_dict(self, dict_, name): # type: (ast.Call, str) -> Optional[Any] + def _find_in_dict( + self, dict_, name + ): # type: (Union[ast.Dict, ast.Call], str) -> Optional[Any] for key, val in zip(dict_.keys, dict_.values): if isinstance(key, ast.Str) and key.s == name: return val diff --git a/poetry/utils/shell.py b/poetry/utils/shell.py index 3c0e5fbe92c..e009903a6de 100644 --- a/poetry/utils/shell.py +++ b/poetry/utils/shell.py @@ -3,6 +3,7 @@ import sys from pathlib import Path +from typing import Any import pexpect @@ -78,7 +79,7 @@ def activate(self, env): # type: (VirtualEnv) -> None activate_path = env.path / bin_dir / activate_script c.sendline("{} {}".format(self._get_source_command(), activate_path)) - def resize(sig, data): + def resize(sig, data): # type: (Any, Any) -> None terminal = Terminal() c.setwinsize(terminal.height, terminal.width) @@ -90,7 +91,7 @@ def resize(sig, data): sys.exit(c.exitstatus) - def _get_activate_script(self): + def _get_activate_script(self): # type: () -> str if "fish" == self._name: suffix = ".fish" elif "csh" == self._name: @@ -102,7 +103,7 @@ def _get_activate_script(self): return "activate" + suffix - def _get_source_command(self): + def _get_source_command(self): # type: () -> str if "fish" == self._name: return "source" elif "csh" == self._name: diff --git a/poetry/version/version_selector.py b/poetry/version/version_selector.py index ea002860938..350e3ec7ca5 100644 --- a/poetry/version/version_selector.py +++ b/poetry/version/version_selector.py @@ -1,19 +1,25 @@ +from typing import TYPE_CHECKING +from typing import Optional from typing import Union from poetry.core.packages import Package from poetry.core.semver import Version +if TYPE_CHECKING: + from poetry.repositories import Pool # noqa + + class VersionSelector(object): - def __init__(self, pool): + def __init__(self, pool): # type: ("Pool") -> None self._pool = pool def find_best_candidate( self, package_name, # type: str - target_package_version=None, # type: Union[str, None] + target_package_version=None, # type: Optional[str] allow_prereleases=False, # type: bool - source=None, # type: str + source=None, # type: Optional[str] ): # type: (...) -> Union[Package, bool] """ Given a package name and optional version, @@ -52,12 +58,12 @@ def find_best_candidate( return False return package - def find_recommended_require_version(self, package): + def find_recommended_require_version(self, package): # type: (Package) -> str version = package.version return self._transform_version(version.text, package.pretty_version) - def _transform_version(self, version, pretty_version): + def _transform_version(self, version, pretty_version): # type: (str, str) -> str try: parsed = Version.parse(version) parts = [parsed.major, parsed.minor, parsed.patch]