{"record":{"id":"2887aff69d536d26","repo":"pypa/pip","slug":"cannot-restore-requirement-from-state-r","errorCode":null,"errorMessage":"Cannot restore Requirement from {state!r}","messagePattern":"Cannot restore Requirement from (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/requirements.py","lineNumber":144,"sourceCode":"        if isinstance(state, str):\n            # Format (26.2): just the requirement string.\n            requirement_string: str = state\n            prereleases: bool | None = None\n        elif (\n            isinstance(state, tuple)\n            and len(state) == 2\n            and isinstance(state[0], str)\n            and (state[1] is None or isinstance(state[1], bool))\n        ):\n            # New format (26.3+): (requirement string, specifier prereleases).\n            requirement_string, prereleases = state\n        elif isinstance(state, dict) and state.keys() >= set(self.__slots__):\n            # Old format (packaging <= 26.1, no __slots__): plain __dict__.\n            for key in self.__slots__:\n                setattr(self, key, state[key])\n            return\n        else:\n            raise TypeError(f\"Cannot restore Requirement from {state!r}\")\n\n        try:\n            tmp = Requirement(requirement_string)\n        except InvalidRequirement as exc:\n            raise TypeError(f\"Cannot restore Requirement from {state!r}\") from exc\n        self.name = tmp.name\n        self.url = tmp.url\n        self.extras = tmp.extras\n        self.specifier = tmp.specifier\n        self.specifier._prereleases = prereleases\n        self.marker = tmp.marker\n\n    def __str__(self) -> str:\n        return \"\".join(self._iter_parts(self.name))\n\n    def __repr__(self) -> str:\n        return f\"<{self.__class__.__name__}({str(self)!r})>\"\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/requirements.py#L126-L162","documentation":"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.","triggerScenarios":"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__.","commonSituations":"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.","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."],"exampleFix":"# before: pickle produced by an incompatible serializer\nreq = pickle.loads(blob)  # TypeError: Cannot restore Requirement from (1, 0, 'foo')\n\n# after: store/restore the canonical string form\nimport pickle\nfrom packaging.requirements import Requirement\nblob = pickle.dumps(str(Requirement('foo>=1.0')))\nreq = Requirement(pickle.loads(blob))","handlingStrategy":"try-catch","validationCode":"from packaging.requirements import Requirement\n\ndef looks_like_requirement_state(state) -> bool:\n    if isinstance(state, str):\n        return True\n    if (isinstance(state, tuple) and len(state) == 2\n            and isinstance(state[0], str)\n            and (state[1] is None or isinstance(state[1], bool))):\n        return True\n    if isinstance(state, dict) and state.keys() >= set(Requirement.__slots__):\n        return True\n    return False\n\nassert looks_like_requirement_state(loaded_state), repr(loaded_state)","typeGuard":"null","tryCatchPattern":"import pickle\nfrom packaging.requirements import Requirement\ntry:\n    req = pickle.loads(blob)\nexcept TypeError as e:\n    if 'Cannot restore Requirement' in str(e):\n        # not a real Requirement pickle; reconstruct from its string form instead\n        raise","preventionTips":["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."],"tags":["packaging","requirement","pickle","serialization","compatibility"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}