Chris@87
|
1 """Utility to compare (Numpy) version strings.
|
Chris@87
|
2
|
Chris@87
|
3 The NumpyVersion class allows properly comparing numpy version strings.
|
Chris@87
|
4 The LooseVersion and StrictVersion classes that distutils provides don't
|
Chris@87
|
5 work; they don't recognize anything like alpha/beta/rc/dev versions.
|
Chris@87
|
6
|
Chris@87
|
7 """
|
Chris@87
|
8 from __future__ import division, absolute_import, print_function
|
Chris@87
|
9
|
Chris@87
|
10 import re
|
Chris@87
|
11
|
Chris@87
|
12 from numpy.compat import basestring
|
Chris@87
|
13
|
Chris@87
|
14
|
Chris@87
|
15 __all__ = ['NumpyVersion']
|
Chris@87
|
16
|
Chris@87
|
17
|
Chris@87
|
18 class NumpyVersion():
|
Chris@87
|
19 """Parse and compare numpy version strings.
|
Chris@87
|
20
|
Chris@87
|
21 Numpy has the following versioning scheme (numbers given are examples; they
|
Chris@87
|
22 can be > 9) in principle):
|
Chris@87
|
23
|
Chris@87
|
24 - Released version: '1.8.0', '1.8.1', etc.
|
Chris@87
|
25 - Alpha: '1.8.0a1', '1.8.0a2', etc.
|
Chris@87
|
26 - Beta: '1.8.0b1', '1.8.0b2', etc.
|
Chris@87
|
27 - Release candidates: '1.8.0rc1', '1.8.0rc2', etc.
|
Chris@87
|
28 - Development versions: '1.8.0.dev-f1234afa' (git commit hash appended)
|
Chris@87
|
29 - Development versions after a1: '1.8.0a1.dev-f1234afa',
|
Chris@87
|
30 '1.8.0b2.dev-f1234afa',
|
Chris@87
|
31 '1.8.1rc1.dev-f1234afa', etc.
|
Chris@87
|
32 - Development versions (no git hash available): '1.8.0.dev-Unknown'
|
Chris@87
|
33
|
Chris@87
|
34 Comparing needs to be done against a valid version string or other
|
Chris@87
|
35 `NumpyVersion` instance. Note that all development versions of the same
|
Chris@87
|
36 (pre-)release compare equal.
|
Chris@87
|
37
|
Chris@87
|
38 .. versionadded:: 1.9.0
|
Chris@87
|
39
|
Chris@87
|
40 Parameters
|
Chris@87
|
41 ----------
|
Chris@87
|
42 vstring : str
|
Chris@87
|
43 Numpy version string (``np.__version__``).
|
Chris@87
|
44
|
Chris@87
|
45 Examples
|
Chris@87
|
46 --------
|
Chris@87
|
47 >>> from numpy.lib import NumpyVersion
|
Chris@87
|
48 >>> if NumpyVersion(np.__version__) < '1.7.0'):
|
Chris@87
|
49 ... print('skip')
|
Chris@87
|
50 skip
|
Chris@87
|
51
|
Chris@87
|
52 >>> NumpyVersion('1.7') # raises ValueError, add ".0"
|
Chris@87
|
53
|
Chris@87
|
54 """
|
Chris@87
|
55
|
Chris@87
|
56 def __init__(self, vstring):
|
Chris@87
|
57 self.vstring = vstring
|
Chris@87
|
58 ver_main = re.match(r'\d[.]\d+[.]\d+', vstring)
|
Chris@87
|
59 if not ver_main:
|
Chris@87
|
60 raise ValueError("Not a valid numpy version string")
|
Chris@87
|
61
|
Chris@87
|
62 self.version = ver_main.group()
|
Chris@87
|
63 self.major, self.minor, self.bugfix = [int(x) for x in
|
Chris@87
|
64 self.version.split('.')]
|
Chris@87
|
65 if len(vstring) == ver_main.end():
|
Chris@87
|
66 self.pre_release = 'final'
|
Chris@87
|
67 else:
|
Chris@87
|
68 alpha = re.match(r'a\d', vstring[ver_main.end():])
|
Chris@87
|
69 beta = re.match(r'b\d', vstring[ver_main.end():])
|
Chris@87
|
70 rc = re.match(r'rc\d', vstring[ver_main.end():])
|
Chris@87
|
71 pre_rel = [m for m in [alpha, beta, rc] if m is not None]
|
Chris@87
|
72 if pre_rel:
|
Chris@87
|
73 self.pre_release = pre_rel[0].group()
|
Chris@87
|
74 else:
|
Chris@87
|
75 self.pre_release = ''
|
Chris@87
|
76
|
Chris@87
|
77 self.is_devversion = bool(re.search(r'.dev', vstring))
|
Chris@87
|
78
|
Chris@87
|
79 def _compare_version(self, other):
|
Chris@87
|
80 """Compare major.minor.bugfix"""
|
Chris@87
|
81 if self.major == other.major:
|
Chris@87
|
82 if self.minor == other.minor:
|
Chris@87
|
83 if self.bugfix == other.bugfix:
|
Chris@87
|
84 vercmp = 0
|
Chris@87
|
85 elif self.bugfix > other.bugfix:
|
Chris@87
|
86 vercmp = 1
|
Chris@87
|
87 else:
|
Chris@87
|
88 vercmp = -1
|
Chris@87
|
89 elif self.minor > other.minor:
|
Chris@87
|
90 vercmp = 1
|
Chris@87
|
91 else:
|
Chris@87
|
92 vercmp = -1
|
Chris@87
|
93 elif self.major > other.major:
|
Chris@87
|
94 vercmp = 1
|
Chris@87
|
95 else:
|
Chris@87
|
96 vercmp = -1
|
Chris@87
|
97
|
Chris@87
|
98 return vercmp
|
Chris@87
|
99
|
Chris@87
|
100 def _compare_pre_release(self, other):
|
Chris@87
|
101 """Compare alpha/beta/rc/final."""
|
Chris@87
|
102 if self.pre_release == other.pre_release:
|
Chris@87
|
103 vercmp = 0
|
Chris@87
|
104 elif self.pre_release == 'final':
|
Chris@87
|
105 vercmp = 1
|
Chris@87
|
106 elif other.pre_release == 'final':
|
Chris@87
|
107 vercmp = -1
|
Chris@87
|
108 elif self.pre_release > other.pre_release:
|
Chris@87
|
109 vercmp = 1
|
Chris@87
|
110 else:
|
Chris@87
|
111 vercmp = -1
|
Chris@87
|
112
|
Chris@87
|
113 return vercmp
|
Chris@87
|
114
|
Chris@87
|
115 def _compare(self, other):
|
Chris@87
|
116 if not isinstance(other, (basestring, NumpyVersion)):
|
Chris@87
|
117 raise ValueError("Invalid object to compare with NumpyVersion.")
|
Chris@87
|
118
|
Chris@87
|
119 if isinstance(other, basestring):
|
Chris@87
|
120 other = NumpyVersion(other)
|
Chris@87
|
121
|
Chris@87
|
122 vercmp = self._compare_version(other)
|
Chris@87
|
123 if vercmp == 0:
|
Chris@87
|
124 # Same x.y.z version, check for alpha/beta/rc
|
Chris@87
|
125 vercmp = self._compare_pre_release(other)
|
Chris@87
|
126 if vercmp == 0:
|
Chris@87
|
127 # Same version and same pre-release, check if dev version
|
Chris@87
|
128 if self.is_devversion is other.is_devversion:
|
Chris@87
|
129 vercmp = 0
|
Chris@87
|
130 elif self.is_devversion:
|
Chris@87
|
131 vercmp = -1
|
Chris@87
|
132 else:
|
Chris@87
|
133 vercmp = 1
|
Chris@87
|
134
|
Chris@87
|
135 return vercmp
|
Chris@87
|
136
|
Chris@87
|
137 def __lt__(self, other):
|
Chris@87
|
138 return self._compare(other) < 0
|
Chris@87
|
139
|
Chris@87
|
140 def __le__(self, other):
|
Chris@87
|
141 return self._compare(other) <= 0
|
Chris@87
|
142
|
Chris@87
|
143 def __eq__(self, other):
|
Chris@87
|
144 return self._compare(other) == 0
|
Chris@87
|
145
|
Chris@87
|
146 def __ne__(self, other):
|
Chris@87
|
147 return self._compare(other) != 0
|
Chris@87
|
148
|
Chris@87
|
149 def __gt__(self, other):
|
Chris@87
|
150 return self._compare(other) > 0
|
Chris@87
|
151
|
Chris@87
|
152 def __ge__(self, other):
|
Chris@87
|
153 return self._compare(other) >= 0
|
Chris@87
|
154
|
Chris@87
|
155 def __repr(self):
|
Chris@87
|
156 return "NumpyVersion(%s)" % self.vstring
|