pypa/pip · error · TypeError
Cannot restore Requirement from
Error message
Cannot restore Requirement from {state!r} What it means
TypeError raised by Requirement.__setstate__ during unpickling when the saved state does not match any recognized pickle format. packaging recognizes three shapes (26.2 string, 26.3 (string, prereleases) tuple, legacy __dict__); anything else means the pickle was not produced by a packaging Requirement, so restoration is refused to avoid silently constructing a wrong object.
Solutions
- Verify the object in the pickle is actually a packaging Requirement; if not, reconstruct it from its string form instead.
- If migrating from an old private format, read it with the code that wrote it and re-serialize as a Requirement string (str(req)), then re-parse: Requirement(req_string).
- Do not fabricate __getstate__ tuples manually; if you must, use the 26.3 shape (requirement_string, prereleases_bool_or_None).
- Regenerate the pickle from a current packaging version to get a forward-compatible format.
Example fix
# before: pickle produced by an incompatible serializer
req = pickle.loads(blob) # TypeError: Cannot restore Requirement from (1, 0, 'foo')
# after: store/restore the canonical string form
import pickle
from packaging.requirements import Requirement
blob = pickle.dumps(str(Requirement('foo>=1.0')))
req = Requirement(pickle.loads(blob)) Defensive patterns
Strategy: try-catch
Validate before calling
from packaging.requirements import Requirement
def looks_like_requirement_state(state) -> bool:
if isinstance(state, str):
return True
if (isinstance(state, tuple) and len(state) == 2
and isinstance(state[0], str)
and (state[1] is None or isinstance(state[1], bool))):
return True
if isinstance(state, dict) and state.keys() >= set(Requirement.__slots__):
return True
return False
assert looks_like_requirement_state(loaded_state), repr(loaded_state) Type guard
null
Try / catch
import pickle
from packaging.requirements import Requirement
try:
req = pickle.loads(blob)
except TypeError as e:
if 'Cannot restore Requirement' in str(e):
# not a real Requirement pickle; reconstruct from its string form instead
raise Prevention
- Only unpickle Requirement objects that were pickled by packaging itself.
- For long-term storage, persist str(req) and re-parse with Requirement(...) on load.
- Do not hand-craft Requirement.__getstate__ tuples; if unavoidable, use the (string, prereleases) shape.
When it happens
Trigger: Unpickling (pickle.loads) a bytes stream that claims to be a Requirement but whose __getstate__ payload is, e.g., a 3-tuple, an int, a list, or a dict missing some __slots__ keys. Also if a custom serializer wrote a non-conforming state and you feed it to Requirement.__setstate__.
Common situations: Loading a pickle written by a different/older library version that used a private format; a corrupted or hand-crafted pickle; a migration that round-trips Requirement through an intermediate format that lost the prereleases field.
Related errors
- Cannot restore Specifier from
- Cannot restore SpecifierSet from
- Cannot restore Tag from
- Cannot restore Version from
- Cannot restore Marker from
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/2887aff69d536d26.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/packaging/requirements.py:144
if isinstance(state, str):
# Format (26.2): just the requirement string.
requirement_string: str = state
prereleases: bool | None = None
elif (
isinstance(state, tuple)
and len(state) == 2
and isinstance(state[0], str)
and (state[1] is None or isinstance(state[1], bool))
):
# New format (26.3+): (requirement string, specifier prereleases).
requirement_string, prereleases = state
elif isinstance(state, dict) and state.keys() >= set(self.__slots__):
# Old format (packaging <= 26.1, no __slots__): plain __dict__.
for key in self.__slots__:
setattr(self, key, state[key])
return
else:
raise TypeError(f"Cannot restore Requirement from {state!r}")
try:
tmp = Requirement(requirement_string)
except InvalidRequirement as exc:
raise TypeError(f"Cannot restore Requirement from {state!r}") from exc
self.name = tmp.name
self.url = tmp.url
self.extras = tmp.extras
self.specifier = tmp.specifier
self.specifier._prereleases = prereleases
self.marker = tmp.marker
def __str__(self) -> str:
return "".join(self._iter_parts(self.name))
def __repr__(self) -> str:
return f"<{self.__class__.__name__}({str(self)!r})>"
View on GitHub (pinned to f399c37189)