{"id":"19e72ef59a9611a6","repo":"pypa/pip","slug":"cannot-restore-self-class-name-value-fro","errorCode":null,"errorMessage":"Cannot restore {self.__class__.__name__} value from {value!r}","messagePattern":"Cannot restore (.+?) value from (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/_parser.py","lineNumber":36,"sourceCode":"    def __init__(self, value: str) -> None:\n        self.value = value\n\n    def __str__(self) -> str:\n        return self.value\n\n    def __repr__(self) -> str:\n        return f\"<{self.__class__.__name__}({self.value!r})>\"\n\n    def serialize(self) -> str:\n        raise NotImplementedError\n\n    def __getstate__(self) -> str:\n        # Return just the value string for compactness and stability.\n        return self.value\n\n    def _restore_value(self, value: object) -> None:\n        if not isinstance(value, str):\n            raise TypeError(\n                f\"Cannot restore {self.__class__.__name__} value from {value!r}\"\n            )\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\"])","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/packaging/_parser.py#L18-L54","documentation":"Raised by `packaging._parser.Node._restore_value` during unpickling/deepcopy when the persisted value is not a `str`. AST nodes (`Variable`, `Value`, `Op`, etc.) carry a single string `value`; any non-string passed to restore is rejected as a type error. This guard enforces the new compact pickle format introduced in packaging 26.2.","triggerScenarios":"Calling `__setstate__` directly with a non-string, unpickling a marker node from a pickle produced by tampering or by a different class hierarchy, or deepcopy when `__reduce__` was monkeypatched to return a non-string.","commonSituations":"Loading a pickle (e.g. cached parsed marker/specifier) from an older packaging version with a monkeypatch; serialization frameworks (dill, cloudpickle) that reconstruct state from non-str; test fixtures that hand-craft `__setstate__` payloads.","solutions":["Ensure the object being unpickled was created by the same packaging version — re-parse from the source string instead","If you must rebuild state, pass a str: `node.__setstate__('>=1.0')`","Avoid pickling marker/specifier AST nodes; serialize the source specifier string and re-parse on load"],"exampleFix":"// before\nnode.__setstate__(123)\n// after\nnode.__setstate__('>=1.0')","handlingStrategy":"type-guard","validationCode":"def restore_node_value(node, value):\n    if not isinstance(value, str):\n        raise TypeError(f'value must be str, got {type(value).__name__}')\n    node._restore_value(value)","typeGuard":"def is_str_state(value: object) -> bool:\n    return isinstance(value, str)","tryCatchPattern":"try:\n    node.__setstate__(payload)\nexcept TypeError as e:\n    if 'Cannot restore' in str(e):\n        raise ValueError(f'invalid pickle payload for node: {payload!r}') from e\n    raise","preventionTips":["Do not pickle packaging AST nodes; store the source string and re-parse","Pin packaging versions across environments that exchange pickles","Avoid monkeypatching __reduce__/__getstate__ on Node subclasses"],"tags":["packaging","parser","pickle","serialization"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}