{"id":"b7c76bf3176b5f34","repo":"pypa/pip","slug":"cannot-restore-specifierset-from-state-r","errorCode":null,"errorMessage":"Cannot restore SpecifierSet from {state!r}","messagePattern":"Cannot restore SpecifierSet from (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/specifiers.py","lineNumber":1502,"sourceCode":"        if isinstance(state, dict):\n            # Old format (packaging <= 25.x, no __slots__): state is a plain dict.\n            specs = state.get(\"_specs\", ())\n            prereleases = state.get(\"_prereleases\")\n            # Convert frozenset to tuple (26.0 stored as frozenset)\n            if isinstance(specs, frozenset):\n                specs = tuple(sorted(specs, key=str))\n            if (\n                isinstance(specs, tuple)\n                and all(isinstance(s, Specifier) for s in specs)\n                and _validate_pre(prereleases)\n            ):\n                self._specs = specs\n                self._prereleases = prereleases\n                self._canonicalized = len(self._specs) <= 1\n                self._has_arbitrary = any(\"===\" in str(s) for s in self._specs)\n                return\n\n        raise TypeError(f\"Cannot restore SpecifierSet from {state!r}\")\n\n    def __repr__(self) -> str:\n        \"\"\"A representation of the specifier set that shows all internal state.\n\n        Note that the ordering of the individual specifiers within the set may not\n        match the input string.\n\n        >>> SpecifierSet('>=1.0.0,!=2.0.0')\n        <SpecifierSet('!=2.0.0,>=1.0.0')>\n        >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=False)\n        <SpecifierSet('!=2.0.0,>=1.0.0', prereleases=False)>\n        >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=True)\n        <SpecifierSet('!=2.0.0,>=1.0.0', prereleases=True)>\n        \"\"\"\n        pre = (\n            f\", prereleases={self.prereleases!r}\"\n            if self._prereleases is not None\n            else \"\"","sourceCodeStart":1484,"sourceCodeEnd":1520,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/packaging/specifiers.py#L1484-L1520","documentation":"Raised as TypeError (specifiers.py:1502) inside SpecifierSet.__setstate__ when the pickled state is unrecognized: it accepts the new (specs_tuple, prereleases) format, the 26.0-26.1 slot-dict tuple, or the legacy plain dict, all requiring specs to be a tuple of Specifier and prereleases to pass _validate_pre. Any other shape hits this fall-through.","triggerScenarios":"Unpickling a SpecifierSet whose state was produced by an incompatible packaging, manually edited, or whose specs member is not a tuple of Specifier (e.g. a list, or contains non-Specifier objects). Also if prereleases is a non-bool/non-None value.","commonSituations":"Cross-release pickle caches (resolution caches, lock caches) shared between packaging versions. A pickle from a fork that changed SpecifierSet internals. frozenset specs are tolerated but lists or other iterables are not.","solutions":["Rebuild the SpecifierSet from its string form: SpecifierSet(str(pickle.load(...))) is unsafe if load itself fails; instead store/restore the string representation.","Pin producer and consumer to compatible packaging versions.","Prefer serializing SpecifierSet as str(specifier_set) rather than as a pickle."],"exampleFix":"# before: pickle shared across incompatible packaging versions\nss = pickle.load(open(\"ss.pkl\", \"rb\"))  # TypeError\n\n# after: persist the round-trippable string instead\n# write: open(\"ss.txt\",\"w\").write(str(ss))\nfrom pip._vendor.packaging.specifiers import SpecifierSet\nss = SpecifierSet(open(\"ss.txt\").read().strip())","handlingStrategy":"try-catch","validationCode":"def is_recognized_specifierset_state(state):\n    if isinstance(state, tuple) and len(state) == 2:\n        specs, pre = state\n        from pip._vendor.packaging.specifiers import Specifier\n        return (isinstance(specs, tuple) and all(isinstance(s, Specifier) for s in specs))\n    if isinstance(state, dict):\n        return True\n    return False","typeGuard":"null","tryCatchPattern":"import pickle\nfrom pip._vendor.packaging.specifiers import SpecifierSet\ntry:\n    ss = pickle.load(open(path, 'rb'))\nexcept TypeError as e:\n    if 'Cannot restore SpecifierSet' in str(e):\n        ss = SpecifierSet(open('specs.txt').read().strip())","preventionTips":["Serialize SpecifierSet as str(ss) for storage, not as a pickle.","Avoid sharing specifier pickles across packaging major versions."],"tags":["packaging","specifiers","pickle","serialization"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}