[python-debian/master 1/2] changelog: Use debian_support.Version directly
John Wright
jsw at debian.org
Sun Mar 14 08:54:31 UTC 2010
When implementing the native Python Version class, I didn't notice that
changelog subclasses debian_support.Version and adds a bunch of
properties to it. I had already implemented most of those in
debian_support.BaseVersion, but I hadn't made the properties mutable.
This commit makes them mutable, makes the debian_version property
equivalent to debian_revision, and makes changelog.Version a subclass
without any custom methods.
Now we pass the full test suite again. :) Eventually, the version tests
in test_changelog.py should probably be split out into their own module
and test debian_support.AptPkgVersion and debian_support.NativeVersion
explicitly. But I'll leave that for later.
---
debian/changelog | 3 ++
debian/rules | 2 +-
debian_bundle/changelog.py | 65 ++----------------------------------
debian_bundle/debian_support.py | 70 ++++++++++++++++++++++++++++++++-------
4 files changed, 66 insertions(+), 74 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index c842014..4dd43ec 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -37,6 +37,9 @@ python-debian (0.1.15) UNRELEASED; urgency=low
[ Jelmer Vernooij ]
* Remove unused imports in the debfile and debtags modules
+ [ John Wright ]
+ * changelog: Use debian_support.Version directly
+
-- John Wright <jsw at debian.org> Sat, 13 Mar 2010 21:53:18 -0700
python-debian (0.1.14) unstable; urgency=low
diff --git a/debian/rules b/debian/rules
index 6ce409f..0c3d7bc 100755
--- a/debian/rules
+++ b/debian/rules
@@ -22,7 +22,7 @@ build-stamp: setup.py
cd tests && ./test_debtags.py
cd tests && ./test_changelog.py
- #python debian_bundle/python_support.py
+ python debian_bundle/debian_support.py
debian_bundle/doc-debtags > README.debtags
touch $@
diff --git a/debian_bundle/changelog.py b/debian_bundle/changelog.py
index e64cc3c..9ef7c49 100644
--- a/debian_bundle/changelog.py
+++ b/debian_bundle/changelog.py
@@ -53,67 +53,9 @@ class VersionError(StandardError):
def __str__(self):
return "Could not parse version: "+self._version
-class Version(debian_support.Version, object):
+class Version(debian_support.Version):
"""Represents a version of a Debian package."""
- # Subclassing debian_support.Version for its rich comparison
-
- def __init__(self, version):
- version = str(version)
- debian_support.Version.__init__(self, version)
-
- self.full_version = version
-
- def __setattr__(self, attr, value):
- """Update all the attributes, given a particular piece of the version
-
- Allowable values for attr, hopefully self-explanatory:
- full_version
- epoch
- upstream_version
- debian_version
-
- Any attribute starting with __ is given to object's __setattr__ method.
- """
-
- attrs = ('full_version', 'epoch', 'upstream_version', 'debian_version')
-
- if attr.startswith('_Version__'):
- object.__setattr__(self, attr, value)
- return
- elif attr not in attrs:
- raise AttributeError("Cannot assign to attribute " + attr)
-
- if attr == 'full_version':
- version = value
- p = re.compile(r'^(?:(?P<epoch>\d+):)?'
- + r'(?P<upstream_version>[A-Za-z0-9.+:~-]+?)'
- + r'(?:-(?P<debian_version>[A-Za-z0-9.~+]+))?$')
- m = p.match(version)
- if m is None:
- raise VersionError(version)
- for key, value in m.groupdict().items():
- object.__setattr__(self, key, value)
- self.__asString = version
-
- else:
- # Construct a full version from what was given and pass it back here
- d = {}
- for a in attrs[1:]:
- if a == attr:
- d[a] = value
- else:
- d[a] = getattr(self, a)
-
- version = ""
- if d['epoch'] and d['epoch'] != '0':
- version += d['epoch'] + ":"
- version += d['upstream_version']
- if d['debian_version']:
- version += '-' + d['debian_version']
-
- self.full_version = version
-
- full_version = property(lambda self: self.__asString)
+ # debian_support.Version now has all the functionality we need
class ChangeBlock(object):
"""Holds all the information about one block from the changelog."""
@@ -465,7 +407,8 @@ class Changelog(object):
### For convenience, let's expose some of the version properties
full_version = property(lambda self: self.version.full_version)
epoch = property(lambda self: self.version.epoch)
- debian_version = property(lambda self: self.version.debian_version)
+ debian_version = property(lambda self: self.version.debian_revision)
+ debian_revision = property(lambda self: self.version.debian_revision)
upstream_version = property(lambda self: self.version.upstream_version)
def get_package(self):
diff --git a/debian_bundle/debian_support.py b/debian_bundle/debian_support.py
index 48d2eee..d216bba 100644
--- a/debian_bundle/debian_support.py
+++ b/debian_bundle/debian_support.py
@@ -71,8 +71,10 @@ class BaseVersion(object):
according to Section 5.6.12 in the Debian Policy Manual. Since splitting
the version into epoch, upstream_version, and debian_revision components is
pretty much free with the validation, it sets those fields as properties of
- the object. A missing epoch or debian_revision results in the respective
- property set to "0". These properties are immutable.
+ the object, and sets the raw version to the full_version property. A
+ missing epoch or debian_revision results in the respective property set to
+ None. Setting any of the properties results in the full_version being
+ recomputed and the rest of the properties set from that.
It also implements __str__, just returning the raw version given to the
initializer.
@@ -82,26 +84,70 @@ class BaseVersion(object):
r"^((?P<epoch>\d+):)?"
"(?P<upstream_version>[A-Za-z0-9.+:~-]+?)"
"(-(?P<debian_revision>[A-Za-z0-9+.~]+))?$")
+ magic_attrs = ('full_version', 'epoch', 'upstream_version',
+ 'debian_revision', 'debian_version')
def __init__(self, version):
- if not isinstance(version, (str, unicode)):
- raise ValueError, "version must be a string or unicode object"
+ self.full_version = version
+ def _set_full_version(self, version):
m = self.re_valid_version.match(version)
if not m:
raise ValueError("Invalid version string %r" % version)
- self.__raw_version = version
+ self.__full_version = version
self.__epoch = m.group("epoch")
self.__upstream_version = m.group("upstream_version")
self.__debian_revision = m.group("debian_revision")
- epoch = property(lambda self: self.__epoch or "0")
- upstream_version = property(lambda self: self.__upstream_version)
- debian_revision = property(lambda self: self.__debian_revision or "0")
+ def __setattr__(self, attr, value):
+ if attr not in self.magic_attrs:
+ super(BaseVersion, self).__setattr__(attr, value)
+ return
+
+ # For compatibility with the old changelog.Version class
+ if attr == "debian_version":
+ attr = "debian_revision"
+
+ if attr == "full_version":
+ self._set_full_version(str(value))
+ else:
+ if value is not None:
+ value = str(value)
+ private = "_BaseVersion__%s" % attr
+ old_value = getattr(self, private)
+ setattr(self, private, value)
+ try:
+ self._update_full_version()
+ except ValueError:
+ # Don't leave it in an invalid state
+ setattr(self, private, old_value)
+ self._update_full_version()
+ raise ValueError("Setting %s to %r results in invalid version"
+ % (attr, value))
+
+ def __getattr__(self, attr):
+ if attr not in self.magic_attrs:
+ return super(BaseVersion, self).__getattribute__(attr)
+
+ # For compatibility with the old changelog.Version class
+ if attr == "debian_version":
+ attr = "debian_revision"
+
+ private = "_BaseVersion__%s" % attr
+ return getattr(self, private)
+
+ def _update_full_version(self):
+ version = ""
+ if self.__epoch is not None:
+ version += self.__epoch + ":"
+ version += self.__upstream_version
+ if self.__debian_revision:
+ version += "-" + self.__debian_revision
+ self.full_version = version
def __str__(self):
- return self.__raw_version
+ return self.full_version
def __repr__(self):
return "%s('%s')" % (self.__class__.__name__, self)
@@ -140,15 +186,15 @@ class NativeVersion(BaseVersion):
raise ValueError("Couldn't convert %r to BaseVersion: %s"
% (other, e))
- res = cmp(int(self.epoch), int(other.epoch))
+ res = cmp(int(self.epoch or "0"), int(other.epoch or "0"))
if res != 0:
return res
res = self._version_cmp_part(self.upstream_version,
other.upstream_version)
if res != 0:
return res
- return self._version_cmp_part(self.debian_revision,
- other.debian_revision)
+ return self._version_cmp_part(self.debian_revision or "0",
+ other.debian_revision or "0")
@classmethod
def _order(cls, x):
--
1.6.3.3
More information about the pkg-python-debian-commits
mailing list