microproduct/atmosphericDelay/ISCEApp/site-packages/whoosh/util/versions.py

166 lines
5.2 KiB
Python

# Copyright 2012 Matt Chaput. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY MATT CHAPUT ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL MATT CHAPUT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are
# those of the authors and should not be interpreted as representing official
# policies, either expressed or implied, of Matt Chaput.
from whoosh.util.text import rcompile
class BaseVersion(object):
@classmethod
def parse(cls, text):
obj = cls()
match = cls._version_exp.match(text)
if match:
groupdict = match.groupdict()
for groupname, typ in cls._parts:
v = groupdict.get(groupname)
if v is not None:
setattr(obj, groupname, typ(v))
return obj
def __repr__(self):
vs = ", ".join(repr(getattr(self, slot)) for slot in self.__slots__)
return "%s(%s)" % (self.__class__.__name__, vs)
def tuple(self):
return tuple(getattr(self, slot) for slot in self.__slots__)
def __eq__(self, other):
if not hasattr(other, "tuple"):
raise ValueError("Can't compare %r with %r" % (self, other))
return self.tuple() == other.tuple()
def __lt__(self, other):
if not hasattr(other, "tuple"):
raise ValueError("Can't compare %r with %r" % (self, other))
return self.tuple() < other.tuple()
# It's dumb that you have to define these
def __gt__(self, other):
if not hasattr(other, "tuple"):
raise ValueError("Can't compare %r with %r" % (self, other))
return self.tuple() > other.tuple()
def __ge__(self, other):
if not hasattr(other, "tuple"):
raise ValueError("Can't compare %r with %r" % (self, other))
return self.tuple() >= other.tuple()
def __le__(self, other):
if not hasattr(other, "tuple"):
raise ValueError("Can't compare %r with %r" % (self, other))
return self.tuple() <= other.tuple()
def __ne__(self, other):
if not hasattr(other, "tuple"):
raise ValueError("Can't compare %r with %r" % (self, other))
return self.tuple() != other.tuple()
class SimpleVersion(BaseVersion):
"""An object that parses version numbers such as::
12.2.5b
The filter supports a limited subset of PEP 386 versions including::
1
1.2
1.2c
1.2c3
1.2.3
1.2.3a
1.2.3b4
10.7.5rc1
999.999.999c999
"""
_version_exp = rcompile(r"""
^
(?P<major>\d{1,4})
(
[.](?P<minor>\d{1,4})
(
[.](?P<release>\d{1,4})
)?
(
(?P<ex>[abc]|rc)
(?P<exnum>\d{1,4})?
)?
)?
$
""", verbose=True)
# (groupid, method, skippable, default)
_parts = [("major", int),
("minor", int),
("release", int),
("ex", str),
("exnum", int),
]
_ex_bits = {"a": 0, "b": 1, "c": 2, "rc": 10, "z": 15}
_bits_ex = dict((v, k) for k, v in _ex_bits.items())
__slots__ = ("major", "minor", "release", "ex", "exnum")
def __init__(self, major=1, minor=0, release=0, ex="z", exnum=0):
self.major = major
self.minor = minor
self.release = release
self.ex = ex
self.exnum = exnum
def to_int(self):
assert self.major < 1024
n = self.major << 34
assert self.minor < 1024
n |= self.minor << 24
assert self.release < 1024
n |= self.release << 14
exbits = self._ex_bits.get(self.ex, 15)
n |= exbits << 10
assert self.exnum < 1024
n |= self.exnum
return n
@classmethod
def from_int(cls, n):
major = (n & (1023 << 34)) >> 34
minor = (n & (1023 << 24)) >> 24
release = (n & (1023 << 14)) >> 14
exbits = (n & (7 << 10)) >> 10
ex = cls._bits_ex.get(exbits, "z")
exnum = n & 1023
return cls(major, minor, release, ex, exnum)