Commit 48171301 by David Hotham Committed by GitHub

enable strictness flags for mypy (#5531)

* enable strict mypy checking
* treat poetry.core as untyped
* python 3.7 typechecking
parent c0771f13
...@@ -5,9 +5,6 @@ ban-relative-imports = true ...@@ -5,9 +5,6 @@ ban-relative-imports = true
# flake8-use-fstring: https://github.com/MichaelKim0407/flake8-use-fstring#--percent-greedy-and---format-greedy # flake8-use-fstring: https://github.com/MichaelKim0407/flake8-use-fstring#--percent-greedy-and---format-greedy
format-greedy = 1 format-greedy = 1
inline-quotes = double inline-quotes = double
# Allow omission of a return type hint for __init__ if at least one argument is annotated
# used by flake8-annotations
mypy-init-return = true
enable-extensions = TC, TC1 enable-extensions = TC, TC1
type-checking-exempt-modules = typing, typing-extensions type-checking-exempt-modules = typing, typing-extensions
eradicate-whitelist-extend = ^-.*; eradicate-whitelist-extend = ^-.*;
......
...@@ -103,13 +103,9 @@ force-exclude = ''' ...@@ -103,13 +103,9 @@ force-exclude = '''
[tool.mypy] [tool.mypy]
check_untyped_defs = true
ignore_missing_imports = true
show_error_codes = true
warn_redundant_casts = true
warn_unused_configs = true
warn_unused_ignores = true
files = "src" files = "src"
show_error_codes = true
strict = true
# The following whitelist is used to allow for incremental adoption # The following whitelist is used to allow for incremental adoption
# of Mypy. Modules should be removed from this whitelist as and when # of Mypy. Modules should be removed from this whitelist as and when
...@@ -131,6 +127,21 @@ module = [ ...@@ -131,6 +127,21 @@ module = [
] ]
ignore_errors = true ignore_errors = true
[[tool.mypy.overrides]]
module = [
'cachecontrol.*',
'cachy.*',
'cleo.*',
'crashtest.*',
'entrypoints.*',
'html5lib.*',
'jsonschema.*',
'pexpect.*',
'poetry.core.*',
'requests_toolbelt.*',
'shellingham.*',
]
ignore_missing_imports = true
[tool.coverage.report] [tool.coverage.report]
exclude_lines = [ exclude_lines = [
......
from __future__ import annotations from __future__ import annotations
from typing import Callable
from poetry.utils._compat import metadata from poetry.utils._compat import metadata
__version__ = metadata.version("poetry") # The metadata.version that we import for Python 3.7 is untyped, work around
# that.
version: Callable[[str], str] = metadata.version
__version__ = version("poetry")
...@@ -63,7 +63,7 @@ class Config: ...@@ -63,7 +63,7 @@ class Config:
self._auth_config_source: ConfigSource = DictConfigSource() self._auth_config_source: ConfigSource = DictConfigSource()
@property @property
def config(self) -> dict: def config(self) -> dict[str, Any]:
return self._config return self._config
@property @property
...@@ -90,7 +90,7 @@ class Config: ...@@ -90,7 +90,7 @@ class Config:
merge_dicts(self._config, config) merge_dicts(self._config, config)
def all(self) -> dict[str, Any]: def all(self) -> dict[str, Any]:
def _all(config: dict, parent_key: str = "") -> dict: def _all(config: dict[str, Any], parent_key: str = "") -> dict[str, Any]:
all_ = {} all_ = {}
for key in config: for key in config:
...@@ -159,10 +159,14 @@ class Config: ...@@ -159,10 +159,14 @@ class Config:
if not isinstance(value, str): if not isinstance(value, str):
return value return value
return re.sub(r"{(.+?)}", lambda m: self.get(m.group(1)), value) return re.sub(
r"{(.+?)}",
lambda m: self.get(m.group(1)), # type: ignore[no-any-return]
value,
)
@staticmethod @staticmethod
def _get_normalizer(name: str) -> Callable: def _get_normalizer(name: str) -> Callable[[str], Any]:
if name in { if name in {
"virtualenvs.create", "virtualenvs.create",
"virtualenvs.in-project", "virtualenvs.in-project",
......
...@@ -37,12 +37,13 @@ if TYPE_CHECKING: ...@@ -37,12 +37,13 @@ if TYPE_CHECKING:
from poetry.poetry import Poetry from poetry.poetry import Poetry
def load_command(name: str) -> Callable: def load_command(name: str) -> Callable[[], type[Command]]:
def _load() -> type[Command]: def _load() -> type[Command]:
words = name.split(" ") words = name.split(" ")
module = import_module("poetry.console.commands." + ".".join(words)) module = import_module("poetry.console.commands." + ".".join(words))
command_class = getattr(module, "".join(c.title() for c in words) + "Command") command_class = getattr(module, "".join(c.title() for c in words) + "Command")
return command_class() command_type: type[Command] = command_class()
return command_type
return _load return _load
...@@ -89,7 +90,7 @@ COMMANDS = [ ...@@ -89,7 +90,7 @@ COMMANDS = [
] ]
class Application(BaseApplication): class Application(BaseApplication): # type: ignore[misc]
def __init__(self) -> None: def __init__(self) -> None:
super().__init__("poetry", __version__) super().__init__("poetry", __version__)
...@@ -128,7 +129,8 @@ class Application(BaseApplication): ...@@ -128,7 +129,8 @@ class Application(BaseApplication):
@property @property
def command_loader(self) -> CommandLoader: def command_loader(self) -> CommandLoader:
return self._command_loader command_loader: CommandLoader = self._command_loader
return command_loader
def reset_poetry(self) -> None: def reset_poetry(self) -> None:
self._poetry = None self._poetry = None
...@@ -176,7 +178,8 @@ class Application(BaseApplication): ...@@ -176,7 +178,8 @@ class Application(BaseApplication):
self._load_plugins(io) self._load_plugins(io)
return super()._run(io) exit_code: int = super()._run(io)
return exit_code
def _configure_io(self, io: IO) -> None: def _configure_io(self, io: IO) -> None:
# We need to check if the command being run # We need to check if the command being run
...@@ -212,7 +215,7 @@ class Application(BaseApplication): ...@@ -212,7 +215,7 @@ class Application(BaseApplication):
io.set_input(run_input) io.set_input(run_input)
return super()._configure_io(io) super()._configure_io(io)
def register_command_loggers( def register_command_loggers(
self, event: ConsoleCommandEvent, event_name: str, _: Any self, event: ConsoleCommandEvent, event_name: str, _: Any
...@@ -376,7 +379,8 @@ class Application(BaseApplication): ...@@ -376,7 +379,8 @@ class Application(BaseApplication):
def main() -> int: def main() -> int:
return Application().run() exit_code: int = Application().run()
return exit_code
if __name__ == "__main__": if __name__ == "__main__":
......
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING
from typing import Callable from typing import Callable
from cleo.exceptions import LogicException from cleo.exceptions import LogicException
from cleo.loaders.factory_command_loader import FactoryCommandLoader from cleo.loaders.factory_command_loader import FactoryCommandLoader
class CommandLoader(FactoryCommandLoader): if TYPE_CHECKING:
def register_factory(self, command_name: str, factory: Callable) -> None: from poetry.console.commands.command import Command
class CommandLoader(FactoryCommandLoader): # type: ignore[misc]
def register_factory(
self, command_name: str, factory: Callable[[], Command]
) -> None:
if command_name in self._factories: if command_name in self._factories:
raise LogicException(f'The command "{command_name}" already exists.') raise LogicException(f'The command "{command_name}" already exists.')
......
from __future__ import annotations from __future__ import annotations
from typing import Callable
from poetry.console.commands.command import Command from poetry.console.commands.command import Command
...@@ -12,12 +14,16 @@ class AboutCommand(Command): ...@@ -12,12 +14,16 @@ class AboutCommand(Command):
def handle(self) -> None: def handle(self) -> None:
from poetry.utils._compat import metadata from poetry.utils._compat import metadata
# The metadata.version that we import for Python 3.7 is untyped, work around
# that.
version: Callable[[str], str] = metadata.version
self.line( self.line(
f"""\ f"""\
<info>Poetry - Package Management for Python <info>Poetry - Package Management for Python
Version: {metadata.version('poetry')} Version: {version('poetry')}
Poetry-Core Version: {metadata.version('poetry-core')}</info> Poetry-Core Version: {version('poetry-core')}</info>
<comment>Poetry is a dependency manager tracking local dependencies of your projects\ <comment>Poetry is a dependency manager tracking local dependencies of your projects\
and libraries. and libraries.
......
...@@ -262,7 +262,7 @@ You can specify a package in the following forms: ...@@ -262,7 +262,7 @@ You can specify a package in the following forms:
return status return status
def get_existing_packages_from_input( def get_existing_packages_from_input(
self, packages: list[str], section: dict self, packages: list[str], section: dict[str, Any]
) -> list[str]: ) -> list[str]:
existing_packages = [] existing_packages = []
......
...@@ -12,7 +12,7 @@ if TYPE_CHECKING: ...@@ -12,7 +12,7 @@ if TYPE_CHECKING:
from poetry.poetry import Poetry from poetry.poetry import Poetry
class Command(BaseCommand): class Command(BaseCommand): # type: ignore[misc]
loggers: list[str] = [] loggers: list[str] = []
_poetry: Poetry | None = None _poetry: Poetry | None = None
...@@ -28,7 +28,8 @@ class Command(BaseCommand): ...@@ -28,7 +28,8 @@ class Command(BaseCommand):
self._poetry = poetry self._poetry = poetry
def get_application(self) -> Application: def get_application(self) -> Application:
return self.application application: Application = self.application
return application
def reset_poetry(self) -> None: def reset_poetry(self) -> None:
self.get_application().reset_poetry() self.get_application().reset_poetry()
......
...@@ -318,7 +318,8 @@ To remove a repository (repo is a short alias for repositories): ...@@ -318,7 +318,8 @@ To remove a repository (repo is a short alias for repositories):
if isinstance(value, dict): if isinstance(value, dict):
k += f"{key}." k += f"{key}."
self._list_configuration(value, cast(dict, raw_val), k=k) raw_val = cast("dict[str, Any]", raw_val)
self._list_configuration(value, raw_val, k=k)
k = orig_k k = orig_k
continue continue
...@@ -338,50 +339,3 @@ To remove a repository (repo is a short alias for repositories): ...@@ -338,50 +339,3 @@ To remove a repository (repo is a short alias for repositories):
message = f"<c1>{k + key}</c1> = <c2>{json.dumps(value)}</c2>" message = f"<c1>{k + key}</c1> = <c2>{json.dumps(value)}</c2>"
self.line(message) self.line(message)
def _get_setting(
self,
contents: dict,
setting: str | None = None,
k: str | None = None,
default: Any | None = None,
) -> list[tuple[str, str]]:
orig_k = k
if setting and setting.split(".")[0] not in contents:
value = json.dumps(default)
return [((k or "") + setting, value)]
else:
values = []
for key, value in contents.items():
if setting and key != setting.split(".")[0]:
continue
if isinstance(value, dict) or key == "repositories" and k is None:
if k is None:
k = ""
k += re.sub(r"^config\.", "", key + ".")
if setting and len(setting) > 1:
setting = ".".join(setting.split(".")[1:])
values += self._get_setting(
cast(dict, value), k=k, setting=setting, default=default
)
k = orig_k
continue
if isinstance(value, list):
value = ", ".join(
json.dumps(val) if isinstance(val, list) else val
for val in value
)
value = f"[{value}]"
value = json.dumps(value)
values.append(((k or "") + key, value))
return values
...@@ -25,4 +25,5 @@ class DebugInfoCommand(Command): ...@@ -25,4 +25,5 @@ class DebugInfoCommand(Command):
) )
command = self.application.get("env info") command = self.application.get("env info")
return command.run(self._io) exit_code: int = command.run(self._io)
return exit_code
...@@ -41,7 +41,7 @@ class DebugResolveCommand(InitCommand): ...@@ -41,7 +41,7 @@ class DebugResolveCommand(InitCommand):
from poetry.core.packages.project_package import ProjectPackage from poetry.core.packages.project_package import ProjectPackage
from poetry.factory import Factory from poetry.factory import Factory
from poetry.puzzle import Solver from poetry.puzzle.solver import Solver
from poetry.repositories.pool import Pool from poetry.repositories.pool import Pool
from poetry.repositories.repository import Repository from poetry.repositories.repository import Repository
from poetry.utils.env import EnvManager from poetry.utils.env import EnvManager
......
...@@ -73,7 +73,7 @@ dependencies and not including the current project, run the command with the ...@@ -73,7 +73,7 @@ dependencies and not including the current project, run the command with the
def handle(self) -> int: def handle(self) -> int:
from poetry.core.masonry.utils.module import ModuleOrPackageNotFound from poetry.core.masonry.utils.module import ModuleOrPackageNotFound
from poetry.masonry.builders import EditableBuilder from poetry.masonry.builders.editable import EditableBuilder
self._installer.use_executor( self._installer.use_executor(
self.poetry.config.get("experimental.new-installer", False) self.poetry.config.get("experimental.new-installer", False)
......
...@@ -170,16 +170,17 @@ You can specify a package in the following forms: ...@@ -170,16 +170,17 @@ You can specify a package in the following forms:
if self.option("dry-run"): if self.option("dry-run"):
argv.append("--dry-run") argv.append("--dry-run")
return update_command.run( exit_code: int = update_command.run(
IO( IO(
StringInput(" ".join(argv)), StringInput(" ".join(argv)),
self._io.output, self._io.output,
self._io.error_output, self._io.error_output,
) )
) )
return exit_code
def get_existing_packages_from_input( def get_existing_packages_from_input(
self, packages: list[str], poetry_content: dict, target_section: str self, packages: list[str], poetry_content: dict[str, Any], target_section: str
) -> list[str]: ) -> list[str]:
existing_packages = [] existing_packages = []
......
...@@ -59,10 +59,11 @@ class PluginRemoveCommand(Command): ...@@ -59,10 +59,11 @@ class PluginRemoveCommand(Command):
if self.option("dry-run"): if self.option("dry-run"):
argv.append("--dry-run") argv.append("--dry-run")
return remove_command.run( exit_code: int = remove_command.run(
IO( IO(
StringInput(" ".join(argv)), StringInput(" ".join(argv)),
self._io.output, self._io.output,
self._io.error_output, self._io.error_output,
) )
) )
return exit_code
...@@ -298,7 +298,10 @@ lists all packages available.""" ...@@ -298,7 +298,10 @@ lists all packages available."""
io.write_line(f" <b>{package.pretty_version}</b>{description}") io.write_line(f" <b>{package.pretty_version}</b>{description}")
dependencies = package.requires dependencies = package.requires
dependencies = sorted(dependencies, key=lambda x: x.name) dependencies = sorted(
dependencies,
key=lambda x: x.name, # type: ignore[no-any-return]
)
tree_bar = "├" tree_bar = "├"
total = len(dependencies) total = len(dependencies)
for i, dependency in enumerate(dependencies, 1): for i, dependency in enumerate(dependencies, 1):
...@@ -338,7 +341,10 @@ lists all packages available.""" ...@@ -338,7 +341,10 @@ lists all packages available."""
break break
dependencies = sorted(dependencies, key=lambda x: x.name) dependencies = sorted(
dependencies,
key=lambda x: x.name, # type: ignore[no-any-return]
)
tree_bar = previous_tree_bar + " ├" tree_bar = previous_tree_bar + " ├"
total = len(dependencies) total = len(dependencies)
for i, dependency in enumerate(dependencies, 1): for i, dependency in enumerate(dependencies, 1):
......
...@@ -3,6 +3,6 @@ from __future__ import annotations ...@@ -3,6 +3,6 @@ from __future__ import annotations
from cleo.exceptions import CleoSimpleException from cleo.exceptions import CleoSimpleException
class PoetrySimpleConsoleException(CleoSimpleException): class PoetrySimpleConsoleException(CleoSimpleException): # type: ignore[misc]
pass pass
...@@ -9,7 +9,7 @@ if TYPE_CHECKING: ...@@ -9,7 +9,7 @@ if TYPE_CHECKING:
from cleo.io.inputs.definition import Definition from cleo.io.inputs.definition import Definition
class RunArgvInput(ArgvInput): class RunArgvInput(ArgvInput): # type: ignore[misc]
def __init__( def __init__(
self, self,
argv: list[str] | None = None, argv: list[str] | None = None,
......
...@@ -43,7 +43,7 @@ if TYPE_CHECKING: ...@@ -43,7 +43,7 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Factory(BaseFactory): class Factory(BaseFactory): # type: ignore[misc]
""" """
Factory class to create various elements needed by Poetry. Factory class to create various elements needed by Poetry.
""" """
......
...@@ -71,7 +71,7 @@ class PackageInfo: ...@@ -71,7 +71,7 @@ class PackageInfo:
requires_python: str | None = None, requires_python: str | None = None,
files: list[dict[str, str]] | None = None, files: list[dict[str, str]] | None = None,
cache_version: str | None = None, cache_version: str | None = None,
): ) -> None:
self.name = name self.name = name
self.version = version self.version = version
self.summary = summary self.summary = summary
......
...@@ -41,7 +41,7 @@ class Installer: ...@@ -41,7 +41,7 @@ class Installer:
config: Config, config: Config,
installed: Repository | None = None, installed: Repository | None = None,
executor: Executor | None = None, executor: Executor | None = None,
): ) -> None:
self._io = io self._io = io
self._env = env self._env = env
self._package = package self._package = package
......
...@@ -43,7 +43,8 @@ class Operation: ...@@ -43,7 +43,8 @@ class Operation:
raise NotImplementedError() raise NotImplementedError()
def format_version(self, package: Package) -> str: def format_version(self, package: Package) -> str:
return package.full_pretty_version version: str = package.full_pretty_version
return version
def skip(self: T, reason: str) -> T: def skip(self: T, reason: str) -> T:
self._skipped = True self._skipped = True
......
...@@ -3,6 +3,8 @@ from __future__ import annotations ...@@ -3,6 +3,8 @@ from __future__ import annotations
import json import json
import os import os
from typing import Any
import jsonschema import jsonschema
...@@ -14,7 +16,7 @@ class ValidationError(ValueError): ...@@ -14,7 +16,7 @@ class ValidationError(ValueError):
pass pass
def validate_object(obj: dict, schema_name: str) -> list[str]: def validate_object(obj: dict[str, Any], schema_name: str) -> list[str]:
schema = os.path.join(SCHEMA_DIR, f"{schema_name}.json") schema = os.path.join(SCHEMA_DIR, f"{schema_name}.json")
if not os.path.exists(schema): if not os.path.exists(schema):
...@@ -24,7 +26,10 @@ def validate_object(obj: dict, schema_name: str) -> list[str]: ...@@ -24,7 +26,10 @@ def validate_object(obj: dict, schema_name: str) -> list[str]:
schema = json.loads(f.read()) schema = json.loads(f.read())
validator = jsonschema.Draft7Validator(schema) validator = jsonschema.Draft7Validator(schema)
validation_errors = sorted(validator.iter_errors(obj), key=lambda e: e.path) validation_errors = sorted(
validator.iter_errors(obj),
key=lambda e: e.path, # type: ignore[no-any-return]
)
errors = [] errors = []
......
...@@ -52,7 +52,7 @@ class Layout: ...@@ -52,7 +52,7 @@ class Layout:
python: str = "*", python: str = "*",
dependencies: dict[str, str] | None = None, dependencies: dict[str, str] | None = None,
dev_dependencies: dict[str, str] | None = None, dev_dependencies: dict[str, str] | None = None,
): ) -> None:
self._project = canonicalize_name(project).replace(".", "-") self._project = canonicalize_name(project).replace(".", "-")
self._package_path_relative = Path( self._package_path_relative = Path(
*(module_name(part) for part in canonicalize_name(project).split(".")) *(module_name(part) for part in canonicalize_name(project).split("."))
...@@ -91,10 +91,13 @@ class Layout: ...@@ -91,10 +91,13 @@ class Layout:
package = inline_table() package = inline_table()
include = self._package_path_relative.parts[0] include = self._package_path_relative.parts[0]
package.append("include", include) package.append("include", include) # type: ignore[no-untyped-call]
if self.basedir != Path(): if self.basedir != Path():
package.append("from", self.basedir.as_posix()) package.append( # type: ignore[no-untyped-call]
"from",
self.basedir.as_posix(),
)
else: else:
if include == self._project: if include == self._project:
# package include and package name are the same, # package include and package name are the same,
......
...@@ -39,7 +39,7 @@ WINDOWS_CMD_TEMPLATE = """\ ...@@ -39,7 +39,7 @@ WINDOWS_CMD_TEMPLATE = """\
""" """
class EditableBuilder(Builder): class EditableBuilder(Builder): # type: ignore[misc]
def __init__(self, poetry: Poetry, env: Env, io: IO) -> None: def __init__(self, poetry: Poetry, env: Env, io: IO) -> None:
super().__init__(poetry) super().__init__(poetry)
......
...@@ -63,7 +63,7 @@ class _Writer: ...@@ -63,7 +63,7 @@ class _Writer:
buffer.append("") buffer.append("")
if isinstance(self._root.cause, ConflictCause): if isinstance(self._root.cause, ConflictCause):
self._visit(self._root, {}) self._visit(self._root)
else: else:
self._write(self._root, f"Because {self._root}, version solving failed.") self._write(self._root, f"Because {self._root}, version solving failed.")
...@@ -108,7 +108,6 @@ class _Writer: ...@@ -108,7 +108,6 @@ class _Writer:
def _visit( def _visit(
self, self,
incompatibility: Incompatibility, incompatibility: Incompatibility,
details_for_incompatibility: dict,
conclusion: bool = False, conclusion: bool = False,
) -> None: ) -> None:
numbered = conclusion or self._derivations[incompatibility] > 1 numbered = conclusion or self._derivations[incompatibility] > 1
...@@ -117,7 +116,6 @@ class _Writer: ...@@ -117,7 +116,6 @@ class _Writer:
cause: ConflictCause = cast(ConflictCause, incompatibility.cause) cause: ConflictCause = cast(ConflictCause, incompatibility.cause)
details_for_cause: dict = {}
if isinstance(cause.conflict.cause, ConflictCause) and isinstance( if isinstance(cause.conflict.cause, ConflictCause) and isinstance(
cause.other.cause, ConflictCause cause.other.cause, ConflictCause
): ):
...@@ -126,7 +124,7 @@ class _Writer: ...@@ -126,7 +124,7 @@ class _Writer:
if conflict_line is not None and other_line is not None: if conflict_line is not None and other_line is not None:
reason = cause.conflict.and_to_string( reason = cause.conflict.and_to_string(
cause.other, details_for_cause, conflict_line, other_line cause.other, conflict_line, other_line
) )
self._write( self._write(
incompatibility, incompatibility,
...@@ -143,7 +141,7 @@ class _Writer: ...@@ -143,7 +141,7 @@ class _Writer:
without_line = cause.conflict without_line = cause.conflict
line = other_line line = other_line
self._visit(without_line, details_for_cause) self._visit(without_line)
self._write( self._write(
incompatibility, incompatibility,
f"{conjunction} because {with_line!s} ({line})," f"{conjunction} because {with_line!s} ({line}),"
...@@ -157,18 +155,18 @@ class _Writer: ...@@ -157,18 +155,18 @@ class _Writer:
if single_line_other or single_line_conflict: if single_line_other or single_line_conflict:
first = cause.conflict if single_line_other else cause.other first = cause.conflict if single_line_other else cause.other
second = cause.other if single_line_other else cause.conflict second = cause.other if single_line_other else cause.conflict
self._visit(first, details_for_cause) self._visit(first)
self._visit(second, details_for_cause) self._visit(second)
self._write( self._write(
incompatibility, incompatibility,
f"Thus, {incompatibility_string}.", f"Thus, {incompatibility_string}.",
numbered=numbered, numbered=numbered,
) )
else: else:
self._visit(cause.conflict, {}, conclusion=True) self._visit(cause.conflict, conclusion=True)
self._lines.append(("", None)) self._lines.append(("", None))
self._visit(cause.other, details_for_cause) self._visit(cause.other)
self._write( self._write(
incompatibility, incompatibility,
...@@ -193,9 +191,7 @@ class _Writer: ...@@ -193,9 +191,7 @@ class _Writer:
derived_line = self._line_numbers.get(derived) derived_line = self._line_numbers.get(derived)
if derived_line is not None: if derived_line is not None:
reason = ext.and_to_string( reason = ext.and_to_string(derived, None, derived_line)
derived, details_for_cause, None, derived_line
)
self._write( self._write(
incompatibility, incompatibility,
f"Because {reason}, {incompatibility_string}.", f"Because {reason}, {incompatibility_string}.",
...@@ -211,26 +207,22 @@ class _Writer: ...@@ -211,26 +207,22 @@ class _Writer:
collapsed_ext = derived_cause.conflict collapsed_ext = derived_cause.conflict
details_for_cause = {} self._visit(collapsed_derived)
reason = collapsed_ext.and_to_string(ext, None, None)
self._visit(collapsed_derived, details_for_cause)
reason = collapsed_ext.and_to_string(ext, details_for_cause, None, None)
self._write( self._write(
incompatibility, incompatibility,
f"{conjunction} because {reason}, {incompatibility_string}.", f"{conjunction} because {reason}, {incompatibility_string}.",
numbered=numbered, numbered=numbered,
) )
else: else:
self._visit(derived, details_for_cause) self._visit(derived)
self._write( self._write(
incompatibility, incompatibility,
f"{conjunction} because {ext!s}, {incompatibility_string}.", f"{conjunction} because {ext!s}, {incompatibility_string}.",
numbered=numbered, numbered=numbered,
) )
else: else:
reason = cause.conflict.and_to_string( reason = cause.conflict.and_to_string(cause.other, None, None)
cause.other, details_for_cause, None, None
)
self._write( self._write(
incompatibility, incompatibility,
f"Because {reason}, {incompatibility_string}.", f"Because {reason}, {incompatibility_string}.",
......
...@@ -214,23 +214,18 @@ class Incompatibility: ...@@ -214,23 +214,18 @@ class Incompatibility:
def and_to_string( def and_to_string(
self, self,
other: Incompatibility, other: Incompatibility,
details: dict,
this_line: int | None, this_line: int | None,
other_line: int | None, other_line: int | None,
) -> str: ) -> str:
requires_both = self._try_requires_both(other, details, this_line, other_line) requires_both = self._try_requires_both(other, this_line, other_line)
if requires_both is not None: if requires_both is not None:
return requires_both return requires_both
requires_through = self._try_requires_through( requires_through = self._try_requires_through(other, this_line, other_line)
other, details, this_line, other_line
)
if requires_through is not None: if requires_through is not None:
return requires_through return requires_through
requires_forbidden = self._try_requires_forbidden( requires_forbidden = self._try_requires_forbidden(other, this_line, other_line)
other, details, this_line, other_line
)
if requires_forbidden is not None: if requires_forbidden is not None:
return requires_forbidden return requires_forbidden
...@@ -248,7 +243,6 @@ class Incompatibility: ...@@ -248,7 +243,6 @@ class Incompatibility:
def _try_requires_both( def _try_requires_both(
self, self,
other: Incompatibility, other: Incompatibility,
details: dict,
this_line: int | None, this_line: int | None,
other_line: int | None, other_line: int | None,
) -> str | None: ) -> str | None:
...@@ -298,7 +292,6 @@ class Incompatibility: ...@@ -298,7 +292,6 @@ class Incompatibility:
def _try_requires_through( def _try_requires_through(
self, self,
other: Incompatibility, other: Incompatibility,
details: dict,
this_line: int | None, this_line: int | None,
other_line: int | None, other_line: int | None,
) -> str | None: ) -> str | None:
...@@ -380,7 +373,6 @@ class Incompatibility: ...@@ -380,7 +373,6 @@ class Incompatibility:
def _try_requires_forbidden( def _try_requires_forbidden(
self, self,
other: Incompatibility, other: Incompatibility,
details: dict,
this_line: int | None, this_line: int | None,
other_line: int | None, other_line: int | None,
) -> str | None: ) -> str | None:
...@@ -442,7 +434,8 @@ class Incompatibility: ...@@ -442,7 +434,8 @@ class Incompatibility:
return f"every version of {term.dependency.complete_name}" return f"every version of {term.dependency.complete_name}"
if term.dependency.is_root: if term.dependency.is_root:
return term.dependency.pretty_name pretty_name: str = term.dependency.pretty_name
return pretty_name
return f"{term.dependency.pretty_name} ({term.dependency.pretty_constraint})" return f"{term.dependency.pretty_name} ({term.dependency.pretty_constraint})"
......
...@@ -13,7 +13,7 @@ if TYPE_CHECKING: ...@@ -13,7 +13,7 @@ if TYPE_CHECKING:
from poetry.puzzle.exceptions import SolverProblemError from poetry.puzzle.exceptions import SolverProblemError
class PythonRequirementSolutionProvider(HasSolutionsForException): class PythonRequirementSolutionProvider(HasSolutionsForException): # type: ignore[misc]
def can_solve(self, exception: Exception) -> bool: def can_solve(self, exception: Exception) -> bool:
from poetry.puzzle.exceptions import SolverProblemError from poetry.puzzle.exceptions import SolverProblemError
......
...@@ -10,7 +10,7 @@ if TYPE_CHECKING: ...@@ -10,7 +10,7 @@ if TYPE_CHECKING:
from poetry.puzzle.exceptions import SolverProblemError from poetry.puzzle.exceptions import SolverProblemError
class PythonRequirementSolution(Solution): class PythonRequirementSolution(Solution): # type: ignore[misc]
def __init__(self, exception: SolverProblemError) -> None: def __init__(self, exception: SolverProblemError) -> None:
from poetry.core.semver.helpers import parse_constraint from poetry.core.semver.helpers import parse_constraint
......
...@@ -152,11 +152,12 @@ class Term: ...@@ -152,11 +152,12 @@ class Term:
return self.intersect(other.inverse) return self.intersect(other.inverse)
def _compatible_dependency(self, other: Dependency) -> bool: def _compatible_dependency(self, other: Dependency) -> bool:
return ( compatible: bool = (
self.dependency.is_root self.dependency.is_root
or other.is_root or other.is_root
or other.is_same_package_as(self.dependency) or other.is_same_package_as(self.dependency)
) )
return compatible
def _non_empty_term( def _non_empty_term(
self, constraint: VersionConstraint, is_positive: bool self, constraint: VersionConstraint, is_positive: bool
......
...@@ -39,7 +39,7 @@ class DependencyCache: ...@@ -39,7 +39,7 @@ class DependencyCache:
again. again.
""" """
def __init__(self, provider: Provider): def __init__(self, provider: Provider) -> None:
self.provider = provider self.provider = provider
self.cache: dict[str, list[DependencyPackage]] = {} self.cache: dict[str, list[DependencyPackage]] = {}
...@@ -75,7 +75,7 @@ class VersionSolver: ...@@ -75,7 +75,7 @@ class VersionSolver:
provider: Provider, provider: Provider,
locked: dict[str, list[DependencyPackage]] | None = None, locked: dict[str, list[DependencyPackage]] | None = None,
use_latest: list[str] | None = None, use_latest: list[str] | None = None,
): ) -> None:
self._root = root self._root = root
self._provider = provider self._provider = provider
self._dependency_cache = DependencyCache(provider) self._dependency_cache = DependencyCache(provider)
...@@ -212,7 +212,8 @@ class VersionSolver: ...@@ -212,7 +212,8 @@ class VersionSolver:
unsatisfied.dependency, not unsatisfied.is_positive(), incompatibility unsatisfied.dependency, not unsatisfied.is_positive(), incompatibility
) )
return unsatisfied.dependency.complete_name complete_name: str = unsatisfied.dependency.complete_name
return complete_name
def _resolve_conflict(self, incompatibility: Incompatibility) -> Incompatibility: def _resolve_conflict(self, incompatibility: Incompatibility) -> Incompatibility:
""" """
...@@ -404,7 +405,8 @@ class VersionSolver: ...@@ -404,7 +405,8 @@ class VersionSolver:
self._add_incompatibility( self._add_incompatibility(
Incompatibility([Term(dependency, True)], PackageNotFoundCause(e)) Incompatibility([Term(dependency, True)], PackageNotFoundCause(e))
) )
return dependency.complete_name complete_name: str = dependency.complete_name
return complete_name
package = None package = None
if dependency.name not in self._use_latest: if dependency.name not in self._use_latest:
...@@ -427,7 +429,8 @@ class VersionSolver: ...@@ -427,7 +429,8 @@ class VersionSolver:
Incompatibility([Term(dependency, True)], NoVersionsCause()) Incompatibility([Term(dependency, True)], NoVersionsCause())
) )
return dependency.complete_name complete_name = dependency.complete_name
return complete_name
else: else:
package = locked package = locked
...@@ -454,7 +457,8 @@ class VersionSolver: ...@@ -454,7 +457,8 @@ class VersionSolver:
f"selecting {package.complete_name} ({package.full_pretty_version})" f"selecting {package.complete_name} ({package.full_pretty_version})"
) )
return dependency.complete_name complete_name = dependency.complete_name
return complete_name
def _result(self) -> SolverResult: def _result(self) -> SolverResult:
""" """
......
...@@ -53,4 +53,5 @@ class DependencyPackage: ...@@ -53,4 +53,5 @@ class DependencyPackage:
if isinstance(other, DependencyPackage): if isinstance(other, DependencyPackage):
other = other.package other = other.package
return self._package == other equal: bool = self._package == other
return equal
...@@ -31,9 +31,9 @@ from tomlkit import document ...@@ -31,9 +31,9 @@ from tomlkit import document
from tomlkit import inline_table from tomlkit import inline_table
from tomlkit import item from tomlkit import item
from tomlkit import table from tomlkit import table
from tomlkit.container import Table
from tomlkit.exceptions import TOMLKitError from tomlkit.exceptions import TOMLKitError
from tomlkit.items import Array from tomlkit.items import Array
from tomlkit.items import Table
from poetry.packages import DependencyPackage from poetry.packages import DependencyPackage
from poetry.utils.extras import get_extra_package_names from poetry.utils.extras import get_extra_package_names
...@@ -55,7 +55,7 @@ class Locker: ...@@ -55,7 +55,7 @@ class Locker:
_legacy_keys = ["dependencies", "source", "extras", "dev-dependencies"] _legacy_keys = ["dependencies", "source", "extras", "dev-dependencies"]
_relevant_keys = [*_legacy_keys, "group"] _relevant_keys = [*_legacy_keys, "group"]
def __init__(self, lock: str | Path, local_config: dict) -> None: def __init__(self, lock: str | Path, local_config: dict[str, Any]) -> None:
self._lock = TOMLFile(lock) self._lock = TOMLFile(lock)
self._local_config = local_config self._local_config = local_config
self._lock_data: TOMLDocument | None = None self._lock_data: TOMLDocument | None = None
...@@ -89,7 +89,8 @@ class Locker: ...@@ -89,7 +89,8 @@ class Locker:
metadata = lock.get("metadata", {}) metadata = lock.get("metadata", {})
if "content-hash" in metadata: if "content-hash" in metadata:
return self._content_hash == metadata["content-hash"] fresh: bool = self._content_hash == metadata["content-hash"]
return fresh
return False return False
...@@ -306,7 +307,10 @@ class Locker: ...@@ -306,7 +307,10 @@ class Locker:
# Put higher versions first so that we prefer them. # Put higher versions first so that we prefer them.
for packages in packages_by_name.values(): for packages in packages_by_name.values():
packages.sort(key=lambda package: package.version, reverse=True) packages.sort(
key=lambda package: package.version, # type: ignore[no-any-return]
reverse=True,
)
nested_dependencies = cls.__walk_dependencies( nested_dependencies = cls.__walk_dependencies(
dependencies=project_requires, dependencies=project_requires,
...@@ -445,7 +449,7 @@ class Locker: ...@@ -445,7 +449,7 @@ class Locker:
raise RuntimeError("No lockfile found. Unable to read locked packages") raise RuntimeError("No lockfile found. Unable to read locked packages")
try: try:
lock_data = self._lock.read() lock_data: TOMLDocument = self._lock.read()
except TOMLKitError as e: except TOMLKitError as e:
raise RuntimeError(f"Unable to read the lock file ({e}).") raise RuntimeError(f"Unable to read the lock file ({e}).")
...@@ -486,7 +490,10 @@ class Locker: ...@@ -486,7 +490,10 @@ class Locker:
def _dump_package(self, package: Package) -> dict[str, Any]: def _dump_package(self, package: Package) -> dict[str, Any]:
dependencies: dict[str, list[Any]] = {} dependencies: dict[str, list[Any]] = {}
for dependency in sorted(package.requires, key=lambda d: d.name): for dependency in sorted(
package.requires,
key=lambda d: d.name, # type: ignore[no-any-return]
):
if dependency.pretty_name not in dependencies: if dependency.pretty_name not in dependencies:
dependencies[dependency.pretty_name] = [] dependencies[dependency.pretty_name] = []
...@@ -549,7 +556,10 @@ class Locker: ...@@ -549,7 +556,10 @@ class Locker:
"category": package.category, "category": package.category,
"optional": package.optional, "optional": package.optional,
"python-versions": package.python_versions, "python-versions": package.python_versions,
"files": sorted(package.files, key=lambda x: x["file"]), "files": sorted(
package.files,
key=lambda x: x["file"], # type: ignore[no-any-return]
),
} }
if dependencies: if dependencies:
......
...@@ -11,7 +11,7 @@ if TYPE_CHECKING: ...@@ -11,7 +11,7 @@ if TYPE_CHECKING:
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
class PackageCollection(list): class PackageCollection(list): # type: ignore[type-arg]
def __init__( def __init__(
self, self,
dependency: Dependency, dependency: Dependency,
......
...@@ -9,7 +9,7 @@ if TYPE_CHECKING: ...@@ -9,7 +9,7 @@ if TYPE_CHECKING:
from poetry.core.semver.version import Version from poetry.core.semver.version import Version
class ProjectPackage(_ProjectPackage): class ProjectPackage(_ProjectPackage): # type: ignore[misc]
def set_version( def set_version(
self, version: str | Version, pretty_version: str | None = None self, version: str | Version, pretty_version: str | None = None
) -> None: ) -> None:
......
...@@ -33,7 +33,11 @@ class PluginManager: ...@@ -33,7 +33,11 @@ class PluginManager:
self._load_plugin_entrypoint(entrypoint) self._load_plugin_entrypoint(entrypoint)
def get_plugin_entry_points(self) -> list[entrypoints.EntryPoint]: def get_plugin_entry_points(self) -> list[entrypoints.EntryPoint]:
return entrypoints.get_group_all(self._group)
entry_points: list[entrypoints.EntryPoint] = entrypoints.get_group_all(
self._group
)
return entry_points
def add_plugin(self, plugin: Plugin) -> None: def add_plugin(self, plugin: Plugin) -> None:
if not isinstance(plugin, (Plugin, ApplicationPlugin)): if not isinstance(plugin, (Plugin, ApplicationPlugin)):
......
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Any
from poetry.core.poetry import Poetry as BasePoetry from poetry.core.poetry import Poetry as BasePoetry
...@@ -19,18 +20,18 @@ if TYPE_CHECKING: ...@@ -19,18 +20,18 @@ if TYPE_CHECKING:
from poetry.repositories.pool import Pool from poetry.repositories.pool import Pool
class Poetry(BasePoetry): class Poetry(BasePoetry): # type: ignore[misc]
VERSION = __version__ VERSION = __version__
def __init__( def __init__(
self, self,
file: Path, file: Path,
local_config: dict, local_config: dict[str, Any],
package: ProjectPackage, package: ProjectPackage,
locker: Locker, locker: Locker,
config: Config, config: Config,
): ) -> None:
from poetry.repositories.pool import Pool from poetry.repositories.pool import Pool
super().__init__(file, local_config, package) super().__init__(file, local_config, package)
......
...@@ -60,7 +60,8 @@ class Uploader: ...@@ -60,7 +60,8 @@ class Uploader:
@property @property
def user_agent(self) -> str: def user_agent(self) -> str:
return user_agent("poetry", __version__) agent: str = user_agent("poetry", __version__)
return agent
@property @property
def adapter(self) -> adapters.HTTPAdapter: def adapter(self) -> adapters.HTTPAdapter:
......
...@@ -54,7 +54,7 @@ if TYPE_CHECKING: ...@@ -54,7 +54,7 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Indicator(ProgressIndicator): class Indicator(ProgressIndicator): # type: ignore[misc]
def _formatter_elapsed(self) -> str: def _formatter_elapsed(self) -> str:
elapsed = time.time() - self._start_time elapsed = time.time() - self._start_time
...@@ -104,7 +104,7 @@ class Provider: ...@@ -104,7 +104,7 @@ class Provider:
self._io = io self._io = io
self._env = env self._env = env
self._python_constraint = package.python_constraint self._python_constraint = package.python_constraint
self._is_debugging = self._io.is_debug() or self._io.is_very_verbose() self._is_debugging: bool = self._io.is_debug() or self._io.is_very_verbose()
self._in_progress = False self._in_progress = False
self._overrides: dict[DependencyPackage, dict[str, Dependency]] = {} self._overrides: dict[DependencyPackage, dict[str, Dependency]] = {}
self._deferred_cache: dict[Dependency, Package] = {} self._deferred_cache: dict[Dependency, Package] = {}
......
...@@ -49,7 +49,7 @@ class Solver: ...@@ -49,7 +49,7 @@ class Solver:
locked: Repository, locked: Repository,
io: IO, io: IO,
provider: Provider | None = None, provider: Provider | None = None,
): ) -> None:
self._package = package self._package = package
self._pool = pool self._pool = pool
self._installed = installed self._installed = installed
...@@ -140,7 +140,8 @@ class Solver: ...@@ -140,7 +140,8 @@ class Solver:
) )
for dependency_packages in locked.values(): for dependency_packages in locked.values():
dependency_packages.sort( dependency_packages.sort(
key=lambda package: package.package.version, reverse=True key=lambda p: p.package.version, # type: ignore[no-any-return]
reverse=True,
) )
try: try:
......
...@@ -3,6 +3,7 @@ from __future__ import annotations ...@@ -3,6 +3,7 @@ from __future__ import annotations
from abc import ABC from abc import ABC
from abc import abstractmethod from abc import abstractmethod
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Any
from cachy import CacheManager from cachy import CacheManager
from poetry.core.semver.helpers import parse_constraint from poetry.core.semver.helpers import parse_constraint
...@@ -20,7 +21,7 @@ if TYPE_CHECKING: ...@@ -20,7 +21,7 @@ if TYPE_CHECKING:
class CachedRepository(Repository, ABC): class CachedRepository(Repository, ABC):
CACHE_VERSION = parse_constraint("1.0.0") CACHE_VERSION = parse_constraint("1.0.0")
def __init__(self, name: str, disable_cache: bool = False): def __init__(self, name: str, disable_cache: bool = False) -> None:
super().__init__(name) super().__init__(name)
self._disable_cache = disable_cache self._disable_cache = disable_cache
self._cache_dir = REPOSITORY_CACHE_DIR / name self._cache_dir = REPOSITORY_CACHE_DIR / name
...@@ -37,7 +38,7 @@ class CachedRepository(Repository, ABC): ...@@ -37,7 +38,7 @@ class CachedRepository(Repository, ABC):
) )
@abstractmethod @abstractmethod
def _get_release_info(self, name: str, version: str) -> dict: def _get_release_info(self, name: str, version: str) -> dict[str, Any]:
raise NotImplementedError() raise NotImplementedError()
def get_release_info(self, name: str, version: str) -> PackageInfo: def get_release_info(self, name: str, version: str) -> PackageInfo:
...@@ -73,6 +74,6 @@ class CachedRepository(Repository, ABC): ...@@ -73,6 +74,6 @@ class CachedRepository(Repository, ABC):
self, self,
name: str, name: str,
version: str, version: str,
extras: (list | None) = None, extras: list[str] | None = None,
) -> Package: ) -> Package:
return self.get_release_info(name, version).to_package(name=name, extras=extras) return self.get_release_info(name, version).to_package(name=name, extras=extras)
...@@ -200,7 +200,7 @@ class HTTPRepository(CachedRepository, ABC): ...@@ -200,7 +200,7 @@ class HTTPRepository(CachedRepository, ABC):
return self._get_info_from_sdist(urls["sdist"][0]) return self._get_info_from_sdist(urls["sdist"][0])
def _links_to_data(self, links: list[Link], data: PackageInfo) -> dict: def _links_to_data(self, links: list[Link], data: PackageInfo) -> dict[str, Any]:
if not links: if not links:
raise PackageNotFound( raise PackageNotFound(
f'No valid distribution links found for package: "{data.name}" version:' f'No valid distribution links found for package: "{data.name}" version:'
...@@ -260,7 +260,7 @@ class HTTPRepository(CachedRepository, ABC): ...@@ -260,7 +260,7 @@ class HTTPRepository(CachedRepository, ABC):
def _get_response(self, endpoint: str) -> requests.Response | None: def _get_response(self, endpoint: str) -> requests.Response | None:
url = self._url + endpoint url = self._url + endpoint
try: try:
response = self.session.get(url, raise_for_status=False) response: requests.Response = self.session.get(url, raise_for_status=False)
if response.status_code in (401, 403): if response.status_code in (401, 403):
self._log( self._log(
f"Authorization error accessing {url}", f"Authorization error accessing {url}",
......
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Any
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
from poetry.core.semver.version import Version from poetry.core.semver.version import Version
...@@ -120,7 +121,7 @@ class LegacyRepository(HTTPRepository): ...@@ -120,7 +121,7 @@ class LegacyRepository(HTTPRepository):
return list(page.links_for_version(package.name, package.version)) return list(page.links_for_version(package.name, package.version))
def _get_release_info(self, name: str, version: str) -> dict: def _get_release_info(self, name: str, version: str) -> dict[str, Any]:
page = self._get_page(f"/{canonicalize_name(name).replace('.', '-')}/") page = self._get_page(f"/{canonicalize_name(name).replace('.', '-')}/")
if page is None: if page is None:
raise PackageNotFound(f'No package named "{name}"') raise PackageNotFound(f'No package named "{name}"')
......
...@@ -122,7 +122,11 @@ class Pool(Repository): ...@@ -122,7 +122,11 @@ class Pool(Repository):
raise NotImplementedError() raise NotImplementedError()
def package( def package(
self, name: str, version: str, extras: list[str] = None, repository: str = None self,
name: str,
version: str,
extras: list[str] | None = None,
repository: str | None = None,
) -> Package: ) -> Package:
if repository is not None: if repository is not None:
repository = repository.lower() repository = repository.lower()
......
...@@ -4,6 +4,7 @@ import logging ...@@ -4,6 +4,7 @@ import logging
from collections import defaultdict from collections import defaultdict
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Any
import requests import requests
...@@ -128,7 +129,7 @@ class PyPiRepository(HTTPRepository): ...@@ -128,7 +129,7 @@ class PyPiRepository(HTTPRepository):
return results return results
def get_package_info(self, name: str) -> dict: def get_package_info(self, name: str) -> dict[str, Any]:
""" """
Return the package information given its name. Return the package information given its name.
...@@ -138,11 +139,12 @@ class PyPiRepository(HTTPRepository): ...@@ -138,11 +139,12 @@ class PyPiRepository(HTTPRepository):
if self._disable_cache: if self._disable_cache:
return self._get_package_info(name) return self._get_package_info(name)
return self._cache.store("packages").remember_forever( package_info: dict[str, Any] = self._cache.store("packages").remember_forever(
name, lambda: self._get_package_info(name) name, lambda: self._get_package_info(name)
) )
return package_info
def _get_package_info(self, name: str) -> dict: def _get_package_info(self, name: str) -> dict[str, Any]:
data = self._get(f"pypi/{name}/json") data = self._get(f"pypi/{name}/json")
if data is None: if data is None:
raise PackageNotFound(f"Package [{name}] not found.") raise PackageNotFound(f"Package [{name}] not found.")
...@@ -226,7 +228,7 @@ class PyPiRepository(HTTPRepository): ...@@ -226,7 +228,7 @@ class PyPiRepository(HTTPRepository):
return data.asdict() return data.asdict()
def _get(self, endpoint: str) -> dict | None: def _get(self, endpoint: str) -> dict[str, Any] | None:
try: try:
json_response = self.session.get(self._base_url + endpoint) json_response = self.session.get(self._base_url + endpoint)
except requests.exceptions.TooManyRedirects: except requests.exceptions.TooManyRedirects:
...@@ -238,4 +240,5 @@ class PyPiRepository(HTTPRepository): ...@@ -238,4 +240,5 @@ class PyPiRepository(HTTPRepository):
if json_response.status_code == 404: if json_response.status_code == 404:
return None return None
return json_response.json() json: dict[str, Any] = json_response.json()
return json
...@@ -5,7 +5,7 @@ from poetry.repositories.link_sources.html import SimpleRepositoryPage ...@@ -5,7 +5,7 @@ from poetry.repositories.link_sources.html import SimpleRepositoryPage
class SinglePageRepository(LegacyRepository): class SinglePageRepository(LegacyRepository):
def _get_page(self, endpoint: str = None) -> SimpleRepositoryPage | None: def _get_page(self, endpoint: str | None = None) -> SimpleRepositoryPage | None:
""" """
Single page repositories only have one page irrespective of endpoint. Single page repositories only have one page irrespective of endpoint.
""" """
......
...@@ -9,7 +9,7 @@ if sys.version_info < (3, 8): ...@@ -9,7 +9,7 @@ if sys.version_info < (3, 8):
# compatibility for python <3.8 # compatibility for python <3.8
import importlib_metadata as metadata import importlib_metadata as metadata
else: else:
from importlib import metadata # noqa: F401, TC002 from importlib import metadata
WINDOWS = sys.platform == "win32" WINDOWS = sys.platform == "win32"
...@@ -49,3 +49,6 @@ def list_to_shell_command(cmd: list[str]) -> str: ...@@ -49,3 +49,6 @@ def list_to_shell_command(cmd: list[str]) -> str:
f'"{token}"' if " " in token and token[0] not in {"'", '"'} else token f'"{token}"' if " " in token and token[0] not in {"'", '"'} else token
for token in cmd for token in cmd
) )
__all__ = ["WINDOWS", "decode", "encode", "list_to_shell_command", "metadata", "to_str"]
...@@ -119,7 +119,8 @@ class Authenticator: ...@@ -119,7 +119,8 @@ class Authenticator:
if not self.is_cached: if not self.is_cached:
return session return session
return CacheControl(sess=session, cache=self._cache_control) session = CacheControl(sess=session, cache=self._cache_control)
return session
def get_session(self, url: str | None = None) -> requests.Session: def get_session(self, url: str | None = None) -> requests.Session:
if not url: if not url:
...@@ -188,7 +189,7 @@ class Authenticator: ...@@ -188,7 +189,7 @@ class Authenticator:
if verify is not None: if verify is not None:
verify = str(verify) verify = str(verify)
settings = session.merge_environment_settings( settings = session.merge_environment_settings( # type: ignore[no-untyped-call]
prepared_request.url, proxies, stream, verify, cert prepared_request.url, proxies, stream, verify, cert
) )
......
...@@ -1852,7 +1852,7 @@ class MockEnv(NullEnv): ...@@ -1852,7 +1852,7 @@ class MockEnv(NullEnv):
marker_env: dict[str, Any] = None, marker_env: dict[str, Any] = None,
supported_tags: list[Tag] = None, supported_tags: list[Tag] = None,
**kwargs: Any, **kwargs: Any,
): ) -> None:
super().__init__(**kwargs) super().__init__(**kwargs)
self._version_info = version_info self._version_info = version_info
......
...@@ -59,7 +59,7 @@ def get_client_cert(config: Config, repository_name: str) -> Path | None: ...@@ -59,7 +59,7 @@ def get_client_cert(config: Config, repository_name: str) -> Path | None:
return None return None
def _on_rm_error(func: Callable, path: str, exc_info: Exception) -> None: def _on_rm_error(func: Callable[[str], None], path: str, exc_info: Exception) -> None:
if not os.path.exists(path): if not os.path.exists(path):
return return
...@@ -84,7 +84,7 @@ def remove_directory( ...@@ -84,7 +84,7 @@ def remove_directory(
shutil.rmtree(path, *args, **kwargs) shutil.rmtree(path, *args, **kwargs)
def merge_dicts(d1: dict, d2: dict) -> None: def merge_dicts(d1: dict[str, Any], d2: dict[str, Any]) -> None:
for k in d2.keys(): for k in d2.keys():
if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], Mapping): if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], Mapping):
merge_dicts(d1[k], d2[k]) merge_dicts(d1[k], d2[k])
...@@ -119,7 +119,8 @@ def get_package_version_display_string( ...@@ -119,7 +119,8 @@ def get_package_version_display_string(
path = Path(os.path.relpath(package.source_url, root.as_posix())).as_posix() path = Path(os.path.relpath(package.source_url, root.as_posix())).as_posix()
return f"{package.version} {path}" return f"{package.version} {path}"
return package.full_pretty_version pretty_version: str = package.full_pretty_version
return pretty_version
def paths_csv(paths: list[Path]) -> str: def paths_csv(paths: list[Path]) -> str:
......
...@@ -168,7 +168,8 @@ class PasswordManager: ...@@ -168,7 +168,8 @@ class PasswordManager:
def get_pypi_token(self, name: str) -> str | None: def get_pypi_token(self, name: str) -> str | None:
if not self.keyring.is_available(): if not self.keyring.is_available():
return self._config.get(f"pypi-token.{name}") token: str | None = self._config.get(f"pypi-token.{name}")
return token
return self.keyring.get_password(name, "__token__") return self.keyring.get_password(name, "__token__")
......
...@@ -25,7 +25,7 @@ class SetupReader: ...@@ -25,7 +25,7 @@ class SetupReader:
FILES = ["setup.py", "setup.cfg"] FILES = ["setup.py", "setup.cfg"]
@classmethod @classmethod
def read_from_directory(cls, directory: str | Path) -> dict[str, list | dict]: def read_from_directory(cls, directory: str | Path) -> dict[str, Any]:
if isinstance(directory, str): if isinstance(directory, str):
directory = Path(directory) directory = Path(directory)
...@@ -44,7 +44,7 @@ class SetupReader: ...@@ -44,7 +44,7 @@ class SetupReader:
return result return result
def read_setup_py(self, filepath: str | Path) -> dict[str, list | dict]: def read_setup_py(self, filepath: str | Path) -> dict[str, Any]:
if isinstance(filepath, str): if isinstance(filepath, str):
filepath = Path(filepath) filepath = Path(filepath)
......
...@@ -3,4 +3,4 @@ from __future__ import annotations ...@@ -3,4 +3,4 @@ from __future__ import annotations
from poetry.vcs.git.backend import Git from poetry.vcs.git.backend import Git
__all__ = [Git.__name__] __all__ = ["Git"]
...@@ -149,18 +149,21 @@ class GitRepoLocalInfo: ...@@ -149,18 +149,21 @@ class GitRepoLocalInfo:
class Git: class Git:
@staticmethod @staticmethod
def as_repo(repo: Path | str) -> Repo: def as_repo(repo: Path | str) -> Repo:
return Repo(repo) return Repo(str(repo)) # type: ignore[no-untyped-call]
@staticmethod @staticmethod
def get_remote_url(repo: Repo, remote: str = "origin") -> str: def get_remote_url(repo: Repo, remote: str = "origin") -> str:
with repo: with repo:
config = repo.get_config() config = repo.get_config()
section = (b"remote", remote.encode("utf-8")) section = (b"remote", remote.encode("utf-8"))
return (
config.get(section, b"url").decode("utf-8") url = ""
if config.has_section(section) if config.has_section(section): # type: ignore[no-untyped-call]
else "" value = config.get(section, b"url") # type: ignore[no-untyped-call]
) assert value is not None
url = value.decode("utf-8")
return url
@staticmethod @staticmethod
def get_revision(repo: Repo) -> str: def get_revision(repo: Repo) -> str:
...@@ -184,16 +187,17 @@ class Git: ...@@ -184,16 +187,17 @@ class Git:
path: str path: str
credentials = get_default_authenticator().get_credentials_for_url(url=url) credentials = get_default_authenticator().get_credentials_for_url(url=url)
client, path = get_transport_and_path( client, path = get_transport_and_path( # type: ignore[no-untyped-call]
url, username=credentials.username, password=credentials.password url, username=credentials.username, password=credentials.password
) )
with local: with local:
return client.fetch( result: FetchPackResult = client.fetch( # type: ignore[no-untyped-call]
path, path,
local, local,
determine_wants=local.object_store.determine_wants_all, determine_wants=local.object_store.determine_wants_all,
) )
return result
@staticmethod @staticmethod
def _clone_legacy(url: str, refspec: GitRefSpec, target: Path) -> Repo: def _clone_legacy(url: str, refspec: GitRefSpec, target: Path) -> Repo:
...@@ -229,7 +233,8 @@ class Git: ...@@ -229,7 +233,8 @@ class Git:
f"Failed to checkout {url} at '{revision}'" f"Failed to checkout {url} at '{revision}'"
) )
return Repo(target) repo = Repo(str(target)) # type: ignore[no-untyped-call]
return repo
@classmethod @classmethod
def _clone(cls, url: str, refspec: GitRefSpec, target: Path) -> Repo: def _clone(cls, url: str, refspec: GitRefSpec, target: Path) -> Repo:
...@@ -237,11 +242,12 @@ class Git: ...@@ -237,11 +242,12 @@ class Git:
Helper method to clone a remove repository at the given `url` at the specified Helper method to clone a remove repository at the given `url` at the specified
ref spec. ref spec.
""" """
local: Repo
if not target.exists(): if not target.exists():
local = Repo.init(target, mkdir=True) local = Repo.init(str(target), mkdir=True) # type: ignore[no-untyped-call]
porcelain.remote_add(local, "origin", url) porcelain.remote_add(local, "origin", url) # type: ignore[no-untyped-call]
else: else:
local = Repo(target) local = Repo(str(target)) # type: ignore[no-untyped-call]
remote_refs = cls._fetch_remote_refs(url=url, local=local) remote_refs = cls._fetch_remote_refs(url=url, local=local)
...@@ -268,7 +274,7 @@ class Git: ...@@ -268,7 +274,7 @@ class Git:
(b"refs/remotes/origin", b"refs/heads/"), (b"refs/remotes/origin", b"refs/heads/"),
(b"refs/tags", b"refs/tags"), (b"refs/tags", b"refs/tags"),
}: }:
local.refs.import_refs( local.refs.import_refs( # type: ignore[no-untyped-call]
base=base, base=base,
other={ other={
n[len(prefix) :]: v n[len(prefix) :]: v
...@@ -279,7 +285,7 @@ class Git: ...@@ -279,7 +285,7 @@ class Git:
try: try:
with local: with local:
local.reset_index() local.reset_index() # type: ignore[no-untyped-call]
except (AssertionError, KeyError) as e: except (AssertionError, KeyError) as e:
# this implies the ref we need does not exist or is invalid # this implies the ref we need does not exist or is invalid
if isinstance(e, KeyError): if isinstance(e, KeyError):
...@@ -321,7 +327,8 @@ class Git: ...@@ -321,7 +327,8 @@ class Git:
url: bytes url: bytes
path: bytes path: bytes
for path, url, _ in parse_submodules(config): submodules = parse_submodules(config) # type: ignore[no-untyped-call]
for path, url, _ in submodules:
path_relative = Path(path.decode("utf-8")) path_relative = Path(path.decode("utf-8"))
path_absolute = repo_root.joinpath(path_relative) path_absolute = repo_root.joinpath(path_relative)
...@@ -344,11 +351,12 @@ class Git: ...@@ -344,11 +351,12 @@ class Git:
def is_using_legacy_client() -> bool: def is_using_legacy_client() -> bool:
from poetry.factory import Factory from poetry.factory import Factory
return ( legacy_client: bool = (
Factory.create_config() Factory.create_config()
.get("experimental", {}) .get("experimental", {})
.get("system-git-client", False) .get("system-git-client", False)
) )
return legacy_client
@staticmethod @staticmethod
def get_default_source_root() -> Path: def get_default_source_root() -> Path:
...@@ -381,7 +389,7 @@ class Git: ...@@ -381,7 +389,7 @@ class Git:
else: else:
# check if the current local copy matches the requested ref spec # check if the current local copy matches the requested ref spec
try: try:
current_repo = Repo(target) current_repo = Repo(str(target)) # type: ignore[no-untyped-call]
with current_repo: with current_repo:
current_sha = current_repo.head().decode("utf-8") current_sha = current_repo.head().decode("utf-8")
......
...@@ -48,10 +48,9 @@ class SystemGit: ...@@ -48,10 +48,9 @@ class SystemGit:
folder.as_posix(), folder.as_posix(),
) + args ) + args
git_command = find_git_command() # type: ignore[no-untyped-call]
return ( return (
subprocess.check_output( subprocess.check_output(git_command + list(args), stderr=subprocess.STDOUT)
find_git_command() + list(args), stderr=subprocess.STDOUT
)
.decode() .decode()
.strip() .strip()
) )
......
...@@ -103,7 +103,8 @@ def test_group_options_are_passed_to_the_installer( ...@@ -103,7 +103,8 @@ def test_group_options_are_passed_to_the_installer(
""" """
mocker.patch.object(tester.command.installer, "run", return_value=0) mocker.patch.object(tester.command.installer, "run", return_value=0)
editable_builder_mock = mocker.patch( editable_builder_mock = mocker.patch(
"poetry.masonry.builders.EditableBuilder", side_effect=ModuleOrPackageNotFound() "poetry.masonry.builders.editable.EditableBuilder",
side_effect=ModuleOrPackageNotFound(),
) )
if not with_root: if not with_root:
......
...@@ -126,7 +126,7 @@ def mock_download(url: str, dest: str, **__: Any) -> None: ...@@ -126,7 +126,7 @@ def mock_download(url: str, dest: str, **__: Any) -> None:
class TestExecutor(Executor): class TestExecutor(Executor):
def __init__(self, *args: Any, **kwargs: Any): def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self._installs = [] self._installs = []
...@@ -162,7 +162,7 @@ class TestExecutor(Executor): ...@@ -162,7 +162,7 @@ class TestExecutor(Executor):
class PoetryTestApplication(Application): class PoetryTestApplication(Application):
def __init__(self, poetry: Poetry): def __init__(self, poetry: Poetry) -> None:
super().__init__() super().__init__()
self._poetry = poetry self._poetry = poetry
...@@ -177,7 +177,7 @@ class PoetryTestApplication(Application): ...@@ -177,7 +177,7 @@ class PoetryTestApplication(Application):
class TestLocker(Locker): class TestLocker(Locker):
def __init__(self, lock: str | Path, local_config: dict): def __init__(self, lock: str | Path, local_config: dict) -> None:
self._lock = TOMLFile(lock) self._lock = TOMLFile(lock)
self._local_config = local_config self._local_config = local_config
self._lock_data = None self._lock_data = None
......
...@@ -62,7 +62,7 @@ class Installer(BaseInstaller): ...@@ -62,7 +62,7 @@ class Installer(BaseInstaller):
class Executor(BaseExecutor): class Executor(BaseExecutor):
def __init__(self, *args: Any, **kwargs: Any): def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self._installs: list[DependencyPackage] = [] self._installs: list[DependencyPackage] = []
...@@ -106,7 +106,7 @@ class CustomInstalledRepository(InstalledRepository): ...@@ -106,7 +106,7 @@ class CustomInstalledRepository(InstalledRepository):
class Locker(BaseLocker): class Locker(BaseLocker):
def __init__(self, lock_path: str | Path): def __init__(self, lock_path: str | Path) -> None:
self._lock = TOMLFile(Path(lock_path).joinpath("poetry.lock")) self._lock = TOMLFile(Path(lock_path).joinpath("poetry.lock"))
self._written_data = None self._written_data = None
self._locked = False self._locked = False
......
...@@ -54,7 +54,7 @@ class CustomInstalledRepository(InstalledRepository): ...@@ -54,7 +54,7 @@ class CustomInstalledRepository(InstalledRepository):
class Locker(BaseLocker): class Locker(BaseLocker):
def __init__(self, lock_path: str | Path): def __init__(self, lock_path: str | Path) -> None:
self._lock = TOMLFile(Path(lock_path).joinpath("poetry.lock")) self._lock = TOMLFile(Path(lock_path).joinpath("poetry.lock"))
self._written_data = None self._written_data = None
self._locked = False self._locked = False
......
...@@ -379,7 +379,9 @@ def test_get_package_retrieves_packages_with_no_hashes(): ...@@ -379,7 +379,9 @@ def test_get_package_retrieves_packages_with_no_hashes():
class MockHttpRepository(LegacyRepository): class MockHttpRepository(LegacyRepository):
def __init__(self, endpoint_responses: dict, http: type[httpretty.httpretty]): def __init__(
self, endpoint_responses: dict, http: type[httpretty.httpretty]
) -> None:
base_url = "http://legacy.foo.bar" base_url = "http://legacy.foo.bar"
super().__init__("legacy", url=base_url, disable_cache=True) super().__init__("legacy", url=base_url, disable_cache=True)
......
...@@ -32,7 +32,7 @@ class MockRepository(PyPiRepository): ...@@ -32,7 +32,7 @@ class MockRepository(PyPiRepository):
JSON_FIXTURES = Path(__file__).parent / "fixtures" / "pypi.org" / "json" JSON_FIXTURES = Path(__file__).parent / "fixtures" / "pypi.org" / "json"
DIST_FIXTURES = Path(__file__).parent / "fixtures" / "pypi.org" / "dists" DIST_FIXTURES = Path(__file__).parent / "fixtures" / "pypi.org" / "dists"
def __init__(self, fallback: bool = False): def __init__(self, fallback: bool = False) -> None:
super().__init__(url="http://foo.bar", disable_cache=True, fallback=fallback) super().__init__(url="http://foo.bar", disable_cache=True, fallback=fallback)
def _get(self, url: str) -> dict | None: def _get(self, url: str) -> dict | None:
......
...@@ -56,7 +56,7 @@ class MockVirtualEnv(VirtualEnv): ...@@ -56,7 +56,7 @@ class MockVirtualEnv(VirtualEnv):
path: Path, path: Path,
base: Path | None = None, base: Path | None = None,
sys_path: list[str] | None = None, sys_path: list[str] | None = None,
): ) -> None:
super().__init__(path, base=base) super().__init__(path, base=base)
self._sys_path = sys_path self._sys_path = sys_path
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment