Skip to content

Commit b5d1373

Browse files
committed
chore: work through remaining types
Signed-off-by: Henry Schreiner <[email protected]>
1 parent 69c974f commit b5d1373

File tree

11 files changed

+452
-289
lines changed

11 files changed

+452
-289
lines changed

src/packaging/markers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import os
99
import platform
1010
import sys
11-
from typing import AbstractSet, Any, Callable, Literal, TypedDict, Union, cast
11+
from typing import AbstractSet, Any, Callable, Literal, Mapping, TypedDict, Union, cast
1212

1313
from ._parser import MarkerAtom, MarkerList, Op, Value, Variable
1414
from ._parser import parse_marker as _parse_marker
@@ -314,7 +314,7 @@ def __eq__(self, other: object) -> bool:
314314

315315
def evaluate(
316316
self,
317-
environment: dict[str, str] | None = None,
317+
environment: Mapping[str, str | AbstractSet[str]] | None = None,
318318
context: EvaluateContext = "metadata",
319319
) -> bool:
320320
"""Evaluate a marker.

tests/test_elffile.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
("s390x-s390x", EIClass.C64, EIData.Msb, EMachine.S390),
2323
],
2424
)
25-
def test_elffile_glibc(name, capacity, encoding, machine) -> None:
25+
def test_elffile_glibc(
26+
name: str, capacity: EIClass, encoding: EIData, machine: EMachine
27+
) -> None:
2628
path = DIR_MANYLINUX.joinpath(f"hello-world-{name}")
2729
with path.open("rb") as f:
2830
ef = ELFFile(f)
@@ -46,7 +48,9 @@ def test_elffile_glibc(name, capacity, encoding, machine) -> None:
4648
("x86_64", EIClass.C64, EIData.Lsb, EMachine.X8664, "x86_64"),
4749
],
4850
)
49-
def test_elffile_musl(name, capacity, encoding, machine, interpreter) -> None:
51+
def test_elffile_musl(
52+
name: str, capacity: EIClass, encoding: EIData, machine: EMachine, interpreter: str
53+
) -> None:
5054
path = DIR_MUSLLINUX.joinpath(f"musl-{name}")
5155
with path.open("rb") as f:
5256
ef = ELFFile(f)
@@ -68,7 +72,7 @@ def test_elffile_musl(name, capacity, encoding, machine, interpreter) -> None:
6872
],
6973
ids=["no-magic", "wrong-magic", "unknown-format"],
7074
)
71-
def test_elffile_bad_ident(data) -> None:
75+
def test_elffile_bad_ident(data: bytes) -> None:
7276
with pytest.raises(ELFInvalid):
7377
ELFFile(io.BytesIO(data))
7478

tests/test_manylinux.py

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1+
from __future__ import annotations
2+
13
try:
24
import ctypes
35
except ImportError:
4-
ctypes = None
6+
ctypes = None # type: ignore[assignment]
57
import os
68
import pathlib
79
import platform
810
import re
911
import sys
1012
import types
13+
import typing
14+
15+
if typing.TYPE_CHECKING:
16+
from collections.abc import Generator
1117

1218
import pretend
1319
import pytest
@@ -18,20 +24,21 @@
1824
_glibc_version_string,
1925
_glibc_version_string_confstr,
2026
_glibc_version_string_ctypes,
27+
_GLibCVersion,
2128
_is_compatible,
2229
_parse_elf,
2330
_parse_glibc_version,
2431
)
2532

2633

2734
@pytest.fixture(autouse=True)
28-
def clear_lru_cache():
35+
def clear_lru_cache() -> Generator[None, None, None]:
2936
yield
3037
_get_glibc_version.cache_clear()
3138

3239

3340
@pytest.fixture
34-
def manylinux_module(monkeypatch: pytest.MonkeyPatch):
41+
def manylinux_module(monkeypatch: pytest.MonkeyPatch) -> types.ModuleType:
3542
monkeypatch.setattr(_manylinux, "_get_glibc_version", lambda *args: (2, 20))
3643
module_name = "_manylinux"
3744
module = types.ModuleType(module_name)
@@ -44,44 +51,54 @@ def manylinux_module(monkeypatch: pytest.MonkeyPatch):
4451
("attribute", "glibc"), [("1", (2, 5)), ("2010", (2, 12)), ("2014", (2, 17))]
4552
)
4653
def test_module_declaration(
47-
monkeypatch: pytest.MonkeyPatch, manylinux_module, attribute, glibc, tf
54+
monkeypatch: pytest.MonkeyPatch,
55+
manylinux_module: types.ModuleType,
56+
attribute: str,
57+
glibc: tuple[int, int],
58+
tf: bool,
4859
) -> None:
4960
manylinux = f"manylinux{attribute}_compatible"
5061
monkeypatch.setattr(manylinux_module, manylinux, tf, raising=False)
51-
res = _is_compatible("x86_64", glibc)
62+
glibc_version = _GLibCVersion(glibc[0], glibc[1])
63+
res = _is_compatible("x86_64", glibc_version)
5264
assert tf is res
5365

5466

5567
@pytest.mark.parametrize(
5668
("attribute", "glibc"), [("1", (2, 5)), ("2010", (2, 12)), ("2014", (2, 17))]
5769
)
5870
def test_module_declaration_missing_attribute(
59-
monkeypatch: pytest.MonkeyPatch, manylinux_module, attribute, glibc
60-
):
71+
monkeypatch: pytest.MonkeyPatch,
72+
manylinux_module: types.ModuleType,
73+
attribute: str,
74+
glibc: tuple[int, int],
75+
) -> None:
6176
manylinux = f"manylinux{attribute}_compatible"
6277
monkeypatch.delattr(manylinux_module, manylinux, raising=False)
63-
assert _is_compatible("x86_64", glibc)
78+
glibc_version = _GLibCVersion(glibc[0], glibc[1])
79+
assert _is_compatible("x86_64", glibc_version)
6480

6581

6682
@pytest.mark.parametrize(
6783
("version", "compatible"), [((2, 0), True), ((2, 5), True), ((2, 10), False)]
6884
)
6985
def test_is_manylinux_compatible_glibc_support(
70-
version, compatible, monkeypatch: pytest.MonkeyPatch
86+
version: tuple[int, int], compatible: bool, monkeypatch: pytest.MonkeyPatch
7187
) -> None:
7288
monkeypatch.setitem(sys.modules, "_manylinux", None)
7389
monkeypatch.setattr(_manylinux, "_get_glibc_version", lambda: (2, 5))
74-
assert bool(_is_compatible("any", version)) == compatible
90+
glibc_version = _GLibCVersion(version[0], version[1])
91+
assert bool(_is_compatible("any", glibc_version)) == compatible
7592

7693

7794
@pytest.mark.parametrize("version_str", ["glibc-2.4.5", "2"])
78-
def test_check_glibc_version_warning(version_str) -> None:
95+
def test_check_glibc_version_warning(version_str: str) -> None:
7996
msg = f"Expected glibc version with 2 components major.minor, got: {version_str}"
8097
with pytest.warns(RuntimeWarning, match=re.escape(msg)):
8198
_parse_glibc_version(version_str)
8299

83100

84-
@pytest.mark.skipif(not ctypes, reason="requires ctypes")
101+
@pytest.mark.skipif(not ctypes, reason="requires ctypes") # type: ignore[truthy-bool]
85102
@pytest.mark.parametrize(
86103
("version_str", "expected"),
87104
[
@@ -91,17 +108,17 @@ def test_check_glibc_version_warning(version_str) -> None:
91108
],
92109
)
93110
def test_glibc_version_string(
94-
version_str, expected, monkeypatch: pytest.MonkeyPatch
111+
version_str: str | bytes, expected: str, monkeypatch: pytest.MonkeyPatch
95112
) -> None:
96113
class LibcVersion:
97-
def __init__(self, version_str):
114+
def __init__(self, version_str: str | bytes) -> None:
98115
self.version_str = version_str
99116

100-
def __call__(self):
101-
return version_str
117+
def __call__(self) -> str | bytes:
118+
return self.version_str
102119

103120
class ProcessNamespace:
104-
def __init__(self, libc_version):
121+
def __init__(self, libc_version: LibcVersion) -> None:
105122
self.gnu_get_libc_version = libc_version
106123

107124
process_namespace = ProcessNamespace(LibcVersion(version_str))
@@ -131,7 +148,7 @@ def test_glibc_version_string_fail(monkeypatch: pytest.MonkeyPatch) -> None:
131148
[pretend.raiser(ValueError), pretend.raiser(OSError), lambda _: "XXX"],
132149
)
133150
def test_glibc_version_string_confstr_fail(
134-
monkeypatch: pytest.MonkeyPatch, failure
151+
monkeypatch: pytest.MonkeyPatch, failure: typing.Callable[[int], str | None]
135152
) -> None:
136153
monkeypatch.setattr(os, "confstr", failure, raising=False)
137154
assert _glibc_version_string_confstr() is None
@@ -151,7 +168,7 @@ def test_glibc_version_string_ctypes_missing(monkeypatch: pytest.MonkeyPatch) ->
151168
def test_glibc_version_string_ctypes_raise_oserror(
152169
monkeypatch: pytest.MonkeyPatch,
153170
) -> None:
154-
def patched_cdll(_name):
171+
def patched_cdll(_name: str) -> None:
155172
raise OSError("Dynamic loading not supported")
156173

157174
monkeypatch.setattr(ctypes, "CDLL", patched_cdll)
@@ -162,27 +179,29 @@ def patched_cdll(_name):
162179
def test_is_manylinux_compatible_old() -> None:
163180
# Assuming no one is running this test with a version of glibc released in
164181
# 1997.
165-
assert _is_compatible("any", (2, 0))
182+
assert _is_compatible("any", _GLibCVersion(2, 0))
166183

167184

168185
def test_is_manylinux_compatible(monkeypatch: pytest.MonkeyPatch) -> None:
169186
monkeypatch.setattr(_manylinux, "_glibc_version_string", lambda: "2.4")
170-
assert _is_compatible("any", (2, 4))
187+
assert _is_compatible("any", _GLibCVersion(2, 4))
171188

172189

173190
def test_glibc_version_string_none(monkeypatch: pytest.MonkeyPatch) -> None:
174191
monkeypatch.setattr(_manylinux, "_glibc_version_string", lambda: None)
175-
assert not _is_compatible("any", (2, 4))
192+
assert not _is_compatible("any", _GLibCVersion(2, 4))
176193

177194

178195
@pytest.mark.parametrize(
179196
"content", [None, "invalid-magic", "invalid-class", "invalid-data", "too-short"]
180197
)
181-
def test_parse_elf_bad_executable(content) -> None:
198+
def test_parse_elf_bad_executable(content: str | None) -> None:
199+
path_str: str | None
182200
if content:
183201
path = pathlib.Path(__file__).parent / "manylinux" / f"hello-world-{content}"
184-
path = os.fsdecode(path)
202+
path_str = os.fsdecode(path)
185203
else:
186-
path = None
187-
with _parse_elf(path) as ef:
204+
path_str = None
205+
# None is not supported in the type annotation, but it was tested before.
206+
with _parse_elf(path_str) as ef: # type: ignore[arg-type]
188207
assert ef is None

tests/test_markers.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
33
# for complete details.
44

5+
from __future__ import annotations
6+
57
import collections
68
import itertools
79
import os
@@ -60,15 +62,15 @@
6062

6163
class TestNode:
6264
@pytest.mark.parametrize("value", ["one", "two", None, 3, 5, []])
63-
def test_accepts_value(self, value) -> None:
64-
assert Node(value).value == value
65+
def test_accepts_value(self, value: str | None | int | list[str]) -> None:
66+
assert Node(value).value == value # type: ignore[arg-type]
6567

6668
@pytest.mark.parametrize("value", ["one", "two"])
67-
def test_str(self, value) -> None:
69+
def test_str(self, value: str) -> None:
6870
assert str(Node(value)) == str(value)
6971

7072
@pytest.mark.parametrize("value", ["one", "two"])
71-
def test_repr(self, value) -> None:
73+
def test_repr(self, value: str) -> None:
7274
assert repr(Node(value)) == f"<Node({str(value)!r})>"
7375

7476
def test_base_class(self) -> None:
@@ -141,11 +143,11 @@ def test_multidigit_minor_version(self, monkeypatch: pytest.MonkeyPatch) -> None
141143

142144
def tests_when_releaselevel_final(self) -> None:
143145
v = FakeVersionInfo(3, 4, 2, "final", 0)
144-
assert format_full_version(v) == "3.4.2"
146+
assert format_full_version(v) == "3.4.2" # type: ignore[arg-type]
145147

146148
def tests_when_releaselevel_not_final(self) -> None:
147149
v = FakeVersionInfo(3, 4, 2, "beta", 4)
148-
assert format_full_version(v) == "3.4.2b4"
150+
assert format_full_version(v) == "3.4.2b4" # type: ignore[arg-type]
149151

150152

151153
class TestMarker:
@@ -160,7 +162,7 @@ class TestMarker:
160162
for i in itertools.product(VARIABLES, OPERATORS, VALUES)
161163
],
162164
)
163-
def test_parses_valid(self, marker_string) -> None:
165+
def test_parses_valid(self, marker_string: str) -> None:
164166
Marker(marker_string)
165167

166168
@pytest.mark.parametrize(
@@ -174,7 +176,7 @@ def test_parses_valid(self, marker_string) -> None:
174176
'(python_version == "2.7") with random text',
175177
],
176178
)
177-
def test_parses_invalid(self, marker_string) -> None:
179+
def test_parses_invalid(self, marker_string: str) -> None:
178180
with pytest.raises(InvalidMarker):
179181
Marker(marker_string)
180182

@@ -213,7 +215,7 @@ def test_parses_invalid(self, marker_string) -> None:
213215
),
214216
],
215217
)
216-
def test_str_repr_eq_hash(self, marker_string, expected) -> None:
218+
def test_str_repr_eq_hash(self, marker_string: str, expected: str) -> None:
217219
m = Marker(marker_string)
218220
assert str(m) == expected
219221
assert repr(m) == f"<Marker({str(m)!r})>"
@@ -248,7 +250,9 @@ def test_str_repr_eq_hash(self, marker_string, expected) -> None:
248250
),
249251
],
250252
)
251-
def test_different_markers_different_hashes(self, example1, example2) -> None:
253+
def test_different_markers_different_hashes(
254+
self, example1: str, example2: str
255+
) -> None:
252256
marker1, marker2 = Marker(example1), Marker(example2)
253257
# Markers created from strings that are not equivalent should differ.
254258
assert marker1 != marker2
@@ -316,8 +320,10 @@ def test_environment_with_extra_none(self) -> None:
316320
),
317321
],
318322
)
319-
def test_evaluates(self, marker_string, environment, expected) -> None:
320-
args = [] if environment is None else [environment]
323+
def test_evaluates(
324+
self, marker_string: str, environment: dict[str, str] | None, expected: bool
325+
) -> None:
326+
args = () if environment is None else (environment,)
321327
assert Marker(marker_string).evaluate(*args) == expected
322328

323329
@pytest.mark.parametrize(
@@ -331,7 +337,7 @@ def test_evaluates(self, marker_string, environment, expected) -> None:
331337
for i in itertools.product(PEP_345_VARIABLES, OPERATORS, VALUES)
332338
],
333339
)
334-
def test_parses_pep345_valid(self, marker_string) -> None:
340+
def test_parses_pep345_valid(self, marker_string: str) -> None:
335341
Marker(marker_string)
336342

337343
@pytest.mark.parametrize(
@@ -354,9 +360,9 @@ def test_parses_pep345_valid(self, marker_string) -> None:
354360
],
355361
)
356362
def test_evaluate_pep345_markers(
357-
self, marker_string, environment, expected
363+
self, marker_string: str, environment: dict[str, str] | None, expected: bool
358364
) -> None:
359-
args = [] if environment is None else [environment]
365+
args = () if environment is None else (environment,)
360366
assert Marker(marker_string).evaluate(*args) == expected
361367

362368
@pytest.mark.parametrize(
@@ -370,12 +376,12 @@ def test_evaluate_pep345_markers(
370376
for i in itertools.product(SETUPTOOLS_VARIABLES, OPERATORS, VALUES)
371377
],
372378
)
373-
def test_parses_setuptools_legacy_valid(self, marker_string) -> None:
379+
def test_parses_setuptools_legacy_valid(self, marker_string: str) -> None:
374380
Marker(marker_string)
375381

376382
def test_evaluate_setuptools_legacy_markers(self) -> None:
377383
marker_string = "python_implementation=='Jython'"
378-
args = [{"platform_python_implementation": "CPython"}]
384+
args = ({"platform_python_implementation": "CPython"},)
379385
assert Marker(marker_string).evaluate(*args) is False
380386

381387
def test_extra_str_normalization(self) -> None:
@@ -414,12 +420,14 @@ def test_python_full_version_untagged(self) -> None:
414420
pytest.param('"Foo" in {0}', True, id="case-sensitive"),
415421
],
416422
)
417-
def test_extras_and_dependency_groups(self, variable, expression, result) -> None:
423+
def test_extras_and_dependency_groups(
424+
self, variable: str, expression: str, result: bool
425+
) -> None:
418426
environment = {variable: {"foo", "bar"}}
419427
assert Marker(expression.format(variable)).evaluate(environment) == result
420428

421429
@pytest.mark.parametrize("variable", ["extras", "dependency_groups"])
422-
def test_extras_and_dependency_groups_disallowed(self, variable) -> None:
430+
def test_extras_and_dependency_groups_disallowed(self, variable: str) -> None:
423431
marker = Marker(f'"foo" in {variable}')
424432
assert not marker.evaluate(context="lock_file")
425433

0 commit comments

Comments
 (0)