From 1dc49ff052d7220323a226972380fbe78b48c161 Mon Sep 17 00:00:00 2001 From: Apoorva Verma Date: Wed, 1 Jul 2026 05:27:26 +0530 Subject: [PATCH] fix: accept single-point Maven range like [5.0,5.0] Maven treats identical boundaries as an error only when a side is exclusive; both inclusive means exactly 5.0. Reject only the exclusive forms, matching Apache Maven's own parser. Signed-off-by: Apoorva Verma --- src/univers/maven.py | 13 +++++++++---- tests/test_maven_version.py | 11 +++++++++++ tests/test_maven_version_range.py | 7 +++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/univers/maven.py b/src/univers/maven.py index 368437a4..f0cbc640 100644 --- a/src/univers/maven.py +++ b/src/univers/maven.py @@ -77,14 +77,19 @@ def __init__(self, spec=None): _spec = spec[1:-1].strip() if "," in _spec: lower_bound, upper_bound = _spec.split(",") - if lower_bound and lower_bound == upper_bound: - raise RestrictionParseError("Range cannot have identical boundaries: %s" % spec) self.lower_bound = Version(lower_bound) if lower_bound else None self.upper_bound = Version(upper_bound) if upper_bound else None - if self.lower_bound and self.upper_bound and self.upper_bound < self.lower_bound: - raise RestrictionParseError("Range defies version ordering: %s" % spec) + if self.lower_bound and self.upper_bound: + if self.upper_bound < self.lower_bound: + raise RestrictionParseError("Range defies version ordering: %s" % spec) + # Identical boundaries describe a single hard requirement such as + # [5.0,5.0] and are only valid when both bounds are inclusive. + if self.upper_bound == self.lower_bound and not ( + self.lower_bound_inclusive and self.upper_bound_inclusive + ): + raise RestrictionParseError("Range cannot have identical boundaries: %s" % spec) else: # single version restriction if not self.lower_bound_inclusive or not self.upper_bound_inclusive: diff --git a/tests/test_maven_version.py b/tests/test_maven_version.py index d852fd6e..4de61426 100644 --- a/tests/test_maven_version.py +++ b/tests/test_maven_version.py @@ -98,6 +98,17 @@ def test_inclusive_range(self): assert "1.3.1" not in r assert "2.0" not in r + def test_identical_inclusive_boundaries(self): + r = Restriction("[5.0,5.0]") + assert str(r.lower_bound) == "5.0" + assert r.lower_bound_inclusive + assert str(r.upper_bound) == "5.0" + assert r.upper_bound_inclusive + + assert "4.0" not in r + assert "5.0" in r + assert "5.1" not in r + def test_exclusive_upper_bound(self): r = Restriction("[1.0,2.0)") assert str(r.lower_bound) == "1.0" diff --git a/tests/test_maven_version_range.py b/tests/test_maven_version_range.py index 0905d75a..dacef22e 100644 --- a/tests/test_maven_version_range.py +++ b/tests/test_maven_version_range.py @@ -36,6 +36,13 @@ def test_maven_version_range_from_native_for_pinned_version(): ) +def test_maven_version_range_from_native_for_single_point_range(): + version_range = MavenVersionRange.from_native("[5.0,5.0]") + assert version_range == MavenVersionRange( + constraints=(VersionConstraint(comparator="=", version=MavenVersion(string="5.0")),) + ) + + def test_maven_version_range_from_native_for_illformed_version(): try: MavenVersionRange.from_native("(1.0.0]")