Skip to content

Commit

Permalink
Fix propagation of include_prerelease when calculating VersionRange i…
Browse files Browse the repository at this point in the history
…ntersection (#16986)

* Propagate include_prerelease when calculating intersection of VersionRange

* Added unittest for propagation of include_prerelease

* Fix shortcircuit condition

* Add tests for shortcircuit behaviour

* review, simplify optimization

---------

Co-authored-by: Abril Rincón Blanco <git@rinconblanco.es>
Co-authored-by: memsharded <james@conan.io>
  • Loading branch information
3 people authored Sep 24, 2024
1 parent 216d3ac commit 218b9b2
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
6 changes: 5 additions & 1 deletion conans/model/version_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ def _calculate_limits(operator, lhs, rhs):
if limits:
return sorted(limits, reverse=operator == ">")[0]

prerelease = True
for lhs_conditions in self.condition_sets:
for rhs_conditions in other.condition_sets:
internal_conditions = []
Expand All @@ -207,10 +208,13 @@ def _calculate_limits(operator, lhs, rhs):
internal_conditions.append(upper_limit)
if internal_conditions and (not lower_limit or not upper_limit or lower_limit <= upper_limit):
conditions.append(internal_conditions)
# conservative approach: if any of the conditions forbid prereleases, forbid them in the result
if not lhs_conditions.prerelease or not rhs_conditions.prerelease:
prerelease = False

if not conditions:
return None
expression = ' || '.join(' '.join(str(c) for c in cs) for cs in conditions)
expression = ' || '.join(' '.join(str(c) for c in cs) for cs in conditions) + (', include_prerelease' if prerelease else '')
result = VersionRange(expression)
# TODO: Direct definition of conditions not reparsing
# result.condition_sets = self.condition_sets + other.condition_sets
Expand Down
32 changes: 32 additions & 0 deletions test/unittests/model/version/test_version_range_intersection.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,35 @@ def test_range_intersection_incompatible(range1, range2):
assert inter is None
inter = r2.intersection(r1) # Test reverse order, result should be the same
assert inter is None


prerelease_values = [
[">=1.0-pre.1 <1.0-pre.99, include_prerelease",
">=1.0-pre.1 <1.0-pre.99, include_prerelease",
">=1.0-pre.1 <1.0-pre.99, include_prerelease"],
[">=1.0-pre.1 <1.0-pre.99, include_prerelease",
">=1.0-pre.12 <1.0-pre.98, include_prerelease",
">=1.0-pre.12 <1.0-pre.98, include_prerelease"],
[">=1.0-pre.12 <1.0-pre.99, include_prerelease",
">=1.0-pre.1 <1.0-pre.98, include_prerelease",
">=1.0-pre.12 <1.0-pre.98, include_prerelease"],
[">=1.0-pre.1 <1.0-pre.99",
">=1.0-pre.1 <1.0-pre.99, include_prerelease",
">=1.0-pre.1 <1.0-pre.99"],
[">=1.0-pre.1 <1.0-pre.99, include_prerelease",
">=1.0-pre.12 <1.0-pre.98",
">=1.0-pre.12 <1.0-pre.98"],
[">=1.0-pre.12 <1.0-pre.99",
">=1.0-pre.1 <1.0-pre.98",
">=1.0-pre.12 <1.0-pre.98"]
]


@pytest.mark.parametrize("range1, range2, result", prerelease_values)
def test_range_intersection_prerelease(range1, range2, result):
r1 = VersionRange(range1)
r2 = VersionRange(range2)
inter = r1.intersection(r2)
assert str(inter.version()) == f'[{result}]'
inter = r2.intersection(r1) # Test reverse order, result should be the same
assert str(inter.version()) == f'[{result}]'

0 comments on commit 218b9b2

Please sign in to comment.