{"record":{"id":"fde6d53ca2d96972","repo":"pypa/pip","slug":"cannot-combine-specifiersets-with-true-and-false-p","errorCode":null,"errorMessage":"Cannot combine SpecifierSets with True and False prerelease overrides.","messagePattern":"Cannot combine SpecifierSets with True and False prerelease overrides\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/specifiers.py","lineNumber":996,"sourceCode":"        <SpecifierSet('!=1.0.1,!=2.0.1,<=2.0.0,>=1.0.0')>\n        \"\"\"\n        if isinstance(other, str):\n            other = SpecifierSet(other)\n        elif not isinstance(other, SpecifierSet):\n            return NotImplemented\n\n        specifier = SpecifierSet()\n        specifier._specs = self._specs + other._specs\n        specifier._canonicalized = len(specifier._specs) <= 1\n        specifier._has_arbitrary = self._has_arbitrary or other._has_arbitrary\n\n        # Combine prerelease settings: use common or non-None value\n        if self._prereleases is None or self._prereleases == other._prereleases:\n            specifier._prereleases = other._prereleases\n        elif other._prereleases is None:\n            specifier._prereleases = self._prereleases\n        else:\n            raise ValueError(\n                \"Cannot combine SpecifierSets with True and False prerelease overrides.\"\n            )\n\n        return specifier\n\n    def __eq__(self, other: object) -> bool:\n        \"\"\"Whether or not the two SpecifierSet-like objects are equal.\n\n        :param other: The other object to check against.\n\n        The value of :attr:`prereleases` is ignored.\n\n        >>> SpecifierSet(\">=1.0.0,!=1.0.1\") == SpecifierSet(\">=1.0.0,!=1.0.1\")\n        True\n        >>> (SpecifierSet(\">=1.0.0,!=1.0.1\", prereleases=False) ==\n        ...  SpecifierSet(\">=1.0.0,!=1.0.1\", prereleases=True))\n        True\n        >>> SpecifierSet(\">=1.0.0,!=1.0.1\") == \">=1.0.0,!=1.0.1\"","sourceCodeStart":978,"sourceCodeEnd":1014,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/specifiers.py#L978-L1014","documentation":"Raised as ValueError by SpecifierSet.__and__ (specifiers.py:996) when intersecting two SpecifierSets whose explicit prerelease overrides conflict: one has prereleases=True and the other prereleases=False (both non-None and unequal). The combination logic at lines 991-994 accepts a None on either side or matching values, but explicitly forbids the True-vs-False clash because there is no defensible combined policy.","triggerScenarios":"SpecifierSet('>=1.0', prereleases=True) & SpecifierSet('<2.0', prereleases=False); building a combined requirement programmatically where one source forces prereleases on and another forces them off; intersecting a tool's resolver settings (prereleases enabled) with a project policy (prereleases disabled).","commonSituations":"A resolver/aggregator merging constraints from multiple sources (e.g. user flag --pre vs. project requires_python style guards); pinning tools that let callers set prerelease policy per-constraint then combine them; config layers where one layer sets prereleases=True globally and another layer overrides a subset to False.","solutions":["Reconcile the prerelease policy before combining: pass the same prereleases value (or None) to both SpecifierSets, or leave both unset to let autodetect decide.","If you must merge, strip the override by reconstructing one side as SpecifierSet(str(other)) (str drops prereleases) before the & operation.","Decide a single project-wide prerelease policy and apply it at the top level rather than per-SpecifierSet.","Wrap the & in try/except ValueError and surface a clear 'conflicting prerelease policy' error naming both sources."],"exampleFix":"# before\na = SpecifierSet('>=1.0', prereleases=True)\nb = SpecifierSet('<2.0', prereleases=False)\ncombined = a & b  # ValueError\n\n# after - drop the conflicting override, apply one policy\nb = SpecifierSet(str(b))  # prereleases=None\ncombined = a & b  # ok; combined honors prereleases=True","handlingStrategy":"validation","validationCode":"from packaging.specifiers import SpecifierSet\n\ndef combine(a: SpecifierSet, b: SpecifierSet) -> SpecifierSet:\n    # Drop conflicting prerelease overrides by normalizing to string form.\n    if a._prereleases is not None and b._prereleases is not None and a._prereleases != b._prereleases:\n        b = SpecifierSet(str(b))  # prereleases=None\n    return a & b","typeGuard":null,"tryCatchPattern":"try:\n    combined = a & b\nexcept ValueError:\n    # conflicting prerelease policy; pick one explicit policy\n    combined = SpecifierSet(str(a) + ',' + str(b), prereleases=True)","preventionTips":["Establish one prerelease policy per merge operation and apply it once.","When building SpecifierSets from layered config, leave prereleases unset unless explicitly needed.","Reconstruct one side from str() to drop its override before combining."],"tags":["packaging","specifiers","prereleases","configuration"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}