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
|
#! /usr/bin/python
#
# Copyright(c) 2009 Gentoo Foundation
# Licensed under the GNU General Public License, v2
#
# Copyright: 2005-2007 Brian Harring <ferringb@gmail.com>
# License: GPL2/BSD
#
# $Header$
"""Gentoo version comparison object from pkgcore.ebuild.atom_restricts."""
# =======
# Imports
# =======
from portage.versions import vercmp
from gentoolkit import errors
from gentoolkit.cpv import CPV
# =======
# Classes
# =======
class VersionMatch(object):
"""Gentoo version comparison object from pkgcore.ebuild.atom_restricts.
Any overriding of this class *must* maintain numerical order of
self.vals, see intersect for reason why. vals also must be a tuple.
"""
_convert_op2int = {(-1,):"<", (-1, 0): "<=", (0,):"=",
(0, 1):">=", (1,):">"}
_convert_int2op = dict([(v, k) for k, v in _convert_op2int.items()])
def __init__(self, cpv, op='='):
"""Initialize a VersionMatch instance.
@type cpv: L{gentoolkit.cpv.CPV}
@param cpv: cpv object
@type op: str
@keyword op: operator
"""
if not isinstance(cpv, (CPV, self.__class__)):
err = "cpv must be a gentoolkit.cpv.CPV "
err += "or gentoolkit.versionmatch.VersionMatch instance"
raise ValueError(err)
self.cpv = cpv
self.operator = op
self.version = cpv.version
self.revision = cpv.revision
self.fullversion = cpv.fullversion
if self.operator != "~" and self.operator not in self._convert_int2op:
raise errors.GentoolkitInvalidVersion(
"invalid operator '%s'" % self.operator)
if self.operator == "~":
if not self.version:
raise errors.GentoolkitInvalidVersion(
"for ~ op, ver must be specified")
self.droprevision = True
self.values = (0,)
else:
self.droprevision = False
self.values = self._convert_int2op[self.operator]
def match(self, other):
"""See whether a passed in VersionMatch or CPV instance matches self.
Example usage:
>>> from gentoolkit.versionmatch import VersionMatch
>>> from gentoolkit.cpv import CPV
>>> VersionMatch(CPV('foo/bar-1.5'), op='>').match(
... VersionMatch(CPV('foo/bar-2.0')))
True
@type other: gentoolkit.versionmatch.VersionMatch OR
gentoolkit.cpv.CPV
@param other: version to compare with self's version
@rtype: bool
"""
if self.droprevision:
ver1, ver2 = self.version, other.version
else:
ver1, ver2 = self.fullversion, other.fullversion
return vercmp(ver2, ver1) in self.values
def __str__(self):
operator = self._convert_op2int[self.values]
if self.droprevision or not self.revision:
return "ver %s %s" % (operator, self.version)
return "ver-rev %s %s-%s" % (
operator, self.version, self.revision
)
def __repr__(self):
return "<%s %r>" % (self.__class__.__name__, str(self))
@staticmethod
def _convert_ops(inst):
if inst.droprevision:
return inst.values
return tuple(sorted(set((-1, 0, 1)).difference(inst.values)))
def __eq__(self, other):
if self is other:
return True
if isinstance(other, self.__class__):
if (self.droprevision != other.droprevision or
self.version != other.version or
self.revision != other.revision):
return False
return self._convert_ops(self) == self._convert_ops(other)
return False
def __ne__(self, other):
return not self == other
def __hash__(self):
return hash((
self.droprevision,
self.version,
self.revision,
self.values
))
# vim: set ts=4 sw=4 tw=79:
|