pypa/pip · error · ValueError
set relations do not support === specifiers
Error message
set relations do not support === specifiers
What it means
Raised as ValueError by SpecifierSet._check_relation_operand (specifiers.py:1147) when either operand of a set relation (is_subset/is_superset/etc.) contains an arbitrary-equality (===) specifier. The _has_arbitrary flag (set during construction from any '===' token) makes set relations mathematically undefined, because === does literal string matching rather than version-range admission, so subset/superset reasoning does not apply.
Source
Thrown at src/pip/_vendor/packaging/specifiers.py:1147
"""Return the :class:`~packaging.ranges.VersionRange` this set accepts.
An empty set yields the full range; an unsatisfiable set yields the
empty range. ``===`` specifiers contribute literal-string admission.
>>> SpecifierSet(">=1.0,<2.0").to_range()
<VersionRange '[1.0, 2.0.dev0)'>
.. versionadded:: 26.3
"""
from .ranges import VersionRange # noqa: PLC0415
return VersionRange._from_specifier_set(self)
def _check_relation_operand(self, other: object) -> None:
if not isinstance(other, SpecifierSet):
raise TypeError("expected a SpecifierSet")
if self._has_arbitrary or other._has_arbitrary:
raise ValueError("set relations do not support === specifiers")
def is_subset(self, other: SpecifierSet) -> bool:
"""Return whether every version matching this set also matches other.
:raises ValueError:
If either set uses ``===`` specifiers, or the two sets were
given different ``prereleases`` arguments (unset on one side
counts as different).
:raises TypeError:
If other is not a :class:`SpecifierSet`.
>>> SpecifierSet(">=3.12,<3.13").is_subset(SpecifierSet(">=3.12"))
True
>>> SpecifierSet(">=3.12").is_subset(SpecifierSet(">=3.12,<3.13"))
False
.. versionadded:: 26.3
"""View on GitHub (pinned to f399c37189)
Solutions
- Filter out or convert === specifiers before computing set relations, or skip the relation for sets that use them.
- Detect _has_arbitrary (or '===' in str(ss)) and report that comparison is unsupported for arbitrary pins.
- Replace the === pin with an == pin if exact version admission (rather than literal string equality) is intended, then re-run the relation.
- Restructure to compare via contains() per-candidate instead of subset/superset when === is involved.
Example fix
# before
a = SpecifierSet('===1.2.3')
b = SpecifierSet('>=1.0')
a.is_subset(b) # ValueError: set relations do not support === specifiers
# after - guard and skip, or convert to ==
if '===' in str(a) or '===' in str(b):
raise NotImplementedError('subset not defined for === pins')
# or: a = SpecifierSet('==1.2.3') # if exact version admission is meant Defensive patterns
Strategy: validation
Validate before calling
from packaging.specifiers import SpecifierSet
def safe_subset(a: SpecifierSet, b: SpecifierSet):
if '===' in str(a) or '===' in str(b):
raise NotImplementedError('set relations unsupported with === specifiers')
return a.is_subset(b) Type guard
from packaging.specifiers import SpecifierSet
def has_no_arbitrary(ss: SpecifierSet) -> bool:
return not ss._has_arbitrary Try / catch
try:
a.is_subset(b)
except ValueError:
# fall back to per-candidate contains() checks
... Prevention
- Avoid === specifiers except for literal string pins; prefer ==.
- Check _has_arbitrary (or '===' in str) before calling set relations.
- Document that === pins are excluded from subset/superset analysis.
When it happens
Trigger: SpecifierSet('===1.0').is_subset(SpecifierSet('>=1.0')); either side built from a requirement that uses '===' (e.g. a local/version-locked pin '===1.0.0+local'); combining a frozen-pin requirement with a range-based policy check.
Common situations: A lock file or resolver that emits '===' pins being fed into a dependency-overlap analyzer using is_subset; tools that compare 'compatible ranges' across packages where one package uses arbitrary equality; PEP 440 edge-case testing.
Related errors
- Invalid specifier: {spec!r}
- expected a SpecifierSet
- Undefined {op!r} on {lhs!r} and {rhs!r}.
- Cannot restore Specifier from {state!r}
- Cannot restore SpecifierSet from {state!r}
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/5f8ee8ec94f084f8.
Report an issue: GitHub.