10aday › Version Constraint Checker › pip ~= and version specifiers

pip ~= “compatible release” and PEP 440 version specifiers: exact ranges for requirements.txt

Short answer: ~=1.4.2 means ≥1.4.2 and ==1.4.* (so <1.5.0); ~=1.4 means ≥1.4 and ==1.* (so <2.0). The last number you wrote may increase. ~=1 is invalid: compatible release needs at least two numbers. ==1.4 is exact (it matches 1.4.0 too, because PEP 440 pads with zeros), ==1.4.* is the wildcard, and a version without an operator (requests 2.31) is not a valid specifier. Multiple clauses are joined with a comma, and there is no “or”.

Have a constraint and a list of versions? Paste them into the Version Constraint Checker: it shows, side by side, what npm, Cargo, Composer, pip and RubyGems accept.

PEP 440 specifiers, next to RubyGems

Each cell shows how that tool spells it, then the range it allows. Highlighted: where the meanings differ.

ConstraintpipRubyGems
~=1.4.2~=1.4.2
≥1.4.2 <1.5.0
~> 1.4.2
≥1.4.2 <1.5.0
try it
~=1.4~=1.4
≥1.4.0 <2.0.0
~> 1.4
≥1.4.0 <2.0.0
try it
~=1
pip needs two numbers
~=1
not valid
~> 1
≥1.0.0 <2.0.0
try it
~=0.2
no special 0.x rule
~=0.2
≥0.2.0 <1.0.0
~> 0.2
≥0.2.0 <1.0.0
try it
==1.4.*
RubyGems: use ~> 1.4.0
≥1.4.0 <1.5.0not validtry it
==1.*≥1.0.0 <2.0.0not validtry it
==1.4==1.4
exactly 1.4.0
= 1.4
exactly 1.4.0
try it
1.4 (bare)
pip requires an operator
not validexactly 1.4.0try it
!=1.4.1not 1.4.1not 1.4.1try it
>1.4>1.4.0>1.4.0try it
<=2.3≤2.3.0≤2.3.0try it
>=1.4, <2≥1.4.0 <2.0.0≥1.4.0 <2.0.0try it
>=1.0, <2.0, !=1.4.1≥1.0.0 <2.0.0, not 1.4.1≥1.0.0 <2.0.0, not 1.4.1try it

Ranges shown for final releases. pip skips pre-releases (1.5.0rc1) unless the specifier names one or you pass --pre; post-releases (1.4.2.post1) and local versions have their own rules. The checker handles pre-releases.

Same string, other package managers

ConstraintpipnpmComposer
~=1.4
npm reads ~= as its own ~
≥1.4.0 <2.0.0≥1.4.0 <1.5.0not validtry it
>=1.4, <2
npm: use a space
≥1.4.0 <2.0.0not valid≥1.4.0 <2.0.0try it

Rules of thumb for requirements.txt and pyproject.toml

Common questions

What does ~= mean in requirements.txt?

It is the PEP 440 “compatible release” operator. ~=1.4.2 = ≥1.4.2, ==1.4.* (<1.5.0). ~=1.4 = ≥1.4, ==1.* (<2.0). It equals Ruby's ~> and Composer's ~, but not npm's ~ when you write two numbers.

What is the difference between ==1.4 and ==1.4.*?

==1.4 matches only 1.4 (and 1.4.0, which is the same version under PEP 440). ==1.4.* matches every 1.4.x release: ≥1.4.0 <1.5.0.

Why is ~=1 invalid?

PEP 440 requires at least two release numbers with ~=, because it drops the last one to build the prefix. Use ~=1.0 (≥1.0, <2.0) or ==1.* instead.

How do I say "1.x but not 1.4.1" in pip?

Join clauses with a comma: >=1.0, <2.0, !=1.4.1. Every clause must hold. pip has no “or” operator; || is rejected.

Related

Sources