{"record":{"id":"77f530b492ebe1bc","repo":"pypa/pip","slug":"cannot-restore-self-class-name-from-sta","errorCode":null,"errorMessage":"Cannot restore {self.__class__.__name__} from {state!r}","messagePattern":"Cannot restore (.+?) from (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/_parser.py","lineNumber":57,"sourceCode":"            )\n        self.value = value\n\n    def __setstate__(self, state: object) -> None:\n        if isinstance(state, str):\n            # New format (26.2+): just the value string.\n            self._restore_value(state)\n            return\n        if isinstance(state, tuple) and len(state) == 2:\n            # Old format (packaging <= 26.0, __slots__): (None, {slot: value}).\n            _, slot_dict = state\n            if isinstance(slot_dict, dict) and \"value\" in slot_dict:\n                self._restore_value(slot_dict[\"value\"])\n                return\n        if isinstance(state, dict) and \"value\" in state:\n            # Old format (packaging <= 25.0, no __slots__): plain __dict__.\n            self._restore_value(state[\"value\"])\n            return\n        raise TypeError(f\"Cannot restore {self.__class__.__name__} from {state!r}\")\n\n\nclass Variable(Node):\n    __slots__ = ()\n\n    def serialize(self) -> str:\n        return str(self)\n\n\nclass Value(Node):\n    __slots__ = ()\n\n    def serialize(self) -> str:\n        value = str(self)\n        if '\"' not in value:\n            return f'\"{value}\"'\n        if \"'\" not in value:\n            return f\"'{value}'\"","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/_parser.py#L39-L75","documentation":"Node.__setstate__ tries three known pickle formats when restoring during unpickling: the new compact string format (26.2+), the old __slots__ tuple format (<=26.0), and the old __dict__ format (<=25.0). If the state matches none of them, TypeError is raised with the unrecognizable state shown. This is a broader guard than error 265: it catches completely unrecognized state structures rather than just non-string values.","triggerScenarios":"Unpickling a Variable, Value, or Op node from a pickle created by a future or incompatible version of packaging that uses a serialization format this version does not understand.","commonSituations":"Downgrading packaging after pickling nodes with a newer format. Loading cached data from a different packaging fork. Pickle protocol mismatches after environment changes.","solutions":["Serialize nodes to strings using serialize() and re-parse on load with parse_marker()/parse_requirement()","Version your cache format and invalidate caches on packaging upgrades","Catch TypeError and re-parse from the original source string as a fallback"],"exampleFix":"# before\nimport pickle\nmarker_node = pickle.loads(pickled_data)  # incompatible format\n\n# after\n# Persist the serialized string form, not the Node object:\n# stored = marker_node.serialize()  -> \"python_version >= '3.8'\"\n# On load, re-parse:\nfrom packaging._parser import parse_marker\nmarker_node = parse_marker(stored_string)","handlingStrategy":"try-catch","validationCode":"def safe_restore_node(pickled_data, original_source=None):\n    import pickle\n    try:\n        return pickle.loads(pickled_data)\n    except TypeError:\n        if original_source:\n            from packaging._parser import parse_marker\n            return parse_marker(original_source)\n        raise","typeGuard":"def is_recognized_node_state(state) -> bool:\n    if isinstance(state, str):\n        return True\n    if isinstance(state, tuple) and len(state) == 2:\n        _, d = state\n        return isinstance(d, dict) and \"value\" in d\n    if isinstance(state, dict) and \"value\" in state:\n        return True\n    return False","tryCatchPattern":"try:\n    node = pickle.loads(data)\nexcept TypeError as e:\n    if \"Cannot restore\" in str(e):\n        from packaging._parser import parse_marker\n        node = parse_marker(original_req_string)","preventionTips":["Use string serialization (serialize()) for persistence, not pickling","Version your cache format and invalidate on upgrades","Store the original requirement string alongside cached objects"],"tags":["packaging","pickle","deserialization","version-compat","vendored"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}