Quick examples:
Compare versions:
>>> from versions import Version
>>> Version.parse('2.0.0') > Version.parse('1.0.0')
True
Test if constraints are satisfied by a version:
>>> from versions import Constraint, Constraints
>>> '2.0' in Constraint.parse('>1')
True
>>> '1.5' in Constraints.parse('>1,<2')
True
Version comparison examples:
>>> from versions import Version
>>> v1 = Version.parse('1')
>>> v2 = Version.parse('2')
>>> v1 == v2
False
>>> v1 != v2
True
>>> v1 > v2
False
>>> v1 < v2
True
>>> v1 >= v2
False
>>> v1 <= v2
True
Version.parse() expects a version expression string and returns a corresponding Version object:
>>> from versions import Version
>>> v = Version.parse('1.2.0-dev+foo.bar')
>>> v.major, v.minor, v.patch, v.prerelease, v.build_metadata
(1, 2, 0, 'dev', set(['foo', 'bar']))
If it isn’t a semantic version string, the parser tries to normalize it:
>>> v = Version.parse('1')
>>> v.major, v.minor, v.patch, v.prerelease, v.build_metadata
(1, 0, 0, None, None)
versions also implements version constraint parsing and evaluation:
>>> from versions import Constraint
>>> Constraint.parse('>1').match('2')
True
>>> Constraint.parse('<2').match(Version.parse('1'))
True
For conveniance, constraint matching can be tested using the in operator:
>>> '1.5' in Constraint.parse('<2')
True
>>> Version(2) in Constraint.parse('!=2')
False
Constraints can be merged using Constraints:
>>> from versions import Constraints
>>> '1.0' in Constraints.parse('>1,<2')
False
>>> '1.5' in Constraints.parse('>1,<2')
True
>>> '2.0' in Constraints.parse('>1,<2')
False
Modules:
Version expressions are strings representing a software version. They are defined by this EBNF grammar:
version_expression ::= main | main '-' prerelease | main '+' build_metadata | main '-' prerelease '+' build_metadata main ::= major ('.' minor ('.' patch)?)? postrelease? major ::= number minor ::= number patch ::= number postrelease ::= string prerelease ::= string | number build_metadata ::= string number ::= [0-9]+ string ::= [0-9a-zA-Z.-]+
They can be parsed into Version objects using the Version.parse() class method.
Omitted parts in an expression use these defaults:
Part | Default value |
---|---|
minor | 0 |
patch | 0 |
postrelease | None |
prerelease | None |
build_metadata | None |
Examples of valid version expressions:
>>> from versions import Version
>>> v = Version.parse('1')
>>> v == '1.0'
True
>>> v == '1.0.0'
True
>>> v.major, v.minor, v.patch, v.prerelease, v.build_metadata
(1, 0, 0, None, None)
>>> v = Version.parse('1.2.3-dev+foo')
>>> v.major, v.minor, v.patch, v.prerelease, v.build_metadata
(1, 2, 3, 'dev', 'foo')
When parsing fails, an InvalidVersionExpression exception is raised:
>>> Version.parse('#@!')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "versions/version.py", line 119, in parse
raise InvalidVersionExpression(version_string)
versions.version.InvalidVersionExpression: Invalid version expression: '#@!'
A package version.
Parameters: |
---|
This class constructor is usually not called directly. For version string parsing, see Version.parse.
Version major number
Version minor number
Version prerelease
Version build metadata
Version objects are comparable with standard operators:
>>> from versions import Version
>>> v1 = Version(1)
>>> v2 = Version(2)
>>> v1 == v2
False
>>> v1 != v2
True
>>> v1 > v2
False
>>> v1 < v2
True
>>> v1 >= v2
False
>>> v1 <= v2
True
Hint
When comparing 2 versions, only the version and the pre-release are used. The build metadata are ignored.
Raised when failing to parse a version expression.
The bogus version expression.
Constraint expressions are strings representing a constraint on a software version. They are defined by this EBNF grammar:
constraint_expression ::= operator version_expression operator ::= '==' | '!=' | '>' | '<' | '<=' | '>=' version_expression ::= main | main '-' prerelease main ::= major ('.' minor ('.' patch)?)? major ::= number minor ::= number patch ::= number prerelease ::= string | number build_metadata ::= string number ::= [0-9]+ string ::= [0-9a-zA-Z.-]+
They can be parsed into Constraint objects using the Constraint.parse() class method.
Examples of valid constraint expressions:
>>> from versions import Constraint
>>> c = Constraint.parse('==1.0')
>>> c.operator, c.version
(Operator.parse('=='), Version.parse('1.0.0'))
>>> c = Constraint.parse('>=1.2.3-dev+foo')
>>> c.operator, c.version
(Operator.parse('>='), Version.parse('1.2.3-dev+foo'))
When parsing fails, an InvalidConstraintExpression exception is raised:
>>> Constraint.parse('WTF')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "versions/constraint.py", line 94, in parse
raise InvalidConstraintExpression(constraint_expression)
versions.constraint.InvalidConstraintExpression: Invalid constraint expression: 'WTF'
A constraint on a package version.
Parameters: |
---|
The constraint Operator.
The constraint Version.
Match version with the constraint.
Parameters: | version (version expression or Version) – Version to match against the constraint. |
---|---|
Return type: | True if version satisfies the constraint, False if it doesn’t. |
Parses a constraint_expression and returns a Constraint object.
Parameters: | constraint_expression (str) – A constraint expression |
---|---|
Raises: | InvalidConstraintExpression when parsing fails. |
Return type: | Constraint |
The Constraint.match() method returns True when passed a satisfying version expression or Version object:
>>> from versions import Constraint, Version
>>> Constraint.parse('>1').match('2')
True
>>> Constraint.parse('<2').match(Version(1))
True
Matching can also be tested using the in operator:
>>> '1.5' in Constraint.parse('== 1.0')
False
>>> Version(1, 5) in Constraint.parse('> 1.0')
True
>>> Version(1) in Constraint.parse('>= 2.0.0')
False
Constraints expressions are strings representing multiple constraints on a software version. They are defined by this EBNF grammar:
constraints_expression ::= constraint_expression (',' constraint_expression)* constraint_expression ::= operator version_expression operator ::= '==' | '!=' | '>' | '<' | '<=' | '>=' version_expression ::= main | main '-' prerelease main ::= major ('.' minor ('.' patch)?)? major ::= number minor ::= number patch ::= number prerelease ::= string | number build_metadata ::= string number ::= [0-9]+ string ::= [0-9a-zA-Z.-]+
They can be parsed into Constraints objects using the Constraints.parse() class method.
Examples of valid constraint expressions:
>>> from versions import Constraints
>>> c = Constraints.parse('==1.0')
>>> c.constraints
[Constraint.parse('==1.0.0')]
>>> c = Constraints.parse('>=1.0,<2,!=1.5')
>>> c.constraints
[Constraint.parse('!=1.5.0'), Constraint.parse('>=1.0.0'), Constraint.parse('<2.0.0')]
A collection of Constraint objects.
List of Constraint.
Match version with this collection of constraints.
Parameters: | version (version expression or Version) – Version to match against the constraint. |
---|---|
Return type: | True if version satisfies the constraint, False if it doesn’t. |
Parses a constraints_expression and returns a Constraints object.
Constraint objects can be merged using a Constraints object and the + operator:
>>> from versions import Constraints, Constraint
>>> Constraints() + Constraint.parse('<2') + Constraint.parse('!=1.5')
Constraints.parse('<2.0.0,!=1.5.0')
Note
The Constraints object must be on the left side of the + operator. The Constraint object must be on right side.
If the constraint is a constraints expression, it is automatically parsed into a Constraints object.
The previous example can therefore be shortened as:
>>> Constraints() + '<2' + '!=1.5'
Constraints.parse('!=1.5.0,<2.0.0')
Or:
>>> Constraints() + '<2,!=1.5'
Constraints.parse('!=1.5.0,<2.0.0')
Constraints objects work like Constraint objects: they have a Constraints.match() method which returns True when passed a version expression or Version matching all constraints:
>>> Constraints.parse('>=1,<2').match('1.4')
True
>>> '1.4' in Constraints.parse('>=1.2,<2,!=1.4')
False
When merging conflicting constraints, an ExclusiveConstraints exception is raised:
>>> Constraints.parse('<1') + '>1'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "versions/constraints.py", line 96, in __add__
return Constraints(self._merge(constraint))
File "versions/constraints.py", line 89, in _merge
return merge(self.constraints + constraints)
File "versions/constraints.py", line 203, in merge
raise ExclusiveConstraints(g_constraint, [l_constraint])
versions.constraints.ExclusiveConstraints: Constraint >1.0.0 conflicts with constraints <1.0.0
>>> Constraints.parse('<1') + '==1'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "versions/constraints.py", line 96, in __add__
return Constraints(self._merge(constraint))
File "versions/constraints.py", line 89, in _merge
return merge(self.constraints + constraints)
File "versions/constraints.py", line 217, in merge
raise ExclusiveConstraints(eq_constraint, conflict_list)
versions.constraints.ExclusiveConstraints: Constraint ==1.0.0 conflicts with constraints <1.0.0
>>> Constraints.parse('>=1') + '!=1' + '<=1'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "versions/constraints.py", line 96, in __add__
return Constraints(self._merge(constraint))
File "versions/constraints.py", line 89, in _merge
return merge(self.constraints + constraints)
File "versions/constraints.py", line 217, in merge
raise ExclusiveConstraints(eq_constraint, conflict_list)
versions.constraints.ExclusiveConstraints: Constraint ==1.0.0 conflicts with constraints !=1.0.0
Requirement expressions are strings representing a required software package. They are defined by this EBNF grammar:
requirement_expression ::= name build_options? constraints_expression? name ::= [A-Za-z0-9][-A-Za-z0-9]* build_options ::= '[' name (',' name)* ']' constraints_expression ::= constraint_expression (',' constraint_expression)* constraint_expression ::= operator version_expression operator ::= '==' | '!=' | '>' | '<' | '<=' | '>=' version_expression ::= main | main '-' prerelease | main '+' build_metadata | main '-' prerelease '+' build_metadata main ::= major ('.' minor ('.' patch)?)? major ::= number minor ::= number patch ::= number prerelease ::= string | number build_metadata ::= string number ::= [0-9]+ string ::= [0-9a-zA-Z.-]+
The Requirement.parse() class method parses requirement expressions into Requirement objects:
>>> from versions import Requirement
>>> r = Requirement.parse('foo')
>>> r.name
'foo'
>>> r = Requirement.parse('foo >1.0, <2.0')
>>> r.version_constraints
Constraints.parse('>1.0.0,<2.0.0')
>>> r = Requirement.parse('vim [python, perl] >7')
>>> r.build_options
set(['python', 'perl'])
The Requirement.match() method returns True when passed a package which satisfies the requirement:
>>> from versions import Requirement, Package, Version
>>> Requirement('foo').match(Package('foo', Version.parse('1.0')))
True
If passed a str, it is automatically parsed using Package.parse():
>>> Requirement.parse('foo [baz, bar] >0.9').match('foo-1.0+bar.baz')
True
Matching can also be tested using the in operator:
>>> 'foo-0.2' in Requirement.parse('foo [bar] >0.9')
False
Package requirements are used to define a dependency from a Package to another.
Parameters: |
|
---|
Name of the required package.
Constraints on the required package version.
set of required build options
Match package with the requirement.
Parameters: | package (package expression string or Package) – Package to test with the requirement. |
---|---|
Returns: | True if package satisfies the requirement. |
Return type: | bool |
Parses a requirement_expression into a Requirement object.
Parameters: | requirement_expression (requirement_expression) – A package requirement expression. |
---|---|
Return type: | Requirement |
Package expressions are strings representing a software package. They are defined by this EBNF grammar:
package_expression ::= name '-' version_expression dependency* name ::= [A-Za-z0-9][-A-Za-z0-9]* dependency ::= ';' 'depends' requirement_expression requirement_expression ::= name build_options? constraints_expression? build_options ::= '[' name (',' name)* ']' constraints_expression ::= constraint_expression (',' constraint_expression)* constraint_expression ::= operator version_expression operator ::= '==' | '!=' | '>' | '<' | '<=' | '>=' version_expression ::= main | main '-' prerelease | main '+' build_metadata | main '-' prerelease '+' build_metadata main ::= major ('.' minor ('.' patch)?)? major ::= number minor ::= number patch ::= number prerelease ::= string | number build_metadata ::= string number ::= [0-9]+ string ::= [0-9a-zA-Z.-]+
The Package.parse() class method parses package expressions into corresponding Package objects:
>>> from versions import Package
>>> p = Package.parse('foo-1.0')
>>> p.name
'foo'
>>> p.version
Version.parse('1.0.0')
Dependencies can also be specified in a package expression:
>>> package = Package.parse('foo-1.0; depends bar; depends baz >1, <2')
>>> package.dependencies
set([Requirement.parse('baz>1.0.0,<2.0.0'), Requirement.parse('bar')])
A package repository.
Parameters: | packages (set() of Package or None) – Repository packages. |
---|
Find packages matching requirement.
Parameters: | requirement (str or Requirement) – Requirement to match against repository packages. |
---|---|
Returns: | list() of matching Package objects. |
A package repository pool.
When querying a repository pool, it queries all repositories, and merges their results.
Parameters: | repositories (list() of Repository or None) – Underlying package repositories. |
---|
list() of Repository
Find packages matching requirement.
Parameters: | requirement (str or Requirement) – Requirement to get from all underlying repositories. |
---|---|
Returns: | list() of matching Package objects. |
A package version constraint operator.
Parameters: |
---|
Operator callable
Operator string representation
Parses string and returns an Operator object.
Raises: | InvalidOperatorExpression If string is not a valid operator. |
---|
Valid operators are ==, !=, <, >, <=, and >=.