File size: 5,010 Bytes
dc2106c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
"""Utility to compare (NumPy) version strings.



The NumpyVersion class allows properly comparing numpy version strings.

The LooseVersion and StrictVersion classes that distutils provides don't

work; they don't recognize anything like alpha/beta/rc/dev versions.



"""
import re


__all__ = ['NumpyVersion']


class NumpyVersion():
    """Parse and compare numpy version strings.



    NumPy has the following versioning scheme (numbers given are examples; they

    can be > 9 in principle):



    - Released version: '1.8.0', '1.8.1', etc.

    - Alpha: '1.8.0a1', '1.8.0a2', etc.

    - Beta: '1.8.0b1', '1.8.0b2', etc.

    - Release candidates: '1.8.0rc1', '1.8.0rc2', etc.

    - Development versions: '1.8.0.dev-f1234afa' (git commit hash appended)

    - Development versions after a1: '1.8.0a1.dev-f1234afa',

                                     '1.8.0b2.dev-f1234afa',

                                     '1.8.1rc1.dev-f1234afa', etc.

    - Development versions (no git hash available): '1.8.0.dev-Unknown'



    Comparing needs to be done against a valid version string or other

    `NumpyVersion` instance. Note that all development versions of the same

    (pre-)release compare equal.



    .. versionadded:: 1.9.0



    Parameters

    ----------

    vstring : str

        NumPy version string (``np.__version__``).



    Examples

    --------

    >>> from numpy.lib import NumpyVersion

    >>> if NumpyVersion(np.__version__) < '1.7.0':

    ...     print('skip')

    >>> # skip



    >>> NumpyVersion('1.7')  # raises ValueError, add ".0"

    Traceback (most recent call last):

        ...

    ValueError: Not a valid numpy version string



    """

    def __init__(self, vstring):
        self.vstring = vstring
        ver_main = re.match(r'\d+\.\d+\.\d+', vstring)
        if not ver_main:
            raise ValueError("Not a valid numpy version string")

        self.version = ver_main.group()
        self.major, self.minor, self.bugfix = [int(x) for x in
            self.version.split('.')]
        if len(vstring) == ver_main.end():
            self.pre_release = 'final'
        else:
            alpha = re.match(r'a\d', vstring[ver_main.end():])
            beta = re.match(r'b\d', vstring[ver_main.end():])
            rc = re.match(r'rc\d', vstring[ver_main.end():])
            pre_rel = [m for m in [alpha, beta, rc] if m is not None]
            if pre_rel:
                self.pre_release = pre_rel[0].group()
            else:
                self.pre_release = ''

        self.is_devversion = bool(re.search(r'.dev', vstring))

    def _compare_version(self, other):
        """Compare major.minor.bugfix"""
        if self.major == other.major:
            if self.minor == other.minor:
                if self.bugfix == other.bugfix:
                    vercmp = 0
                elif self.bugfix > other.bugfix:
                    vercmp = 1
                else:
                    vercmp = -1
            elif self.minor > other.minor:
                vercmp = 1
            else:
                vercmp = -1
        elif self.major > other.major:
            vercmp = 1
        else:
            vercmp = -1

        return vercmp

    def _compare_pre_release(self, other):
        """Compare alpha/beta/rc/final."""
        if self.pre_release == other.pre_release:
            vercmp = 0
        elif self.pre_release == 'final':
            vercmp = 1
        elif other.pre_release == 'final':
            vercmp = -1
        elif self.pre_release > other.pre_release:
            vercmp = 1
        else:
            vercmp = -1

        return vercmp

    def _compare(self, other):
        if not isinstance(other, (str, NumpyVersion)):
            raise ValueError("Invalid object to compare with NumpyVersion.")

        if isinstance(other, str):
            other = NumpyVersion(other)

        vercmp = self._compare_version(other)
        if vercmp == 0:
            # Same x.y.z version, check for alpha/beta/rc
            vercmp = self._compare_pre_release(other)
            if vercmp == 0:
                # Same version and same pre-release, check if dev version
                if self.is_devversion is other.is_devversion:
                    vercmp = 0
                elif self.is_devversion:
                    vercmp = -1
                else:
                    vercmp = 1

        return vercmp

    def __lt__(self, other):
        return self._compare(other) < 0

    def __le__(self, other):
        return self._compare(other) <= 0

    def __eq__(self, other):
        return self._compare(other) == 0

    def __ne__(self, other):
        return self._compare(other) != 0

    def __gt__(self, other):
        return self._compare(other) > 0

    def __ge__(self, other):
        return self._compare(other) >= 0

    def __repr__(self):
        return "NumpyVersion(%s)" % self.vstring