Skip to content

Commit

Permalink
more type-checking (python-poetry#7845)
Browse files Browse the repository at this point in the history
  • Loading branch information
dimbleby authored Apr 27, 2023
1 parent 978d435 commit 603b398
Show file tree
Hide file tree
Showing 39 changed files with 413 additions and 227 deletions.
6 changes: 3 additions & 3 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 8 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ force-exclude = '''


[tool.mypy]
files = "src"
files = "src, tests"
mypy_path = "src"
namespace_packages = true
explicit_package_bases = true
Expand All @@ -195,17 +195,17 @@ exclude = [
"tests/utils/fixtures"
]

# use of importlib-metadata backport at python3.7 makes it impossible to
# satisfy mypy without some ignores: but we get a different set of ignores at
# different python versions.
#
# <https://github.com/python/mypy/issues/8823>, meanwhile suppress that
# warning.
# use of importlib-metadata backport makes it impossible to satisfy mypy
# without some ignores: but we get different sets of ignores at different
# python versions.
[[tool.mypy.overrides]]
module = [
'poetry.plugins.plugin_manager',
'poetry.repositories.installed_repository',
'poetry.utils.env',
'tests.helpers',
'tests.repositories.test_installed_repository',
'tests.console.commands.self.test_show_plugins'
]
warn_unused_ignores = false

Expand All @@ -222,6 +222,7 @@ module = [
'shellingham.*',
'virtualenv.*',
'xattr.*',
'zipp.*'
]
ignore_missing_imports = true

Expand Down
2 changes: 1 addition & 1 deletion src/poetry/repositories/pypi_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def find_links_for_package(self, package: Package) -> list[Link]:

def _get_release_info(
self, name: NormalizedName, version: Version
) -> dict[str, str | list[str] | None]:
) -> dict[str, Any]:
from poetry.inspection.info import PackageInfo

self._log(f"Getting info for {name} ({version}) from PyPI", "debug")
Expand Down
7 changes: 0 additions & 7 deletions src/poetry/utils/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -1727,13 +1727,11 @@ def __init__(self, path: Path, base: Path | None = None) -> None:
# from inside the virtualenv.
if base is None:
output = self.run_python_script(GET_BASE_PREFIX)
assert isinstance(output, str)
self._base = Path(output.strip())

@property
def sys_path(self) -> list[str]:
output = self.run_python_script(GET_SYS_PATH)
assert isinstance(output, str)
paths: list[str] = json.loads(output)
return paths

Expand All @@ -1749,20 +1747,17 @@ def get_python_implementation(self) -> str:

def get_supported_tags(self) -> list[Tag]:
output = self.run_python_script(GET_SYS_TAGS)
assert isinstance(output, str)

return [Tag(*t) for t in json.loads(output)]

def get_marker_env(self) -> dict[str, Any]:
output = self.run_python_script(GET_ENVIRONMENT_INFO)
assert isinstance(output, str)

env: dict[str, Any] = json.loads(output)
return env

def get_pip_version(self) -> Version:
output = self.run_pip("--version")
assert isinstance(output, str)
output = output.strip()

m = re.match("pip (.+?)(?: from .+)?$", output)
Expand All @@ -1773,7 +1768,6 @@ def get_pip_version(self) -> Version:

def get_paths(self) -> dict[str, str]:
output = self.run_python_script(GET_PATHS)
assert isinstance(output, str)
paths: dict[str, str] = json.loads(output)
return paths

Expand Down Expand Up @@ -1889,7 +1883,6 @@ def find_executables(self) -> None:

def get_paths(self) -> dict[str, str]:
output = self.run_python_script(GET_PATHS_FOR_GENERIC_ENVS)
assert isinstance(output, str)

paths: dict[str, str] = json.loads(output)
return paths
Expand Down
10 changes: 7 additions & 3 deletions tests/config/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
from collections.abc import Callable
from collections.abc import Iterator

Normalizer = Callable[[str], Any]

def get_options_based_on_normalizer(normalizer: Callable[[str], Any]) -> str:

def get_options_based_on_normalizer(normalizer: Normalizer) -> Iterator[str]:
flattened_config = flatten_dict(obj=Config.default_config, delimiter=".")

for k in flattened_config:
Expand All @@ -42,10 +44,12 @@ def test_config_get_processes_depended_on_values(


def generate_environment_variable_tests() -> Iterator[tuple[str, str, str, bool]]:
for normalizer, values in [
data: list[tuple[Normalizer, list[tuple[str, Any]]]] = [
(boolean_normalizer, [("true", True), ("false", False)]),
(int_normalizer, [("4", 4), ("2", 2)]),
]:
]

for normalizer, values in data:
for env_value, value in values:
for name in get_options_based_on_normalizer(normalizer=normalizer):
env_var = "POETRY_" + re.sub("[.-]+", "_", name).upper()
Expand Down
22 changes: 14 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def dummy_keyring() -> DummyBackend:
def with_simple_keyring(dummy_keyring: DummyBackend) -> None:
import keyring

keyring.set_keyring(dummy_keyring)
keyring.set_keyring(dummy_keyring) # type: ignore[no-untyped-call]


@pytest.fixture()
Expand All @@ -130,7 +130,7 @@ def with_fail_keyring() -> None:

from keyring.backends.fail import Keyring

keyring.set_keyring(Keyring())
keyring.set_keyring(Keyring()) # type: ignore[no-untyped-call]


@pytest.fixture()
Expand All @@ -139,31 +139,37 @@ def with_null_keyring() -> None:

from keyring.backends.null import Keyring

keyring.set_keyring(Keyring())
keyring.set_keyring(Keyring()) # type: ignore[no-untyped-call]


@pytest.fixture()
def with_chained_fail_keyring(mocker: MockerFixture) -> None:
from keyring.backends.fail import Keyring

mocker.patch("keyring.backend.get_all_keyring", lambda: [Keyring()])
mocker.patch(
"keyring.backend.get_all_keyring",
lambda: [Keyring()], # type: ignore[no-untyped-call]
)
import keyring

from keyring.backends.chainer import ChainerBackend

keyring.set_keyring(ChainerBackend())
keyring.set_keyring(ChainerBackend()) # type: ignore[no-untyped-call]


@pytest.fixture()
def with_chained_null_keyring(mocker: MockerFixture) -> None:
from keyring.backends.null import Keyring

mocker.patch("keyring.backend.get_all_keyring", lambda: [Keyring()])
mocker.patch(
"keyring.backend.get_all_keyring",
lambda: [Keyring()], # type: ignore[no-untyped-call]
)
import keyring

from keyring.backends.chainer import ChainerBackend

keyring.set_keyring(ChainerBackend())
keyring.set_keyring(ChainerBackend()) # type: ignore[no-untyped-call]


@pytest.fixture
Expand Down Expand Up @@ -203,7 +209,7 @@ def config(

from keyring.backends.fail import Keyring

keyring.set_keyring(Keyring())
keyring.set_keyring(Keyring()) # type: ignore[no-untyped-call]

c = Config()
c.merge(config_source.config)
Expand Down
3 changes: 2 additions & 1 deletion tests/console/commands/env/test_use.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any

import pytest
import tomlkit
Expand Down Expand Up @@ -83,7 +84,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(

envs_file = TOMLFile(venv_cache / "envs.toml")
assert envs_file.exists()
envs = envs_file.read()
envs: dict[str, Any] = envs_file.read()
assert envs[venv_name]["minor"] == "3.7"
assert envs[venv_name]["patch"] == "3.7.1"

Expand Down
5 changes: 0 additions & 5 deletions tests/console/commands/self/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ def _patch_repos(repo: TestRepository, installed: Repository) -> None:
installed.add_package(poetry)


@pytest.fixture(autouse=True)
def save_environ(environ: None) -> Repository:
yield


@pytest.fixture()
def pool(repo: TestRepository) -> RepositoryPool:
return RepositoryPool([repo])
Expand Down
24 changes: 14 additions & 10 deletions tests/console/commands/self/test_add_plugins.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
from __future__ import annotations

from typing import TYPE_CHECKING
from typing import Any


if TYPE_CHECKING:
from collections.abc import Mapping

import pytest

from poetry.core.packages.package import Package

from poetry.console.commands.add import AddCommand
from poetry.console.commands.self.self_command import SelfCommand
from poetry.factory import Factory
from tests.console.commands.self.utils import get_self_command_dependencies
Expand All @@ -26,10 +32,10 @@ def tester(command_tester_factory: CommandTesterFactory) -> CommandTester:
def assert_plugin_add_result(
tester: CommandTester,
expected: str,
constraint: str | dict[str, str],
constraint: str | Mapping[str, str | list[str]],
) -> None:
assert tester.io.fetch_output() == expected
dependencies = get_self_command_dependencies()
dependencies: dict[str, Any] = get_self_command_dependencies()

assert "poetry-plugin" in dependencies
assert dependencies["poetry-plugin"] == constraint
Expand Down Expand Up @@ -128,14 +134,11 @@ def test_add_with_git_constraint_with_extras(
Writing lock file
"""

assert_plugin_add_result(
tester,
expected,
{
"git": "https://github.com/demo/poetry-plugin.git",
"extras": ["foo"],
},
)
constraint: dict[str, str | list[str]] = {
"git": "https://github.com/demo/poetry-plugin.git",
"extras": ["foo"],
}
assert_plugin_add_result(tester, expected, constraint)


@pytest.mark.parametrize(
Expand Down Expand Up @@ -212,6 +215,7 @@ def test_add_existing_plugin_warns_about_no_operation(

tester.execute("poetry-plugin")

assert isinstance(tester.command, AddCommand)
expected = f"""\
The following packages are already present in the pyproject.toml and will be\
skipped:
Expand Down
18 changes: 12 additions & 6 deletions tests/console/commands/self/test_show_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ def read_text(self, filename: str) -> str | None:
)
return None

def locate_file(self, path: PathLike[str]) -> PathLike[str]:
def locate_file(self, path: str | PathLike[str]) -> Path:
return tmp_path / path

return MockDistribution()
return MockDistribution() # type: ignore[no-untyped-call]


@pytest.fixture
Expand All @@ -101,10 +101,14 @@ def entry_points(
entry_point_name: str,
entry_point_values_by_group: dict[str, list[str]],
plugin_distro: metadata.Distribution,
) -> Callable[[...], list[metadata.EntryPoint]]:
) -> Callable[..., list[metadata.EntryPoint]]:
by_group = {
key: [
EntryPoint(name=entry_point_name, group=key, value=value)._for(
EntryPoint( # type: ignore[no-untyped-call]
name=entry_point_name,
group=key,
value=value,
)._for( # type: ignore[attr-defined]
plugin_distro
)
for value in values
Expand All @@ -118,7 +122,9 @@ def _entry_points(**params: Any) -> list[metadata.EntryPoint]:
if group not in by_group:
return []

return by_group.get(group)
eps: list[metadata.EntryPoint] = by_group[group]

return eps

return _entry_points

Expand All @@ -130,7 +136,7 @@ def mock_metadata_entry_points(
installed: Repository,
mocker: MockerFixture,
tmp_venv: Env,
entry_points: Callable[[...], metadata.EntryPoint],
entry_points: Callable[..., metadata.EntryPoint],
) -> None:
installed.add_package(plugin_package)

Expand Down
17 changes: 10 additions & 7 deletions tests/console/commands/self/utils.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

from poetry.factory import Factory
from typing import Any

from tomlkit.items import Table as TOMLTable

if TYPE_CHECKING:
from tomlkit.container import Table as TOMLTable
from poetry.factory import Factory


def get_self_command_dependencies(locked: bool = True) -> TOMLTable:
Expand All @@ -24,10 +22,15 @@ def get_self_command_dependencies(locked: bool = True) -> TOMLTable:

poetry = Factory().create_poetry(system_pyproject_file.parent, disable_plugins=True)

content = poetry.file.read()["tool"]["poetry"]
pyproject: dict[str, Any] = poetry.file.read()
content = pyproject["tool"]["poetry"]

assert "group" in content
assert SelfCommand.ADDITIONAL_PACKAGE_GROUP in content["group"]
assert "dependencies" in content["group"][SelfCommand.ADDITIONAL_PACKAGE_GROUP]

return content["group"][SelfCommand.ADDITIONAL_PACKAGE_GROUP]["dependencies"]
dependencies = content["group"][SelfCommand.ADDITIONAL_PACKAGE_GROUP][
"dependencies"
]
assert isinstance(dependencies, TOMLTable)
return dependencies
2 changes: 1 addition & 1 deletion tests/console/commands/source/test_show.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def test_source_show_two(
),
)
def test_source_show_given_priority(
tester_all_types: CommandTester, source_str: Source, request: pytest.FixtureRequest
tester_all_types: CommandTester, source_str: str, request: pytest.FixtureRequest
) -> None:
source = request.getfixturevalue(source_str)
tester_all_types.execute(f"{source.name}")
Expand Down
Loading

0 comments on commit 603b398

Please sign in to comment.