pypa/pip · error · PylockValidationError
Unexpected type (expected )
Error message
Unexpected type {type(value).__name__} (expected {expected_type.__name__}) What it means
Raised by _get in pylock.py:108-116 while reading a TOML key for a pylock dataclass. It fires when a present value is not the expected type, and also when expected_type is int but the value is a bool (TOML keeps bool and int distinct, even though bool subclasses int in Python). Surfaces as PylockValidationError with context set to the offending key.
Solutions
- Use the correct TOML scalar: unquoted integers, quoted strings, true/false booleans, native datetime.
- Never pass a bool where an int is expected (e.g. size).
Example fix
# before [[packages.sdist]] size = "12345" # after [[packages.sdist]] size = 12345
Defensive patterns
Strategy: validation
Validate before calling
def toml_scalar_ok(key: str, value, expected_type: type) -> bool:
if isinstance(value, expected_type) and not (expected_type is int and isinstance(value, bool)):
return True
return False
Try / catch
from packaging.pylock import Pylock, PylockValidationError
try:
lock = Pylock.from_dict(toml_dict)
except PylockValidationError as e:
# e.context names the offending key
...
Prevention
- Keep TOML scalars type-correct: unquoted ints, quoted strings, true/false booleans.
- Never use a bool where an int (e.g. size) is expected.
When it happens
Trigger: In a pylock TOML: size = "12345" (str where int expected), size = true (bool where int expected), index = 5 (int where str expected), upload-time = "2024-01-01 00:00:00" (str where datetime expected).
Common situations: Hand-editing pylock.toml with quoted numbers; a TOML emitter that quotes everything as strings; using true/false where an integer size is required.
Related errors
- Unexpected type (expected )
- Unexpected type (expected Sequence)
- Hash values must be strings
- Invalid pylock file
- At least one hash must be provided
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/a9d0f828ef91be38.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/packaging/pylock.py:112
def _toml_dict_factory(data: list[tuple[str, Any]]) -> dict[str, Any]:
return {
_toml_key(key): _toml_value(key, value)
for key, value in data
if value is not None
}
def _get(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T | None:
"""Get a value from the dictionary and verify it's the expected type."""
if (value := d.get(key)) is None:
return None
if not isinstance(value, expected_type) or (
# Special case: bool is a subclass of int, but TOML distinguishes the two
expected_type is int and isinstance(value, bool)
):
raise PylockValidationError(
f"Unexpected type {type(value).__name__} "
f"(expected {expected_type.__name__})",
context=key,
)
return value
def _get_required(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T:
"""Get a required value from the dictionary and verify it's the expected type."""
if (value := _get(d, expected_type, key)) is None:
raise _PylockRequiredKeyError(key)
return value
def _get_sequence(
d: Mapping[str, Any], expected_item_type: type[_T], key: str
) -> Sequence[_T] | None:
"""Get a list value from the dictionary and verify it's the expected items type."""View on GitHub (pinned to f399c37189)