Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ Changelog
=========


Version v30.9.1
----------------

- Add inverse function to VersionRange.


Version v30.9.0
----------------

Expand Down
37 changes: 37 additions & 0 deletions src/univers/version_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ class InvalidVersionRange(Exception):
"""


INVERTED_COMPARATORS = {
Comment thread
TG1999 marked this conversation as resolved.
">=": "<",
"<=": ">",
"!=": "=",
"<": ">=",
">": "<=",
"=": "!=",
}


@attr.s(frozen=True, order=False, eq=True, hash=True)
class VersionRange:
"""
Expand Down Expand Up @@ -164,6 +174,33 @@ def from_versions(cls, sequence):
constraints.append(constraint)
return cls(constraints=constraints)

def invert(self):
"""
Return the inverse of this VersionRange. For example, if this range is
Comment thread
TG1999 marked this conversation as resolved.
Outdated
">=1.0.0", the inverse is "<1.0.0".
>>> VersionRange.from_string("vers:npm/>=1.0.0").invert()
Comment thread
TG1999 marked this conversation as resolved.
Outdated
NpmVersionRange(constraints=(VersionConstraint(comparator='<', version=SemverVersion(string='1.0.0')),))
"""
inverted_constraints = []

if len(self.constraints) == 1 and self.constraints[0].comparator == "*":
Comment thread
TG1999 marked this conversation as resolved.
Outdated
# The inverse of "*" is an empty range.
return None

for constraint in self.constraints:
if constraint.comparator in INVERTED_COMPARATORS:
Comment thread
TG1999 marked this conversation as resolved.
Outdated
inverted_comparator = INVERTED_COMPARATORS[constraint.comparator]
else:
raise NotImplementedError(
Comment thread
TG1999 marked this conversation as resolved.
Outdated
f"Cannot invert a range with a {constraint.comparator!r} comparator."
)
inverted_constraint = VersionConstraint(
Comment thread
TG1999 marked this conversation as resolved.
Outdated
comparator=inverted_comparator,
version=constraint.version,
)
inverted_constraints.append(inverted_constraint)
return self.__class__(constraints=inverted_constraints)

def __str__(self):
constraints = "|".join(str(c) for c in sorted(self.constraints))
return f"vers:{self.scheme}/{constraints}"
Expand Down
Loading