semantic_version
compare(v1, v2)
Compare two version strings, and return a result similar to that of cmp
:
>>> compare('0.1.1', '0.1.2')
-1
>>> compare('0.1.1', '0.1.1')
0
>>> compare('0.1.1', '0.1.1-alpha')
1
- param str v1
The first version to compare
- param str v2
The second version to compare
- raises
ValueError
, if any version string is invalid- rtype
int
, -1 / 0 / 1 as for acmp
comparison;NotImplemented
if versions only differ by build metadata
Warning
Since build metadata has no ordering, compare(Version('0.1.1'), Version('0.1.1+3'))
returns NotImplemented
match(spec, version)
Check whether a version string matches a specification string:
>>> match('>=0.1.1', '0.1.2')
True
>>> match('>=0.1.1', '0.1.1-alpha')
False
>>> match('~0.1.1', '0.1.1-alpha')
True
- param str spec
The specification to use, as a string
- param str version
The version string to test against the spec
- raises
ValueError
, if thespec
or theversion
is invalid- rtype
bool
validate(version)
Check whether a version string complies with the SemVer rules.
>>> semantic_version.validate('1.1.1')
True
>>> semantic_version.validate('1.2.3a4')
False
- param str version
The version string to validate
- rtype
bool
Object representation of a SemVer-compliant version.
Constructed from a textual version string:
>>> Version('1.1.1')
Version('1.1.1')
>>> str(Version('1.1.1'))
'1.1.1'
Attributes
partial
bool
, whether this is a 'partial' or a complete version number. Partial version number may lack minor
or patch
version numbers.
major
int
, the major version number
minor
int
, the minor version number.
May be None
for a partial
version number in a <major>
format.
patch
int
, the patch version number.
May be None
for a partial
version number in a <major>
or <major>.<minor>
format.
prerelease
tuple
of strings
, the prerelease component.
It contains the various dot-separated identifiers in the prerelease component.
May be None
for a partial
version number in a <major>
, <major>.<minor>
or <major>.<minor>.<patch>
format.
build
tuple
of strings
, the build metadata.
It contains the various dot-separated identifiers in the build metadata.
May be None
for a partial
version number in a <major>
, <major>.<minor>
, <major>.<minor>.<patch>
or <major>.<minor>.<patch>-<prerelease>
format.
Methods
__iter__(self)
Iterates over the version components (major
, minor
, patch
, prerelease
, build
):
>>> list(Version('0.1.1'))
[0, 1, 1, [], []]
Note
This may pose some subtle bugs when iterating over a single version while expecting an iterable of versions -- similar to:
>>> list('abc')
['a', 'b', 'c'] >>> list(('abc',)) ['abc']
__cmp__(self, other)
Provides comparison methods with other Version
objects.
The rules are:
- For non-
partial
versions, compare using the SemVer scheme - If any compared object is
partial
: - Begin comparison using the SemVer scheme
- If a component (
minor
,patch
,prerelease
orbuild
) was absent from thepartial
Version
-- represented withNone
--, consider both versions equal.
For instance,
Version('1.0', partial=True)
means "any version beginning in1.0
".Version('1.0.1-alpha', partial=True)
means "The1.0.1-alpha
version or any any release differing only in build metadata":1.0.1-alpha+build3
matches,1.0.1-alpha.2
doesn't.
- If any compared object is
Examples:
>>> Version('1.0', partial=True) == Version('1.0.1')
True
>>> Version('1.0.1-rc1.1') == Version('1.0.1-rc1', partial=True)
False
>>> Version('1.0.1-rc1+build345') == Version('1.0.1-rc1')
False
>>> Version('1.0.1-rc1+build345') == Version('1.0.1-rc1', partial=True)
True
__str__(self)
Returns the standard text representation of the version:
>>> v = Version('0.1.1-rc2+build4.4')
>>> v
Version('0.1.1-rc2+build4.4')
>>> str(v)
'0.1.1-rc2+build4.4'
__hash__(self)
Provides a hash based solely on the components.
Allows using a Version
as a dictionary key.
Note
A fully qualified partial
Version
(up to the build
component) will hash the same as the equally qualified, non-partial
Version
:
>>> hash(Version('1.0.1+build4')) == hash(Version('1.0.1+build4', partial=True))
True
Class methods
parse(cls, version_string[, partial=False])
Parse a version string into a (major, minor, patch, prerelease, build)
tuple.
- param str version_string
The version string to parse
- param bool partial
Whether this should be considered a
partial
version- raises
ValueError
, if theversion_string
is invalid.- rtype
(major, minor, patch, prerelease, build)
coerce(cls, version_string[, partial=False])
Try to convert an arbitrary version string into a Version
instance.
Rules are:
- If no minor or patch component, and
partial
isFalse
, replace them with zeroes - Any character outside of
a-zA-Z0-9.+-
is replaced with a-
- If more than 3 dot-separated numerical components, everything from the fourth component belongs to the
build
part - Any extra
+
in thebuild
part will be replaced with dots
Examples:
>>> Version.coerce('02')
Version('2.0.0')
>>> Version.coerce('1.2.3.4')
Version('1.2.3+4')
>>> Version.coerce('1.2.3.4beta2')
Version('1.2.3+4beta2')
>>> Version.coerce('1.2.3.4.5_6/7+8+9+10')
Version('1.2.3+4.5-6-7.8.9.10')
- param str version_string
The version string to coerce
- param bool partial
Whether to allow generating a
partial
version- raises
ValueError
, if theversion_string
is invalid.- rtype
Version
Version specifications describe a 'range' of accepted versions: older than, equal, similar to, …
The main issue with representing version specifications is that the usual syntax does not map well onto SemVer precedence rules:
- A specification of
<1.3.4
is not expected to allow1.3.4-rc2
, but strict SemVer comparisons allow it ; prereleases has the issue of excluding1.3.3+build3
; - It may be necessary to exclude either all variations on a patch-level release (
!=1.3.3
) or specifically one build-level release (1.3.3-build.434
).
In order to have version specification behave naturally, the rules are the following:
- If no pre-release number was included in the specification, pre-release numbers are ignored when deciding whether a version satisfies a specification.
- If no build metadata was included in the specification, build metadata is ignored when deciding whether a version satisfies a specification.
This means that:
>>> Version('1.1.1-rc1') in Spec('<1.1.1')
False
>>> Version('1.1.1-rc1') in Spec('<1.1.1-rc4')
True
>>> Version('1.1.1-rc1+build4') in Spec('<=1.1.1-rc1')
True
>>> Version('1.1.1-rc1+build4') in Spec('==1.1.1-rc1+build2')
False
Note
python-semanticversion also accepts "*"
as a version spec, that matches all (valid) version strings.
Note
python-semanticversion supports PyPI-style compatible release clauses:
~=2.2
means "Any release between 2.2.0 and 3.0.0"~=1.4.5
means "Any release between 1.4.5 and 1.5.0"
Note
python-semanticversion includes support for NPM-style specs:
~1.2.3
means "Any release between 1.2.3 and 1.3.0"^1.3.4
means "Any release between 1.3.4 and 2.0.0"
In order to force matches to strictly compare version numbers, these additional rules apply:
Setting a pre-release separator without a pre-release identifier (
<=1.1.1-
) forces match to take into account pre-release version:>>> Version('1.1.1-rc1') in Spec('<1.1.1') False >>> Version('1.1.1-rc1') in Spec('<1.1.1-') True
Setting a build metadata separator without build metadata (
<=1.1.1+
) forces matches "up to the build metadata"; use this to include/exclude a release lacking build metadata while excluding/including all other builds of that release>>> Version('1.1.1') in Spec('==1.1.1+') True >>> Version('1.1.1+2') in Spec('==1.1.1+') False
Warning
As stated in the SemVer specification, the ordering of build metadata is undefined. Thus, a Spec
string can only mention build metadata to include or exclude a specific version:
==1.1.1+b1234
includes this specific build!=1.1.1+b1234
excludes it (but would match1.1.1+b1235
<1.1.1+b1
is invalid
Stores a list of SpecItem
and matches any Version
against all contained specs <SpecItem>
.
It is built from a comma-separated list of version specifications:
>>> Spec('>=1.0.0,<1.2.0,!=1.1.4')
<Spec: (
<SpecItem: >= Version('1.0.0', partial=True)>,
<SpecItem: < Version('1.2.0', partial=True)>,
<SpecItem: != Version('1.1.4', partial=True)>
)>
Version specifications may also be passed in separated arguments:
>>> Spec('>=1.0.0', '<1.2.0', '!=1.1.4,!=1.1.13')
<Spec: (
<SpecItem: >= Version('1.0.0', partial=True)>,
<SpecItem: < Version('1.2.0', partial=True)>,
<SpecItem: != Version('1.1.4', partial=True)>,
<SpecItem: != Version('1.1.13', partial=True)>,
)>
Attributes
specs
Tuple of SpecItem
, the included specifications.
Methods
match(self, version)
Test whether a given Version
matches all included SpecItem
:
>>> Spec('>=1.1.0,<1.1.2').match(Version('1.1.1'))
True
- param version
The version to test against the specs
- type version
Version
- rtype
bool
filter(self, versions)
Extract all compatible versions <Version>
from an iterable of Version
objects.
- param versions
The versions to filter
- type versions
iterable of
Version
- yield
Version
select(self, versions)
Select the highest compatible version from an iterable of Version
objects.
pycon
>>> s = Spec('>=0.1.0') >>> s.select([]) None >>> s.select([Version('0.1.0'), Version('0.1.3'), Version('0.1.1')]) Version('0.1.3')
- param versions
The versions to filter
- type versions
iterable of
Version
- rtype
The highest compatible
Version
if at least one of the given versions is compatible;None
otherwise.
__contains__(self, version)
Alias of the match
method; allows the use of the version in speclist
syntax:
>>> Version('1.1.1-alpha') in Spec('>=1.1.0,<1.1.1')
True
__str__(self)
Converting a Spec
returns the initial description string:
>>> str(Spec('>=0.1.1,!=0.1.2'))
'>=0.1.1,!=0.1.2'
__iter__(self)
Returns an iterator over the contained specs:
>>> for spec in Spec('>=0.1.1,!=0.1.2'):
... print spec
>=0.1.1
!=0.1.2
__hash__(self)
Provides a hash based solely on the hash of contained specs.
Allows using a Spec
as a dictionary key.
Class methods
parse(self, specs_string)
Retrieve a (*specs)
tuple from a string.
- param str requirement_string
The textual description of the specifications
- raises
ValueError
: if therequirement_string
is invalid.- rtype
(*spec)
tuple
Note
This class belong to the private python-semanticversion API.
Stores a version specification, defined from a string:
>>> SpecItem('>=0.1.1')
<SpecItem: >= Version('0.1.1', partial=True)>
This allows to test Version
objects against the SpecItem
:
>>> SpecItem('>=0.1.1').match(Version('0.1.1-rc1')) # pre-release satisfy conditions
True
>>> Version('0.1.1+build2') in SpecItem('>=0.1.1') # build metadata is ignored when checking for precedence
True
>>>
>>> # Use the '-' marker to include the pre-release component in checks
>>> SpecItem('>=0.1.1-').match(Version('0.1.1-rc1')
False
>>> # Use the '+' marker to include the build metadata in checks
>>> SpecItem('==0.1.1+').match(Version('0.1.1+b1234')
False
>>>
Attributes
kind
One of KIND_LT
, KIND_LTE
, KIND_EQUAL
, KIND_GTE
, KIND_GT
and KIND_NEQ
.
spec
Version
in the SpecItem
description.
It is alway a ~Version.partial
Version
.
Class methods
parse(cls, requirement_string)
Retrieve a (kind, version)
tuple from a string.
- param str requirement_string
The textual description of the specification
- raises
ValueError
: if therequirement_string
is invalid.- rtype
(
kind
,version
) tuple
Methods
match(self, version)
Test whether a given Version
matches this SpecItem
:
>>> SpecItem('>=0.1.1').match(Version('0.1.1-alpha'))
True
>>> SpecItem('>=0.1.1-').match(Version('0.1.1-alpha'))
False
- param version
The version to test against the spec
- type version
Version
- rtype
bool
__str__(self)
Converting a SpecItem
to a string returns the initial description string:
>>> str(SpecItem('>=0.1.1'))
'>=0.1.1'
__hash__(self)
Provides a hash based solely on the current kind and the specified version.
Allows using a SpecItem
as a dictionary key.
Class attributes
KIND_LT
The kind of 'Less than' specifications:
>>> Version('1.0.0-alpha') in Spec('<1.0.0')
False
KIND_LTE
The kind of 'Less or equal to' specifications:
>>> Version('1.0.0-alpha1+build999') in Spec('<=1.0.0-alpha1')
True
KIND_EQUAL
The kind of 'equal to' specifications:
>>> Version('1.0.0+build3.3') in Spec('==1.0.0')
True
KIND_GTE
The kind of 'Greater or equal to' specifications:
>>> Version('1.0.0') in Spec('>=1.0.0')
True
KIND_GT
The kind of 'Greater than' specifications:
>>> Version('1.0.0+build667') in Spec('>1.0.1')
False
KIND_NEQ
The kind of 'Not equal to' specifications:
>>> Version('1.0.1') in Spec('!=1.0.1')
False
The kind of 'Almost equal to' specifications