{"id":"e12bb059e8493c28","repo":"pypa/pip","slug":"cannot-restore-specifier-from-state-r","errorCode":null,"errorMessage":"Cannot restore Specifier from {state!r}","messagePattern":"Cannot restore Specifier from (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/specifiers.py","lineNumber":802,"sourceCode":"            if len(state) == 2 and isinstance(state[1], dict):\n                # Format (packaging 26.0-26.1): (None, {slot: value}).\n                _, slot_dict = state\n                spec = slot_dict.get(\"_spec\")\n                prereleases = slot_dict.get(\"_prereleases\", \"invalid\")\n                if _validate_spec(spec) and _validate_pre(prereleases):\n                    self._spec = spec\n                    self._prereleases = prereleases\n                    return\n        if isinstance(state, dict):\n            # Old format (packaging <= 25.x, no __slots__): state is a plain dict.\n            spec = state.get(\"_spec\")\n            prereleases = state.get(\"_prereleases\", \"invalid\")\n            if _validate_spec(spec) and _validate_pre(prereleases):\n                self._spec = spec\n                self._prereleases = prereleases\n                return\n\n        raise TypeError(f\"Cannot restore Specifier from {state!r}\")\n\n    @property\n    def operator(self) -> str:\n        \"\"\"The operator of this specifier.\n\n        >>> Specifier(\"==1.2.3\").operator\n        '=='\n        \"\"\"\n        return self._spec[0]\n\n    @property\n    def version(self) -> str:\n        \"\"\"The version of this specifier.\n\n        >>> Specifier(\"==1.2.3\").version\n        '1.2.3'\n        \"\"\"\n        return self._spec[1]","sourceCodeStart":784,"sourceCodeEnd":820,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/packaging/specifiers.py#L784-L820","documentation":"Raised as TypeError (specifiers.py:802) inside Specifier.__setstate__ when the pickled state matches none of the recognized formats: new tuple ((operator, version), prereleases), the 26.0-26.1 slot-dict tuple, or the legacy plain dict. It is the fail-closed branch for corrupt or foreign Specifier pickles.","triggerScenarios":"pickle.load on a Specifier whose state has been altered, truncated, or produced by a non-standard __getstate__. Reached only after all three format-detection branches decline the state.","commonSituations":"Cross-version pickle sharing where the producer's packaging is neither the new 26.2+ format nor one of the recognized legacy ones (e.g. a custom subclass). Manual tampering with pickle bytes. A pickle from a different Specifier implementation.","solutions":["Discard the pickle and reconstruct the Specifier from its string form via Specifier(str(...)).","Align producer and consumer packaging versions so __getstate__/__setstate__ agree.","Avoid pickling Specifier across processes with different vendored packaging copies."],"exampleFix":"# before\nspec = pickle.load(open(\"s.pkl\", \"rb\"))  # TypeError\n\n# after\ntry:\n    spec = pickle.load(open(\"s.pkl\", \"rb\"))\nexcept TypeError:\n    from pip._vendor.packaging.specifiers import Specifier\n    spec = Specifier(open(\"spec.txt\").read().strip())","handlingStrategy":"try-catch","validationCode":"from typing import Any\ndef is_recognized_specifier_state(state):\n    # new: ((op, ver), prereleases) ; legacy slot: (None, dict) ; legacy: dict\n    if isinstance(state, tuple) and len(state) == 2:\n        return True\n    if isinstance(state, dict):\n        return True\n    return False","typeGuard":"null","tryCatchPattern":"import pickle\nfrom pip._vendor.packaging.specifiers import Specifier\ntry:\n    spec = pickle.load(open(path, 'rb'))\nexcept TypeError as e:\n    if 'Cannot restore Specifier' in str(e):\n        spec = Specifier(open('spec.txt').read().strip())","preventionTips":["Persist Specifier as its string form rather than as a pickle.","Keep producer and consumer packaging versions aligned for pickle exchange."],"tags":["packaging","specifiers","pickle","serialization"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}