Skip to content

Commit 1e1da04

Browse files
committed
Make empty specifier set consistent on pre-releases of non PEP-440 versions
1 parent 93a7824 commit 1e1da04

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

src/packaging/specifiers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,8 +1030,8 @@ def filter(
10301030
return (
10311031
item
10321032
for item in iterable
1033-
if (version := _coerce_version(item)) is not None
1034-
and not version.is_prerelease
1033+
if (version := _coerce_version(item)) is None
1034+
or not version.is_prerelease
10351035
)
10361036

10371037
# Finally if prereleases is None, apply PEP 440 logic:

tests/test_specifiers.py

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,20 @@ def test_specifiers_prereleases(
768768
["invalid", "foobar"],
769769
),
770770
("!=2.0.*", None, None, ["1.0", "invalid", "2.0.0"], ["1.0", "invalid"]),
771+
# Test that !== ignores prereleases parameter for non-PEP 440 versions
772+
("!=1.0", None, True, ["invalid", "foobar"], ["invalid", "foobar"]),
773+
("!=1.0", None, False, ["invalid", "foobar"], ["invalid", "foobar"]),
774+
("!=1.0", True, None, ["invalid", "foobar"], ["invalid", "foobar"]),
775+
("!=1.0", False, None, ["invalid", "foobar"], ["invalid", "foobar"]),
776+
("!=1.0", True, True, ["invalid", "foobar"], ["invalid", "foobar"]),
777+
("!=1.0", False, False, ["invalid", "foobar"], ["invalid", "foobar"]),
778+
# Test that === ignores prereleases parameter for non-PEP 440 versions
779+
("===foobar", None, True, ["foobar", "foo"], ["foobar"]),
780+
("===foobar", None, False, ["foobar", "foo"], ["foobar"]),
781+
("===foobar", True, None, ["foobar", "foo"], ["foobar"]),
782+
("===foobar", False, None, ["foobar", "foo"], ["foobar"]),
783+
("===foobar", True, True, ["foobar", "foo"], ["foobar"]),
784+
("===foobar", False, False, ["foobar", "foo"], ["foobar"]),
771785
],
772786
)
773787
def test_specifier_filter(
@@ -1006,6 +1020,16 @@ def test_empty_specifier(self, version: str) -> None:
10061020
assert parse(version) in spec
10071021
assert spec.contains(parse(version))
10081022

1023+
@pytest.mark.parametrize(
1024+
"prereleases",
1025+
[None, False, True],
1026+
)
1027+
def test_empty_specifier_arbitrary_string(self, prereleases):
1028+
"""Test empty SpecifierSet accepts arbitrary strings."""
1029+
1030+
spec = SpecifierSet("", prereleases=prereleases)
1031+
assert spec.contains("foobar")
1032+
10091033
def test_create_from_specifiers(self) -> None:
10101034
spec_strs = [">=1.0", "!=1.1", "!=1.2", "<2.0"]
10111035
specs = [Specifier(s) for s in spec_strs]
@@ -1227,13 +1251,13 @@ def test_specifier_contains_installed_prereleases(
12271251
(">=1.0,<=2.0", False, True, ["1.0", "1.5a1"], ["1.0", "1.5a1"]),
12281252
(">=1.0,<=2.0dev", True, False, ["1.0", "1.5a1"], ["1.0"]),
12291253
(">=1.0,<=2.0dev", False, True, ["1.0", "1.5a1"], ["1.0", "1.5a1"]),
1230-
# Test that invalid versions are discarded
1254+
# Test that invalid versions are accepted by empty SpecifierSet
12311255
("", None, None, ["invalid version"], ["invalid version"]),
1232-
("", None, False, ["invalid version"], []),
1233-
("", False, None, ["invalid version"], []),
1256+
("", None, False, ["invalid version"], ["invalid version"]),
1257+
("", False, None, ["invalid version"], ["invalid version"]),
12341258
("", None, None, ["1.0", "invalid version"], ["1.0", "invalid version"]),
1235-
("", None, False, ["1.0", "invalid version"], ["1.0"]),
1236-
("", False, None, ["1.0", "invalid version"], ["1.0"]),
1259+
("", None, False, ["1.0", "invalid version"], ["1.0", "invalid version"]),
1260+
("", False, None, ["1.0", "invalid version"], ["1.0", "invalid version"]),
12371261
# Test arbitrary equality (===)
12381262
("===foobar", None, None, ["foobar", "foo", "bar"], ["foobar"]),
12391263
("===foobar", None, None, ["foo", "bar"], []),
@@ -1283,6 +1307,20 @@ def test_specifier_contains_installed_prereleases(
12831307
["invalid", "1.0", "2.0", "3.0"],
12841308
["1.0", "3.0"],
12851309
),
1310+
# Test that != ignores prereleases parameter for non-PEP 440 versions
1311+
("!=1.0", None, True, ["invalid", "foobar"], ["invalid", "foobar"]),
1312+
("!=1.0", None, False, ["invalid", "foobar"], ["invalid", "foobar"]),
1313+
("!=1.0", True, None, ["invalid", "foobar"], ["invalid", "foobar"]),
1314+
("!=1.0", False, None, ["invalid", "foobar"], ["invalid", "foobar"]),
1315+
("!=1.0", True, True, ["invalid", "foobar"], ["invalid", "foobar"]),
1316+
("!=1.0", False, False, ["invalid", "foobar"], ["invalid", "foobar"]),
1317+
# Test that === ignores prereleases parameter for non-PEP 440 versions
1318+
("===foobar", None, True, ["foobar", "foo"], ["foobar"]),
1319+
("===foobar", None, False, ["foobar", "foo"], ["foobar"]),
1320+
("===foobar", True, None, ["foobar", "foo"], ["foobar"]),
1321+
("===foobar", False, None, ["foobar", "foo"], ["foobar"]),
1322+
("===foobar", True, True, ["foobar", "foo"], ["foobar"]),
1323+
("===foobar", False, False, ["foobar", "foo"], ["foobar"]),
12861324
],
12871325
)
12881326
def test_specifier_filter(

0 commit comments

Comments
 (0)