rez.version#
Implements everything needed to manipulate versions and requirements.
There are three class types: VersionToken
, Version
and VersionRange
.
A Version
is a set of zero or more VersionToken
s, separate by .
s or -
s (eg 1.2-3
).
A VersionToken
is a string containing alphanumerics, and default implemenations
NumericToken
and AlphanumericVersionToken
are supplied. You can implement
your own if you want stricter tokens or different sorting behaviour.
A VersionRange
is a set of one or more contiguous version ranges. For example,
3+<5
contains any version >=3 but less than 5. Version ranges can be used to
define dependency requirements between objects. They can be OR’d together, AND’d
and inverted.
The empty version ''
, and empty version range ''
, are also handled. The empty
version is used to denote unversioned objects. The empty version range, also
known as the ‘any’ range, is used to refer to any version of an object.
Requirements and list of requirements are represented by Requirement
and
RequirementList
respectively.
- class rez.version.Version#
Bases:
_Comparable
A Version is a sequence of zero or more version tokens, separated by either a dot
.
or hyphen-
delimiters. Note that separators only affect Version objects cosmetically. In other words, the version1.0.0
is equivalent to1-0-0
.The empty version
''
is the smallest possible version, and can be used to represent an unversioned resource.- inf = Version('[INF]')#
- __init__(ver_str='', make_token=<class 'rez.version._version.AlphanumericVersionToken'>)#
- trim(len_)#
Return a copy of the version, possibly with less tokens.
- next()#
- property major#
Semantic versioning major version.
- Returns:
A VersionToken or a subclass of a VersionToken.
- Return type:
- property minor#
Semantic versioning minor version.
- Returns:
A VersionToken or a subclass of a VersionToken.
- Return type:
- property patch#
Semantic versioning patch version.
- Returns:
A VersionToken or a subclass of a VersionToken.
- Return type:
- class rez.version.VersionRange#
Bases:
_Comparable
A version range is a set of one or more contiguous ranges of versions. For example, “3.0 or greater, but less than 4” is a contiguous range that contains versions such as
3.0
,3.1.0
,3.99
etc. Version ranges behave something like sets. They can be intersected, added and subtracted, but can also be inverted. You can test to see if aVersion
is contained within aVersionRange
.A VersionRange
3
(for example) is the superset of any version3[.X.X...]
. The version3
itself is also within this range, and is smaller than3.0
. Any version with common leading tokens, but with a larger token count, is the larger version of the two.VersionRange objects have a flexible syntax that let you describe any combination of contiguous ranges, including inclusive and exclusive upper and lower bounds. This is best explained by example (those listed on the same line are equivalent):
3
: ‘superset’ syntax, contains3
,3.0
,3.1.4
etc;2+
,>=2
: inclusive lower bound syntax, contains2
,2.1
,5.0.0
etc;>2
: exclusive lower bound;<5
: exclusive upper bound;<=5
: inclusive upper bound;==2
: a range that contains only the exact single version2
.
1+<5
,>=1<5
: inclusive lower, exclusive upper. The most common form of a ‘bounded’ version range (ie, one with a lower and upper bound);
>1<5
: exclusive lower, exclusive upper;>1<=5
: exclusive lower, inclusive upper;1+<=5
,1..5
: inclusive lower, inclusive upper;
<=4,>2
,<4,>2
,<4,>=2
: Reverse pip syntax (note comma)
To help with readability, bounded ranges can also have their bounds separated with a comma, eg
>=2,<=6
. The comma is purely cosmetic and is dropped in the string representation.To describe more than one contiguous range, seperate ranges with the or
|
symbol. For example, the version range4|6+
contains versions such as4
,4.0
,4.3.1
,6
,6.1
,10.0.0
, but does not contain any version5[.X.X...X]
. If you provide multiple ranges that overlap, they will be automatically optimised. For example, the version range3+<6|4+<8
becomes3+<8
.Note that the empty string version range represents the superset of all possible versions. This is called the “any” range. The empty version can also be used as an upper or lower bound, leading to some odd but perfectly valid version range syntax. For example,
>
is a valid range - read like>''
, it meansany version greater than the empty version
.- __init__(range_str='', make_token=<class 'rez.version._version.AlphanumericVersionToken'>, invalid_bound_error=True)#
- Parameters:
range_str (str) – Range string, such as “3”, “3+<4.5”, “2|6+”. The range will be optimised, so the string representation of this instance may not match range_str. For example, “3+<6|4+<8” == “3+<8”.
make_token (Type[VersionToken]) – Version token class to use.
invalid_bound_error (bool) – If True, raise an exception if an impossible range is given, such as ‘3+<2’.
- is_any()#
- Returns:
True if this is the “any” range, ie the empty string range that contains all versions.
- Return type:
- lower_bounded()#
- Returns:
True if the range has a lower bound (that is not the empty version).
- Return type:
- issuperset(range)#
- Returns:
True if the VersionRange is contained within this range.
- Return type:
- union(other)#
OR together version ranges.
Calculates the union of this range with one or more other ranges.
- Parameters:
other (VersionRange or list[VersionRange]) – Version range object(s) to OR with.
- Returns:
Range object representing the union.
- Return type:
- intersection(other)#
AND together version ranges.
Calculates the intersection of this range with one or more other ranges.
- Parameters:
other (VersionRange or list[VersionRange]) – Version range object(s) to AND with.
- Returns:
New VersionRange object representing the intersection, or None if no ranges intersect.
- Return type:
- inverse()#
Calculate the inverse of the range.
- Returns:
New VersionRange object representing the inverse of this range, or None if there is no inverse (ie, this range is the any range).
- Return type:
- intersects(other)#
Determine if we intersect with another range.
- Parameters:
other (VersionRange) – Version range object.
- Returns:
True if the ranges intersect, False otherwise.
- Return type:
- split()#
Split into separate contiguous ranges.
- Returns:
A list of VersionRange objects. For example, the range
3|5+
will be split into["3", "5+"]
.- Return type:
- classmethod as_span(lower_version=None, upper_version=None, lower_inclusive=True, upper_inclusive=True)#
Create a range from lower_version..upper_version.
- Parameters:
- Return type:
- classmethod from_version(version, op=None)#
Create a range from a version.
- Parameters:
- Return type:
- classmethod from_versions(versions)#
Create a range from a list of versions.
This method creates a range that contains only the given versions and no other. Typically the range looks like (for eg)
==3|==4|==5.1
.- Parameters:
- Return type:
- to_versions()#
Returns exact version ranges as Version objects, or None if there are no exact version ranges present.
- iter_intersect_test(iterable, key=None, descending=False)#
Performs containment tests on a sorted list of versions.
This is more optimal than performing separate containment tests on a list of sorted versions.
- Parameters:
iterable – An ordered sequence of versioned objects. If the list is not sorted by version, behaviour is undefined.
key (Callable[Any]) – Function that returns a
Version
given an object fromiterable
. If None, the identity function is used.descending (bool) – Set to True if
iterable
is in descending version order.
- Returns:
An iterator that returns (bool, object) tuples, where ‘object’ is the original object in
iterable
, and the bool indicates whether that version is contained in this range.- Return type:
- iter_intersecting(iterable, key=None, descending=False)#
Like :meth:iter_intersect_test`, but returns intersections only.
- Returns:
An iterator that returns items from iterable that intersect.
- iter_non_intersecting(iterable, key=None, descending=False)#
Like
iter_intersect_test()
, but returns non-intersections only.- Returns:
An iterator that returns items from iterable that don’t intersect.
- span()#
Return a contiguous range that is a superset of this range.
- Returns:
A range object representing the span of this range. For example, the span of
2+<4|6+<8
would be2+<8
.- Return type:
- visit_versions(func)#
Visit each version in the range, and apply a function to each.
This is for advanced usage only.
If
func
returns aVersion
, this call will change the versions in place.It is possible to change versions in a way that is nonsensical - for example setting an upper bound to a smaller version than the lower bound. Use at your own risk.
- class rez.version.Requirement#
Bases:
_Common
Defines a requirement for an object. For example,
foo-5+
means that you require any version offoo
, version 5 or greater. An unversioned requirement can also be used (foo
), this means you require any version of foo. You can drop the hyphen between object name and version range if the version range starts with a non-alphanumeric character - egfoo<2
.There are two different prefixes that can be applied to a requirement:
!
: The conflict requirement. This means that you require this version range of an object NOT to be present. To conflict with all versions of an object, use “!foo”.~
: This is known as a “weak reference”, and means, “I do not require this object, but if present, it must be within this range.” It is equivalent to the conflict of the inverse of the given version range.
There is one subtle case to be aware of.
~foo
is a requirement that has no effect. It means “I do not require foo, but if foo is present, it can be any version.” This statement is still valid, but will produce a Requirement object with a None range.Examples of valid requirement strings:
foo-1.0
foo@1.0
foo#1.0
foo-1+
foo-1+<4.3
foo<3
foo==1.0.1
- sep_regex = re.compile('[-@#=<>]')#
- __init__(s, invalid_bound_error=True)#
- Parameters:
s (str) – Requirement string
invalid_bound_error (bool) – If True, raise
VersionError
if an impossible range is given, such as3+<2
.
- classmethod construct(name, range=None)#
Create a requirement directly from an object name and VersionRange.
- Parameters:
name (str) – Object name string.
range (Optional[VersionRange]) – If None, an unversioned requirement is created.
- property range#
Version range of the requirement.
- Return type:
- property conflict#
True if the requirement is a conflict requirement, eg “!foo”, “~foo-1”.
- Return type:
- property weak#
True if the requirement is weak, eg “~foo”.
Note
Note that weak requirements are also conflict requirements, but not necessarily the other way around.
- Return type:
- safe_str()#
Return a string representation that is safe for the current filesystem, and guarantees that no two different Requirement objects will encode to the same value.
- Return type:
- conflicts_with(other)#
Returns True if this requirement conflicts with another
Requirement
orVersionedObject
.- Return type:
- merged(other)#
Merge two requirements.
Two requirements can be in conflict and if so, this function returns None. For example, requests for
foo-4
andfoo-6
are in conflict, since both cannot be satisfied with a single version of foo.Some example successful requirements merges are:
foo-3+
and!foo-5+
==foo-3+<5
foo-1
andfoo-1.5
==foo-1.5
!foo-2
and!foo-5
==!foo-2|5
- Returns:
the merged result of two requirements.
- Return type:
- class rez.version.RequirementList#
Bases:
_Common
A list of requirements.
This class takes a Requirement list and reduces it to the equivalent optimal form, merging any requirements for common objects. Order of objects is retained.
- __init__(requirements)#
- Parameters:
requirements (list[Requirement]) – List of requirements.
- property requirements#
Returns optimised list of requirements, or None if there are conflicts.
- Return type:
- property conflict#
Get the requirement conflict, if any.
- Returns:
None if there is no conflict, otherwise a 2-tuple containing the conflicting requirement objects.
- Return type:
- property names#
Set of names of requirements, not including conflict requirements.
- class rez.version.VersionedObject#
Bases:
_Common
Definition of a versioned object, eg
foo-1.0
.foo
is also a valid object definiton. When there is no version part, we are defining an unversioned object.Note
Note that
-
,@
or#
can be used as the seperator between object name and version, however this is purely cosmetic.foo-1
is the same asfoo@1
.- sep_regex_str = '[-@#]'#
- sep_regex = re.compile('[-@#]')#
- classmethod construct(name, version=None)#
Create a VersionedObject directly from an object name and version.
- class rez.version.VersionToken#
Bases:
_Comparable
Token within a version number.
A version token is that part of a version number that appears between a delimiter, typically
.
or-
. For example, the version number2.3.07b
contains the tokens2
,3
and07b
respectively.Version tokens are only allowed to contain alphanumerics (any case) and underscores.
- less_than(other)#
Compare to another
VersionToken
.- Parameters:
other (VersionToken) – The VersionToken object to compare against.
- Returns:
True if this token is less than other, False otherwise.
- Return type:
- next()#
Returns the next largest token.
- class rez.version.NumericToken#
Bases:
VersionToken
Numeric version token.
Version token supporting numbers only. Padding is ignored.
- less_than(other)#
Compare to another
VersionToken
.- Parameters:
other (VersionToken) – The VersionToken object to compare against.
- Returns:
True if this token is less than other, False otherwise.
- Return type:
- next()#
Returns the next largest token.
- class rez.version.AlphanumericVersionToken#
Bases:
VersionToken
Alphanumeric version token.
These tokens compare as follows:
each token is split into alpha and numeric groups (subtokens);
the resulting subtoken list is compared.
alpha comparison is case-sensitive, numeric comparison is padding-sensitive.
Subtokens compare as follows:
alphas come before numbers;
alphas are compared alphabetically (
_
, then A-Z, then a-z);numbers are compared numerically. If numbers are equivalent but zero-padded differently, they are then compared alphabetically. Thus
01
<1
.
Some example comparisons that equate to true:
3
<4
01
<1
beta
<1
alpha3
<alpha4
alpha
<alpha3
gamma33
<33gamma
- numeric_regex = re.compile('[0-9]+')#
- regex = re.compile('[a-zA-Z0-9_]+\\Z')#
- less_than(other)#
Compare to another
VersionToken
.- Parameters:
other (VersionToken) – The VersionToken object to compare against.
- Returns:
True if this token is less than other, False otherwise.
- Return type:
- next()#
Returns the next largest token.
- rez.version.reverse_sort_key(comparable)#
Key that gives reverse sort order on versions and version ranges.
Example
>>> Version("1.0") < Version("2.0") True >>> reverse_sort_key(Version("1.0")) < reverse_sort_key(Version("2.0")) False
- Parameters:
comparable (Version or VersionRange) – Object to wrap.
- Returns:
Wrapper object that reverses comparisons.
- Return type:
_ReversedComparable