Author: fw
Date: 2006-06-15 18:17:18 +0000 (Thu, 15 Jun 2006)
New Revision: 4236
Modified:
lib/python/debian_support.py
lib/python/security_db.py
Log:
* lib/python/debian_support.py
(Version): Implement using apt_pkg if APT is available.
(version_compare): Add.
* lib/python/security_db.py
(DB._initFunctions): Directly invoke debian_support.version_compare.
Modified: lib/python/debian_support.py
==================================================================---
lib/python/debian_support.py 2006-06-15 14:21:06 UTC (rev 4235)
+++ lib/python/debian_support.py 2006-06-15 18:17:18 UTC (rev 4236)
@@ -22,6 +22,12 @@
import sha
import types
+try:
+ import apt_pkg
+ __have_apt_pkg = True
+except ImportError:
+ __have_apt_pkg = False
+
class ParseError(Exception):
"""An exception which is used to signal a parse failure.
@@ -52,74 +58,101 @@
file.write("%s:%d: %s\n" % (self.filename, self.lineno,
self.msg))
file.flush()
-letterValue = [None] * 256
-def initLetterValue():
- c = 0
- for x in range(ord(''A''), ord(''Z'') + 1):
- letterValue[x] = chr(c)
- c += 1
- for x in range(ord(''a''), ord(''z'') + 1):
- letterValue[x] = chr(c)
- c += 1
- for x in "+-.:":
- letterValue[ord(x)] = chr(c)
- c += 1
-initLetterValue()
-del initLetterValue
+if __have_apt_pkg:
+ class Version:
+ """Version class which uses the original APT comparison
algorithm."""
-class Version:
- """This class implements Debian version
numbers."""
+ def __init__(self, version):
+ """Creates a new Version object."""
+ assert type(version) == types.StringType, `version`
+ assert version <> ""
+ self.__asString = version
- def __init__(self, version):
- """Creates a new Version object."""
- assert type(version) == types.StringType, `version`
- assert version <> ""
- self.__asString = version
- self.__parsed = self.__parse(version)
+ def __str__(self):
+ return self.__asString
- def __str__(self):
- return self.__asString
+ def __repr__(self):
+ return ''Version(%s)'' % `self.__asString`
- def __repr__(self):
- return ''Version(%s)'' % `self.__asString`
+ def __cmp__(self, other):
+ return apt_pkg.VersionCompare(self.__asString, other.__asString)
- def __cmp__(self, other):
- """Compares two versions.
- This method implements the algorithm in the Debian
Policy."""
- return cmp(self.__parsed, other.__parsed)
+ version_compare = apt_pkg.VersionCompare
+ apt_pkg.init()
- def __parse(self, v, regexp=\
- re.compile(r''^(?:(\d+):)?([A-Za-z0-9.+:-]+?)''
- + r''(?:-([A-Za-z0-9.+]+))?$'')):
- match = regexp.match(v)
- if match is None:
- raise ValueError, "invalid Debian version string"
- (epoch, upstream, debian) = match.groups()
- if epoch is None:
- epoch = 0
- else:
- epoch = int(epoch)
- return (epoch, self.__parse_1(upstream), self.__parse_1(debian))
+else:
+ letterValue = [None] * 256
+ def initLetterValue():
+ c = 0
+ for x in range(ord(''A''), ord(''Z'') +
1):
+ letterValue[x] = chr(c)
+ c += 1
+ for x in range(ord(''a''), ord(''z'') +
1):
+ letterValue[x] = chr(c)
+ c += 1
+ for x in "+-.:":
+ letterValue[ord(x)] = chr(c)
+ c += 1
+ initLetterValue()
+ del initLetterValue
- def __parse_1(self, x,
non_digits=re.compile(r''^([^0-9]*)(.*)$''),
- digits=re.compile(r''^([0-9]*)(.*)$'')):
- l = []
- while x is not None and x <> '''':
- (nd, x) = non_digits.match(x).groups()
- (d, x) = digits.match(x).groups()
- nd_l = []
- for ch in nd:
- nd_l.append(letterValue[ord(ch)])
- nd = ''''.join(nd_l)
- if d == '''':
- d = 0
+ class Version:
+ """This class implements Debian version
numbers."""
+
+ def __init__(self, version):
+ """Creates a new Version object."""
+ assert type(version) == types.StringType, `version`
+ assert version <> ""
+ self.__asString = version
+ self.__parsed = self.__parse(version)
+
+ def __str__(self):
+ return self.__asString
+
+ def __repr__(self):
+ return ''Version(%s)'' % `self.__asString`
+
+ def __cmp__(self, other):
+ """Compares two versions.
+
+ This method implements the algorithm in the Debian
Policy."""
+ return cmp(self.__parsed, other.__parsed)
+
+ def __parse(self, v, regexp=\
+
re.compile(r''^(?:(\d+):)?([A-Za-z0-9.+:-]+?)''
+ +
r''(?:-([A-Za-z0-9.+]+))?$'')):
+ match = regexp.match(v)
+ if match is None:
+ raise ValueError, "invalid Debian version string"
+ (epoch, upstream, debian) = match.groups()
+ if epoch is None:
+ epoch = 0
else:
- d = int(d)
- l.append(nd)
- l.append(d)
- return l
+ epoch = int(epoch)
+ return (epoch, self.__parse_1(upstream), self.__parse_1(debian))
+ def __parse_1(self, x,
non_digits=re.compile(r''^([^0-9]*)(.*)$''),
+ digits=re.compile(r''^([0-9]*)(.*)$'')):
+ l = []
+ while x is not None and x <> '''':
+ (nd, x) = non_digits.match(x).groups()
+ (d, x) = digits.match(x).groups()
+ nd_l = []
+ for ch in nd:
+ nd_l.append(letterValue[ord(ch)])
+ nd = ''''.join(nd_l)
+ if d == '''':
+ d = 0
+ else:
+ d = int(d)
+ l.append(nd)
+ l.append(d)
+ return l
+
+ def version_compare(a,b):
+ return cmp(Version(a), Version(b))
+
class PackageFile:
"""A Debian package file.
Modified: lib/python/security_db.py
==================================================================---
lib/python/security_db.py 2006-06-15 14:21:06 UTC (rev 4235)
+++ lib/python/security_db.py 2006-06-15 18:17:18 UTC (rev 4236)
@@ -455,11 +455,7 @@
return release
self.db.createscalarfunction("release_name", release_name, 3)
- # This is slower than the version_linear_order table, but
- # often more convenient to use in queries.
- def collate_version(a, b):
- return debian_support.Version(a).__cmp__(debian_support.Version(b))
- self.db.createcollation("version", collate_version)
+ self.db.createcollation("version",
debian_support.version_compare)
def filePrint(self, filename):
"""Returns a fingerprint string for
filename."""