def union(self, other): # type: (Range) -> _Union[Range, Union] if isinstance(other, Union): return other.union(self) if not self.is_contiguous_to(other): return Union.of(self, other) if self.allows_lower(other): union_min = self.min union_include_min = self.include_min else: union_min = other.min union_include_min = other.include_min if self.allows_higher(other): union_max = self.max union_include_max = self.include_max else: union_max = other.max union_include_max = other.include_max return Range( union_min, union_max, include_min=union_include_min, include_max=union_include_max, )
def convert_dependency(self, dependency): # type: (Dependency) -> Constraint """Convert a user-defined dependency into a format Mixology understands.""" if isinstance(dependency.constraint, VersionRange): constraint = Range( dependency.constraint.min, dependency.constraint.max, dependency.constraint.include_min, dependency.constraint.include_max, dependency.pretty_constraint, ) else: # VersionUnion ranges = [ Range( _range.min, _range.max, _range.include_min, _range.include_max, str(_range), ) for _range in dependency.constraint.ranges ] constraint = Union.of(*ranges) return Constraint(dependency.name, constraint)
def convert_dependency(self, dependency): # type: (Dependency) -> Constraint if isinstance(dependency.constraint, VersionRange): constraint = Range( dependency.constraint.min, dependency.constraint.max, dependency.constraint.include_min, dependency.constraint.include_max, dependency.pretty_constraint, ) else: # VersionUnion ranges = [ Range( range.min, range.max, range.include_min, range.include_max, str(range), ) for range in dependency.constraint.ranges ] constraint = Union.of(*ranges) return Constraint(dependency.name, constraint)
def difference( self, other): # type: (_Union[Range, Union]) -> _Union[Range, Union] if other.is_empty(): return self if isinstance(other, Union): ranges = [] current = self for range_ in other.ranges: # Skip any ranges that are strictly lower than [current]. if range_.is_strictly_lower(current): continue # If we reach a range strictly higher than [current], no more ranges # will be relevant so we can bail early. if range_.is_strictly_higher(current): break difference = current.difference(range_) if difference.is_empty(): return EmptyRange() elif isinstance(difference, Union): # If [range] split [current] in half, we only need to continue # checking future ranges against the latter half. ranges.append(difference.ranges[0]) current = difference.ranges[-1] else: current = difference if not ranges: return current return Union.of(*(ranges + [current])) if not self.allows_any(other): return self if not self.allows_lower(other): before = None elif self.min == other.min: before = Range(self.min, self.min, True, True) else: before = Range(self.min, other.min, self.include_min, not other.include_min) if not self.allows_higher(other): after = None elif self.max == other.max: after = Range(self.max, self.max, True, True) else: after = Range(other.max, self.max, not other.include_max, self.include_max) if before is None and after is None: return EmptyRange() if before is None: return after if after is None: return before return Union.of(before, after)