Skip to content

Commit b392833

Browse files
authored
Merge pull request #10435 from jdufresne/typing-unit
2 parents 7d28893 + 60c274b commit b392833

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+2052
-1273
lines changed

news/872febff-0617-46ff-8b4a-4daa0011df2e.trivial.rst

Whitespace-only changes.

setup.cfg

+6-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,12 @@ follow_imports = skip
5151
[mypy-pip._vendor.requests.*]
5252
follow_imports = skip
5353

54-
[mypy-tests.*]
55-
# TODO: The following option should be removed at some point in the future.
54+
# TODO: The following options should be removed at some point in the future.
55+
[mypy-tests.conftest]
56+
allow_untyped_defs = True
57+
[mypy-tests.lib.*]
58+
allow_untyped_defs = True
59+
[mypy-tests.functional.*]
5660
allow_untyped_defs = True
5761

5862
[tool:pytest]

src/pip/_internal/req/req_file.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,17 @@
88
import shlex
99
import urllib.parse
1010
from optparse import Values
11-
from typing import TYPE_CHECKING, Any, Callable, Dict, Iterator, List, Optional, Tuple
11+
from typing import (
12+
TYPE_CHECKING,
13+
Any,
14+
Callable,
15+
Dict,
16+
Iterable,
17+
Iterator,
18+
List,
19+
Optional,
20+
Tuple,
21+
)
1222

1323
from pip._internal.cli import cmdoptions
1424
from pip._internal.exceptions import InstallationError, RequirementsFileParseError
@@ -27,7 +37,7 @@
2737

2838
__all__ = ["parse_requirements"]
2939

30-
ReqFileLines = Iterator[Tuple[int, str]]
40+
ReqFileLines = Iterable[Tuple[int, str]]
3141

3242
LineParser = Callable[[str], Tuple[str, Values]]
3343

src/pip/_internal/req/req_install.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import sys
88
import uuid
99
import zipfile
10-
from typing import Any, Dict, Iterable, List, Optional, Sequence, Union
10+
from typing import Any, Collection, Dict, Iterable, List, Optional, Sequence, Union
1111

1212
from pip._vendor import pkg_resources
1313
from pip._vendor.packaging.markers import Marker
@@ -103,7 +103,7 @@ def __init__(
103103
global_options: Optional[List[str]] = None,
104104
hash_options: Optional[Dict[str, List[str]]] = None,
105105
constraint: bool = False,
106-
extras: Iterable[str] = (),
106+
extras: Collection[str] = (),
107107
user_supplied: bool = False,
108108
) -> None:
109109
assert req is None or isinstance(req, Requirement), req

src/pip/_internal/resolution/base.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
from typing import Callable, List
1+
from typing import Callable, List, Optional
22

33
from pip._internal.req.req_install import InstallRequirement
44
from pip._internal.req.req_set import RequirementSet
55

6-
InstallRequirementProvider = Callable[[str, InstallRequirement], InstallRequirement]
6+
InstallRequirementProvider = Callable[
7+
[str, Optional[InstallRequirement]], InstallRequirement
8+
]
79

810

911
class BaseResolver:

src/pip/_internal/resolution/resolvelib/factory.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ def _iter_candidates_from_constraints(
347347
def find_candidates(
348348
self,
349349
identifier: str,
350-
requirements: Mapping[str, Iterator[Requirement]],
350+
requirements: Mapping[str, Iterable[Requirement]],
351351
incompatibilities: Mapping[str, Iterator[Candidate]],
352352
constraint: Constraint,
353353
prefers_installed: bool,
@@ -484,7 +484,7 @@ def make_requirement_from_candidate(
484484
def make_requirement_from_spec(
485485
self,
486486
specifier: str,
487-
comes_from: InstallRequirement,
487+
comes_from: Optional[InstallRequirement],
488488
requested_extras: Iterable[str] = (),
489489
) -> Optional[Requirement]:
490490
ireq = self._make_install_req_from_spec(specifier, comes_from)

tests/lib/requests_mocks.py

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def __init__(self, contents):
2929
self.url = None
3030
self.headers = {"Content-Length": len(contents)}
3131
self.history = []
32+
self.from_cache = False
3233

3334

3435
class MockConnection:

tests/unit/resolution_resolvelib/conftest.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import Iterator
2+
13
import pytest
24

35
from pip._internal.cli.req_command import RequirementCommand
@@ -9,15 +11,17 @@
911
from pip._internal.models.search_scope import SearchScope
1012
from pip._internal.models.selection_prefs import SelectionPreferences
1113
from pip._internal.network.session import PipSession
14+
from pip._internal.operations.prepare import RequirementPreparer
1215
from pip._internal.req.constructors import install_req_from_line
1316
from pip._internal.req.req_tracker import get_requirement_tracker
1417
from pip._internal.resolution.resolvelib.factory import Factory
1518
from pip._internal.resolution.resolvelib.provider import PipProvider
1619
from pip._internal.utils.temp_dir import TempDirectory, global_tempdir_manager
20+
from tests.lib import TestData
1721

1822

1923
@pytest.fixture
20-
def finder(data):
24+
def finder(data: TestData) -> Iterator[PackageFinder]:
2125
session = PipSession()
2226
scope = SearchScope([str(data.packages)], [])
2327
collector = LinkCollector(session, scope)
@@ -27,7 +31,7 @@ def finder(data):
2731

2832

2933
@pytest.fixture
30-
def preparer(finder):
34+
def preparer(finder: PackageFinder) -> Iterator[RequirementPreparer]:
3135
session = PipSession()
3236
rc = InstallCommand("x", "y")
3337
o = rc.parse_args([])
@@ -48,7 +52,7 @@ def preparer(finder):
4852

4953

5054
@pytest.fixture
51-
def factory(finder, preparer):
55+
def factory(finder: PackageFinder, preparer: RequirementPreparer) -> Iterator[Factory]:
5256
yield Factory(
5357
finder=finder,
5458
preparer=preparer,
@@ -63,7 +67,7 @@ def factory(finder, preparer):
6367

6468

6569
@pytest.fixture
66-
def provider(factory):
70+
def provider(factory: Factory) -> Iterator[PipProvider]:
6771
yield PipProvider(
6872
factory=factory,
6973
constraints={},

tests/unit/resolution_resolvelib/test_requirement.py

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
from typing import Iterator, List, Tuple
2+
13
import pytest
24
from pip._vendor.resolvelib import BaseReporter, Resolver
35

4-
from pip._internal.resolution.resolvelib.base import Candidate, Constraint
6+
from pip._internal.resolution.resolvelib.base import Candidate, Constraint, Requirement
7+
from pip._internal.resolution.resolvelib.factory import Factory
8+
from pip._internal.resolution.resolvelib.provider import PipProvider
59
from pip._internal.utils.urls import path_to_url
10+
from tests.lib import TestData
11+
from tests.lib.path import Path
612

713
# NOTE: All tests are prefixed `test_rlr` (for "test resolvelib resolver").
814
# This helps select just these tests using pytest's `-k` option, and
@@ -18,11 +24,11 @@
1824

1925

2026
@pytest.fixture
21-
def test_cases(data):
22-
def data_file(name):
27+
def test_cases(data: TestData) -> Iterator[List[Tuple[str, str, int]]]:
28+
def data_file(name: str) -> Path:
2329
return data.packages.joinpath(name)
2430

25-
def data_url(name):
31+
def data_url(name: str) -> str:
2632
return path_to_url(data_file(name))
2733

2834
test_cases = [
@@ -47,17 +53,23 @@ def data_url(name):
4753
yield test_cases
4854

4955

50-
def test_new_resolver_requirement_has_name(test_cases, factory):
56+
def test_new_resolver_requirement_has_name(
57+
test_cases: List[Tuple[str, str, int]], factory: Factory
58+
) -> None:
5159
"""All requirements should have a name"""
5260
for spec, name, _ in test_cases:
5361
req = factory.make_requirement_from_spec(spec, comes_from=None)
62+
assert req is not None
5463
assert req.name == name
5564

5665

57-
def test_new_resolver_correct_number_of_matches(test_cases, factory):
66+
def test_new_resolver_correct_number_of_matches(
67+
test_cases: List[Tuple[str, str, int]], factory: Factory
68+
) -> None:
5869
"""Requirements should return the correct number of candidates"""
5970
for spec, _, match_count in test_cases:
6071
req = factory.make_requirement_from_spec(spec, comes_from=None)
72+
assert req is not None
6173
matches = factory.find_candidates(
6274
req.name,
6375
{req.name: [req]},
@@ -68,10 +80,13 @@ def test_new_resolver_correct_number_of_matches(test_cases, factory):
6880
assert sum(1 for _ in matches) == match_count
6981

7082

71-
def test_new_resolver_candidates_match_requirement(test_cases, factory):
83+
def test_new_resolver_candidates_match_requirement(
84+
test_cases: List[Tuple[str, str, int]], factory: Factory
85+
) -> None:
7286
"""Candidates returned from find_candidates should satisfy the requirement"""
7387
for spec, _, _ in test_cases:
7488
req = factory.make_requirement_from_spec(spec, comes_from=None)
89+
assert req is not None
7590
candidates = factory.find_candidates(
7691
req.name,
7792
{req.name: [req]},
@@ -84,9 +99,10 @@ def test_new_resolver_candidates_match_requirement(test_cases, factory):
8499
assert req.is_satisfied_by(c)
85100

86101

87-
def test_new_resolver_full_resolve(factory, provider):
102+
def test_new_resolver_full_resolve(factory: Factory, provider: PipProvider) -> None:
88103
"""A very basic full resolve"""
89104
req = factory.make_requirement_from_spec("simplewheel", comes_from=None)
90-
r = Resolver(provider, BaseReporter())
105+
assert req is not None
106+
r: Resolver[Requirement, Candidate, str] = Resolver(provider, BaseReporter())
91107
result = r.resolve([req])
92108
assert set(result.mapping.keys()) == {"simplewheel"}

tests/unit/resolution_resolvelib/test_resolver.py

+26-13
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
from typing import Dict, List, Optional, Tuple, cast
12
from unittest import mock
23

34
import pytest
45
from pip._vendor.packaging.utils import canonicalize_name
56
from pip._vendor.resolvelib.resolvers import Result
67
from pip._vendor.resolvelib.structs import DirectedGraph
78

9+
from pip._internal.index.package_finder import PackageFinder
10+
from pip._internal.operations.prepare import RequirementPreparer
811
from pip._internal.req.constructors import install_req_from_line
912
from pip._internal.req.req_set import RequirementSet
1013
from pip._internal.resolution.resolvelib.resolver import (
@@ -14,29 +17,31 @@
1417

1518

1619
@pytest.fixture()
17-
def resolver(preparer, finder):
20+
def resolver(preparer: RequirementPreparer, finder: PackageFinder) -> Resolver:
1821
resolver = Resolver(
1922
preparer=preparer,
2023
finder=finder,
2124
wheel_cache=None,
2225
make_install_req=mock.Mock(),
23-
use_user_site="not-used",
24-
ignore_dependencies="not-used",
25-
ignore_installed="not-used",
26-
ignore_requires_python="not-used",
27-
force_reinstall="not-used",
26+
use_user_site=False,
27+
ignore_dependencies=False,
28+
ignore_installed=False,
29+
ignore_requires_python=False,
30+
force_reinstall=False,
2831
upgrade_strategy="to-satisfy-only",
2932
)
3033
return resolver
3134

3235

33-
def _make_graph(edges):
36+
def _make_graph(
37+
edges: List[Tuple[Optional[str], Optional[str]]]
38+
) -> "DirectedGraph[Optional[str]]":
3439
"""Build graph from edge declarations."""
3540

36-
graph = DirectedGraph()
41+
graph: "DirectedGraph[Optional[str]]" = DirectedGraph()
3742
for parent, child in edges:
38-
parent = canonicalize_name(parent) if parent else None
39-
child = canonicalize_name(child) if child else None
43+
parent = cast(str, canonicalize_name(parent)) if parent else None
44+
child = cast(str, canonicalize_name(child)) if child else None
4045
for v in (parent, child):
4146
if v not in graph:
4247
graph.add(v)
@@ -76,12 +81,16 @@ def _make_graph(edges):
7681
),
7782
],
7883
)
79-
def test_new_resolver_get_installation_order(resolver, edges, ordered_reqs):
84+
def test_new_resolver_get_installation_order(
85+
resolver: Resolver,
86+
edges: List[Tuple[Optional[str], Optional[str]]],
87+
ordered_reqs: List[str],
88+
) -> None:
8089
graph = _make_graph(edges)
8190

8291
# Mapping values and criteria are not used in test, so we stub them out.
8392
mapping = {vertex: None for vertex in graph if vertex is not None}
84-
resolver._result = Result(mapping, graph, criteria=None)
93+
resolver._result = Result(mapping, graph, criteria=None) # type: ignore
8594

8695
reqset = RequirementSet()
8796
for r in ordered_reqs:
@@ -229,7 +238,11 @@ def test_new_resolver_get_installation_order(resolver, edges, ordered_reqs):
229238
),
230239
],
231240
)
232-
def test_new_resolver_topological_weights(name, edges, expected_weights):
241+
def test_new_resolver_topological_weights(
242+
name: str,
243+
edges: List[Tuple[Optional[str], Optional[str]]],
244+
expected_weights: Dict[Optional[str], int],
245+
) -> None:
233246
graph = _make_graph(edges)
234247

235248
weights = get_topological_weights(graph, len(expected_weights))

0 commit comments

Comments
 (0)