Skip to content

Commit 2e433d6

Browse files
committed
pylock: type-fu
1 parent 892cc79 commit 2e433d6

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

src/pip/_internal/models/pylock.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,22 @@
3535
from pip._vendor.typing_extensions import Self
3636

3737
T = TypeVar("T")
38-
T2 = TypeVar("T2")
3938

4039

4140
class FromDictProtocol(Protocol):
4241
@classmethod
43-
def from_dict(cls, d: Dict[str, Any]) -> "Self":
44-
pass
42+
def from_dict(cls, d: Dict[str, Any]) -> "Self": ...
4543

4644

4745
FromDictProtocolT = TypeVar("FromDictProtocolT", bound=FromDictProtocol)
4846

47+
48+
class SingleArgConstructor(Protocol):
49+
def __init__(self, value: Any) -> None: ...
50+
51+
52+
SingleArgConstructorT = TypeVar("SingleArgConstructorT", bound=SingleArgConstructor)
53+
4954
PYLOCK_FILE_NAME_RE = re.compile(r"^pylock\.([^.]+)\.toml$")
5055

5156

@@ -94,8 +99,11 @@ def _get_required(d: Dict[str, Any], expected_type: Type[T], key: str) -> T:
9499

95100

96101
def _get_as(
97-
d: Dict[str, Any], expected_type: Type[T], target_type: Type[T2], key: str
98-
) -> Optional[T2]:
102+
d: Dict[str, Any],
103+
expected_type: Type[T],
104+
target_type: Type[SingleArgConstructorT],
105+
key: str,
106+
) -> Optional[SingleArgConstructorT]:
99107
"""Get value from dictionary, verify expected type, convert to target type.
100108
101109
This assumes the target_type constructor accepts the value.
@@ -104,14 +112,17 @@ def _get_as(
104112
if value is None:
105113
return None
106114
try:
107-
return target_type(value) # type: ignore[call-arg]
115+
return target_type(value)
108116
except Exception as e:
109117
raise PylockValidationError(f"Error parsing value of {key!r}: {e}") from e
110118

111119

112120
def _get_required_as(
113-
d: Dict[str, Any], expected_type: Type[T], target_type: Type[T2], key: str
114-
) -> T2:
121+
d: Dict[str, Any],
122+
expected_type: Type[T],
123+
target_type: Type[SingleArgConstructorT],
124+
key: str,
125+
) -> SingleArgConstructorT:
115126
"""Get required value from dictionary, verify expected type,
116127
convert to target type."""
117128
value = _get_as(d, expected_type, target_type, key)
@@ -121,8 +132,11 @@ def _get_required_as(
121132

122133

123134
def _get_list_as(
124-
d: Dict[str, Any], expected_type: Type[T], target_type: Type[T2], key: str
125-
) -> Optional[List[T2]]:
135+
d: Dict[str, Any],
136+
expected_type: Type[T],
137+
target_type: Type[SingleArgConstructorT],
138+
key: str,
139+
) -> Optional[List[SingleArgConstructorT]]:
126140
"""Get list value from dictionary and verify expected items type."""
127141
value = _get(d, list, key)
128142
if value is None:
@@ -135,7 +149,7 @@ def _get_list_as(
135149
f"(expected {expected_type})"
136150
)
137151
try:
138-
result.append(target_type(item)) # type: ignore[call-arg]
152+
result.append(target_type(item))
139153
except Exception as e:
140154
raise PylockValidationError(
141155
f"Error parsing item {i} of {key!r}: {e}"

0 commit comments

Comments
 (0)