Skip to content

Commit 5c3d8c5

Browse files
committed
Change != to not allow invalid versions
1 parent 1e1da04 commit 5c3d8c5

File tree

2 files changed

+26
-37
lines changed

2 files changed

+26
-37
lines changed

src/packaging/specifiers.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -638,9 +638,6 @@ def filter(
638638
version, self.version
639639
):
640640
yield version
641-
# != operator: non-version strings pass through (they're "not equal")
642-
elif self.operator == "!=":
643-
yield version
644641
elif operator_callable(parsed_version, self.version):
645642
# If it's not a prerelease or prereleases are allowed, yield it directly
646643
if not parsed_version.is_prerelease or include_prereleases:

tests/test_specifiers.py

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -520,15 +520,14 @@ def test_specifiers(self, version: str, spec_str: str, expected: bool) -> None:
520520
("spec_str", "version", "expected"),
521521
[
522522
("==1.0", "not a valid version", False),
523+
("==1.*", "not a valid version", False),
523524
(">=1.0", "not a valid version", False),
524525
(">1.0", "not a valid version", False),
525526
("<=1.0", "not a valid version", False),
526527
("<1.0", "not a valid version", False),
527528
("~=1.0", "not a valid version", False),
528-
# Test invalid versions with != (should pass as "not equal")
529-
("!=1.0", "not a valid version", True),
530-
("!=1.0", "not a valid version", True),
531-
("!=2.0.*", "not a valid version", True),
529+
("!=1.0", "not a valid version", False),
530+
("!=1.*", "not a valid version", False),
532531
# Test with arbitrary equality (===)
533532
("===invalid", "invalid", True),
534533
("===foobar", "invalid", False),
@@ -757,24 +756,24 @@ def test_specifiers_prereleases(
757756
["foobar"],
758757
),
759758
("===1.0", None, None, ["1.0", "foobar", "invalid", "1.0.0"], ["1.0"]),
760-
# Test != with invalid versions (should pass through as "not equal")
761-
("!=1.0", None, None, ["invalid", "foobar"], ["invalid", "foobar"]),
762-
("!=1.0", None, None, ["1.0", "invalid", "2.0"], ["invalid", "2.0"]),
759+
# Test != with invalid versions (should not pass as versions are not valid)
760+
("!=1.0", None, None, ["invalid", "foobar"], []),
761+
("!=1.0", None, None, ["1.0", "invalid", "2.0"], ["2.0"]),
763762
(
764763
"!=2.0.*",
765764
None,
766765
None,
767766
["invalid", "foobar", "2.0"],
768-
["invalid", "foobar"],
767+
[]
769768
),
770-
("!=2.0.*", None, None, ["1.0", "invalid", "2.0.0"], ["1.0", "invalid"]),
769+
("!=2.0.*", None, None, ["1.0", "invalid", "2.0.0"], ["1.0"]),
771770
# 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"]),
771+
("!=1.0", None, True, ["invalid", "foobar"], []),
772+
("!=1.0", None, False, ["invalid", "foobar"], []),
773+
("!=1.0", True, None, ["invalid", "foobar"], []),
774+
("!=1.0", False, None, ["invalid", "foobar"], []),
775+
("!=1.0", True, True, ["invalid", "foobar"], []),
776+
("!=1.0", False, False, ["invalid", "foobar"], []),
778777
# Test that === ignores prereleases parameter for non-PEP 440 versions
779778
("===foobar", None, True, ["foobar", "foo"], ["foobar"]),
780779
("===foobar", None, False, ["foobar", "foo"], ["foobar"]),
@@ -1267,7 +1266,7 @@ def test_specifier_contains_installed_prereleases(
12671266
("===1.0", None, None, ["1.0", "1.0+downstream1"], ["1.0"]),
12681267
# Test === combined with other operators (arbitrary string)
12691268
(">=1.0,===foobar", None, None, ["foobar", "1.0", "2.0"], []),
1270-
("!= 2.0,===foobar", None, None, ["foobar", "2.0", "bar"], ["foobar"]),
1269+
("!=2.0,===foobar", None, None, ["foobar", "2.0", "bar"], []),
12711270
# Test === combined with other operators (version string)
12721271
(">=1.0,===1.5", None, None, ["1.0", "1.5", "2.0"], ["1.5"]),
12731272
(">=2.0,===1.5", None, None, ["1.0", "1.5", "2.0"], []),
@@ -1282,23 +1281,23 @@ def test_specifier_contains_installed_prereleases(
12821281
("===1.0", None, None, ["1.0", "foobar", "invalid", "1.0.0"], ["1.0"]),
12831282
(">=1.0,===1.5", None, None, ["1.5", "foobar", "invalid"], ["1.5"]),
12841283
# Test != with invalid versions (should pass through as "not equal")
1285-
("!=1.0", None, None, ["invalid", "foobar"], ["invalid", "foobar"]),
1286-
("!=1.0", None, None, ["1.0", "invalid", "2.0"], ["invalid", "2.0"]),
1284+
("!=1.0", None, None, ["invalid", "foobar"], []),
1285+
("!=1.0", None, None, ["1.0", "invalid", "2.0"], ["2.0"]),
12871286
(
12881287
"!=2.0.*",
12891288
None,
12901289
None,
12911290
["invalid", "foobar", "2.0"],
1292-
["invalid", "foobar"],
1291+
[],
12931292
),
1294-
("!=2.0.*", None, None, ["1.0", "invalid", "2.0.0"], ["1.0", "invalid"]),
1293+
("!=2.0.*", None, None, ["1.0", "invalid", "2.0.0"], ["1.0"]),
12951294
# Test != with invalid versions combined with other operators
12961295
(
12971296
"!=1.0,!=2.0",
12981297
None,
12991298
None,
13001299
["invalid", "1.0", "2.0", "3.0"],
1301-
["invalid", "3.0"],
1300+
["3.0"],
13021301
),
13031302
(
13041303
">=1.0,!=2.0",
@@ -1307,13 +1306,6 @@ def test_specifier_contains_installed_prereleases(
13071306
["invalid", "1.0", "2.0", "3.0"],
13081307
["1.0", "3.0"],
13091308
),
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"]),
13171309
# Test that === ignores prereleases parameter for non-PEP 440 versions
13181310
("===foobar", None, True, ["foobar", "foo"], ["foobar"]),
13191311
("===foobar", None, False, ["foobar", "foo"], ["foobar"]),
@@ -1730,19 +1722,19 @@ def test_contains_rejects_invalid_specifier(
17301722
("1.0", "===1.0+downstream1", False),
17311723
("1.0+downstream1", "===1.0", False),
17321724
# Test === combined with other operators (arbitrary string)
1733-
("foobar", "===foobar,!=1.0", True),
1725+
("foobar", "===foobar,!=1.0", False),
17341726
("1.0", "===foobar,!=1.0", False),
17351727
("foobar", ">=1.0,===foobar", False),
17361728
# Test === combined with other operators (version string)
17371729
("1.5", ">=1.0,===1.5", True),
17381730
("1.5", ">=2.0,===1.5", False), # Doesn't meet >=2.0
17391731
("2.5", ">=1.0,===2.5", True),
1740-
# Test != with invalid versions (should pass as "not equal")
1741-
("invalid", "!=1.0", True),
1742-
("foobar", "!=1.0", True),
1743-
("invalid", "!=2.0.*", True),
1732+
# Test != with invalid versions (should not pass as not valid versions)
1733+
("invalid", "!=1.0", False),
1734+
("foobar", "!=1.0", False),
1735+
("invalid", "!=2.0.*", False),
17441736
# Test != with invalid versions combined with other operators
1745-
("invalid", "!=1.0,!=2.0", True),
1737+
("invalid", "!=1.0,!=2.0", False),
17461738
("foobar", ">=1.0,!=2.0", False),
17471739
("1.5", ">=1.0,!=2.0", True),
17481740
],

0 commit comments

Comments
 (0)