Changelog enhancements

John Wright john at movingsucks.org
Mon Nov 27 03:48:28 CET 2006


On Wed, Nov 22, 2006 at 06:02:44PM +0000, James Westby wrote:
> [Apologies if you get this twice, I wasn't sure if you were subscribed,
> I am by the way, so feel free to just post to the list in future.]

Ok, I'll write just to the list from now on. :)

> > I guess there are a couple good ways to handle this.  The one I picked
> > was to expose the attributes through properties which only implement a
> > get method, effectively making the objects immutable.  Another way, of
> > course, would be to add more logic to the class, perhaps by storing each
> > part of the version separately, and having the full_version attribute
> > actually call a method that reconstructs the version.
> > 
> 
> I think mutable might be better, but I'm from a Java background where I
> would have made them immutable. 
> 
> > 
> > I also added an __eq__ method to the Version class.  It might be cool in
> > the future to have a full __cmp__ method, perhaps like the one in
> > debian_support.py, or perhaps to use apt_pkg.VersionCompare if apt_pkg
> > is available.
> 
> I would like to use the debian_support objects, and I can't really
> remember why I didn't. I should look in to transitioning over. I think
> it might have been that you can't get the parts out of the whole number.
> I think it's a bad idea to have two classes in the same package that
> serve the same purpose, it's more of a historical reason.

I went ahead and subclassed the debian_support Version class, and I
implemented the mutable stuff sort of like I was musing about above.  It
seems to work fine, both with and without apt_pkg, and it passes all the
test cases, so I'm happy with it as long as you are.

> I'm more than happy for you to commit your changes direct, as there not
> even an API breakage. I believe you have the permissions now.

I wouldn't mind committing to the trunk, but the properties feature in
the Changelog class does break the API: previously, to get, say, the
latest version, you'd use cl.version().  Now, the thing called version
is an attribute (or, at least acts like one) rather than a method.  Same
with most of the other things in that class.

So, I've pushed the branch here:
    sftp://bzr.debian.org/bzr/pkg-python-debian/people/jsw/changelog_properties
and I've attached a bundle which indicates all the changes from the
trunk.  I've changed a bit of stuff since the last time I wrote (mostly
in the Version class), but I think I've explained myself pretty well the
in the changelog and commit messages.  Also, I updated README.changelog
to reflect the API changes.

Anyway, since the changes might affect bzr-builddeb, I'll let you merge
this one in.

Thanks!
John
-------------- next part --------------
# Bazaar revision bundle v0.8
#
# message:
#   * changelog.py:
#     - Version class:
#       + Subclass debian_support.Version, to get rich comparison
#       + Make the full_version, epoch, upstream_version, and debian_version
#         attributes modifiable, and now any change automatically updates the other
#         affected attribute.  Also, assignment to any other attribute (that
#         doesn't start with '__') raises an exception.
#     - Changelog class:
#       + Fix broken get_versions() method (rewrote with a list comprehension)
#       + Add missing epoch attribute, and make all these convenience version
#         attributes read+write
#     - Add a magic vim line to the bottom to tell it that a "tab" should be two
#       spaces for this file
#     - Add some test cases
#   
#   * README.changelog:
#     - Update to reflect recent changes
#   
# committer: John Wright <john at movingsucks.org>
# date: Sat 2006-11-25 05:17:31.065000057 -0700

=== modified file README.changelog
--- README.changelog
+++ README.changelog
@@ -10,34 +10,39 @@
 file if there are some entries, or None to create an empty changelog.
 See /usr/share/doc/python-debian/examples/changelog/ for examples of usage.
 
-The Changelog class provides the following interesting methods.
-
- * full_version()
-     Returns the full version number of the last version.
- * debian_version()
-     Returns the debian part of the version number of the last version.
- * upstream_version()
-     Returns the upstream part of the version number of the last version.
- * epoch()
-     Returns the epoch number of the last revision, or None if no epoch was 
-     used
- * package()
-     Returns the name of the package in the last version.
- * versions()
-     Returns a list of version objects that the package went through. These
-     version objects provide all attributes named the same as the above
-     functions to get that same information. 
- * set_package(package)
-     Sets the name of the package in the most recent version.
- * set_version(version)
-     Sets the version number of the most recent version. The provided argument
-     is a Version object.
- * set_distributions(distributions)
-     Sets the distributions that the package will be uploaded to in the most
-     recent version. (Provide a string).
- * set_urgency(urgency)
-     Sets the urgency with which the most recent version will be uploaded. 
-     (Provide a string).
+The Changelog class provides the following interesting attributes and methods:
+
+ * version
+     A Version object representing the version of the last block.  You may
+     assign to it a Version object or a full version string.
+ * full_version
+     The full version number of the last version.
+ * debian_version
+     The debian part of the version number of the last version.
+ * upstream_version
+     The upstream part of the version number of the last version.
+ * epoch
+     The epoch number of the last revision, or None if no epoch was 
+     used.
+ * versions
+     A list of Version objects that the package went through. These version
+     objects provide all attributes named the same as the above to get that
+     same information.  You cannot assign to this attribute.
+ * package
+     The name of the package in the last version.
+ * distributions
+     A string indicating the distributions that the package will be uploaded to
+     in the most recent version.
+ * urgency
+     A string indicating the urgency with which the most recent version will be
+     uploaded.
+ * author
+     The author of the most recent change. This should be a properly formatted
+     name/email pair.
+ * date
+     The date associated with the current entry. Should be a properly formatted
+     string with the date and timezone.
+
  * add_change(change)
      Adds a change entry to the most recent version. The change entry should
      conform to the required format of the changelog (i.e. start with two 
@@ -45,16 +50,11 @@
      advisable to do this yourself if it is a long entry. The change will be
      appended to he current changes, no support is provided for per-maintainer
      changes.
-  * set_author(author)
-      Sets the author of the most recent change. THis should be a properly 
-      formatted name/email pair.
-  * set_date(date)
-      Sets the date associated with the current entry. Should be a properly 
-      formatted string with the date and timezone.
-  * new_block(package, version, distributions, urgency, changes, author, date)
-      Start a new version of the package. The arguments (all optional) specify
-      the values that can be provided to the set_* methods. If they are omitted
-      the associated set_ call must be made before the changelog is created.
+ * new_block(package, version, distributions, urgency, changes, author, date)
+     Start a new version of the package. The arguments (all optional) specify
+     the values that can be provided to the set_* methods. If they are omitted
+     the associated attributes must be assigned to before the changelog is
+     created.
 
 To get the properly formatted changelog back out of the object merely call 
 str() on it. The returned string should be a properly formatted changelog.
@@ -74,7 +74,8 @@
      The string used to create a Version object cannot be parsed as it doesn't
      conform to the specification of a version number. Can be thrown when
      creating a Changelog object from an existing changelog, or instantiating
-     a Version object directly to use with the set_version method.
+     a Version object directly to assign to the version attribute of a
+     Changelog object.
 
 This file is (C) 2006 James Westby, and licensed under the GPL, see 
 changelog.py for details.

=== modified file debian/changelog
--- debian/changelog
+++ debian/changelog
@@ -1,3 +1,23 @@
+python-debian (0.1.1) UNRELEASED; urgency=low
+
+  * changelog.py:
+    - Version class:
+      + Subclass debian_support.Version, for rich comparison
+      + Changing any attribute now automatically updates any other affected
+        attribute (i.e. changing full_version will update all of the other
+        attributes; changing debian_version will update full_version)
+    - Changelog class:
+      + Many "getter" and "setter" methods were replaced with properties (so
+        they appear as regular object attributes).  Most set_* methods remain
+        for compatibility, and they're the actual set methods for the
+        properties anyway.  Please see README.changelog.
+      + You can now assign a string to the version attribute, and it will be
+        coerced into a Version object
+  * README.changelog:
+    - Update the documentation to reflect the changes mentioned above
+
+ -- John Wright <john at movingsucks.org>  Sat, 25 Nov 2006 04:40:14 -0700
+
 python-debian (0.1.0) experimental; urgency=low
 
   * Initial release. (Closes: #381599)

=== modified file debian_bundle/changelog.py
--- debian_bundle/changelog.py
+++ debian_bundle/changelog.py
@@ -21,6 +21,8 @@
 import re
 import unittest
 
+import debian_support
+
 class ChangelogParseError(StandardError):
   """Indicates that the changelog could not be parsed"""
   is_user_error = True
@@ -46,24 +48,67 @@
   def __str__(self):
     return "Could not parse version: "+self._version
 
-class Version(object):
+class Version(debian_support.Version, object):
   """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
-    p = re.compile(r'^(?:(\d+):)?([A-Za-z0-9.+:~-]+?)'
-                   + r'(?:-([A-Za-z0-9.~+]+))?$')
-    m = p.match(version)
-    if m is None:
-      raise VersionError(version)
-    (epoch, upstream, debian) = m.groups()
-    self.epoch = epoch
-    self.upstream_version = upstream
-    self.debian_version = debian
-
-  def __str__(self):
-    return self.full_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)
 
 class ChangeBlock(object):
   """Holds all the information about one block from the changelog."""
@@ -213,34 +258,46 @@
       #TODO: shouldn't be required should it?
       self._blocks[-1].del_trailing_newline()
 
-  def full_version(self):
-    """Returns the full version number of the last version."""
-    return self._blocks[0].version.full_version
-
-  def debian_version(self):
-    """Returns the debian part of the version number of the last version. 
-    Will be None if it is a native package"""
-    return self._blocks[0].version.debian_version
-
-  def upstream_version(self):
-    """Returns the upstream part of the version number of the last version"""
-    return self._blocks[0].version.upstream_version
-
-  def epoch(self):
-    """Returns the epoch number of the last revision, or None if no epoch was
-    used"""
-    return self._blocks[0].version.epoch
-
-  def package(self):
+  def get_version(self):
+    """Return a Version object for the last version"""
+    return self._blocks[0].version
+
+  def set_version(self, version):
+    """Set the version of the last changelog block
+
+    version can be a full version string, or a Version object
+    """
+    self._blocks[0].version = Version(version)
+
+  version = property(get_version, set_version,
+                     doc="Version object for last changelog block""")
+
+  ### For convenience, let's expose some of the version properties
+  full_version = property(lambda self: self.version.full_version,
+                  lambda self, v: setattr(self.version, 'full_version', v))
+  epoch = property(lambda self: self.version.epoch,
+                  lambda self, v: setattr(self.version, 'epoch', v))
+  debian_version = property(lambda self: self.version.debian_version,
+                  lambda self, v: setattr(self.version, 'debian_version', v))
+  upstream_version = property(lambda self: self.version.upstream_version,
+                  lambda self, v: setattr(self.version, 'upstream_version', v))
+
+  def get_package(self):
     """Returns the name of the package in the last version."""
     return self._blocks[0].package
-
-  def versions(self):
+  
+  def set_package(self, package):
+    self._blocks[0].package = package
+
+  package = property(get_package, set_package,
+                     doc="Name of the package in the last version")
+
+  def get_versions(self):
     """Returns a list of version objects that the package went through."""
-    versions = []
-    for block in self._blocks:
-      versions.append[block.version]
-    return versions
+    return [block.version for block in self._blocks]
+
+  versions = property(get_versions,
+                      doc="List of version objects the package went through")
 
   def __str__(self):
     cl = ""
@@ -248,26 +305,25 @@
       cl += str(block)
     return cl
 
-  def set_package(self, package):
-    self._blocks[0].package = package
-
-  def set_version(self, version):
-    self._blocks[0].version = version
-
   def set_distributions(self, distributions):
     self._blocks[0].distributions = distributions
+  distributions = property(lambda self: self._blocks[0].distributions,
+                           set_distributions)
 
   def set_urgency(self, urgency):
     self._blocks[0].urgency = urgency
+  urgency = property(lambda self: self._blocks[0].urgency, set_urgency)
 
   def add_change(self, change):
     self._blocks[0].add_change(change)
 
   def set_author(self, author):
     self._blocks[0].author = author
+  author = property(lambda self: self._blocks[0].author, set_author)
 
   def set_date(self, date):
     self._blocks[0].date = date
+  date = property(lambda self: self._blocks[0].date, set_date)
 
   def new_block(self, package=None, version=None, distributions=None,
                 urgency=None, changes=None, author=None, date=None):
@@ -299,13 +355,13 @@
 
     c = open('test_modify_changelog1').read()
     cl = Changelog(c)
-    cl.set_package('gnutls14')
-    cl.set_version(Version('1:1.4.1-2'))
-    cl.set_distributions('experimental')
-    cl.set_urgency('medium')
+    cl.package = 'gnutls14'
+    cl.version = '1:1.4.1-2'
+    cl.distributions = 'experimental'
+    cl.urgency = 'medium'
     cl.add_change('  * Add magic foo')
-    cl.set_author('James Westby <jw+debian at jameswestby.net>')
-    cl.set_date('Sat, 16 Jul 2008 11:11:08 -0200')
+    cl.author = 'James Westby <jw+debian at jameswestby.net>'
+    cl.date = 'Sat, 16 Jul 2008 11:11:08 -0200'
     c = open('test_modify_changelog2').read()
     clines = c.split('\n')
     cslines = str(cl).split('\n')
@@ -333,6 +389,41 @@
       self.assertEqual(clines[i], cslines[i])
     self.assertEqual(len(clines), len(cslines), "Different lengths")
 
+  def test_set_version_with_string(self):
+    c1 = Changelog(open('test_modify_changelog1').read())
+    c2 = Changelog(open('test_modify_changelog1').read())
+
+    c1.version = '1:2.3.5-2'
+    c2.version = Version('1:2.3.5-2')
+    self.assertEqual(c1.version, c2.version)
+    self.assertEqual((c1.full_version, c1.epoch, c1.upstream_version,
+                      c1.debian_version),
+                     (c2.full_version, c2.epoch, c2.upstream_version,
+                      c2.debian_version))
+
+  def test_magic_version_properties(self):
+    c = Changelog(open('test_changelog').read())
+
+    c.debian_version = '2'
+    self.assertEqual(c.debian_version, '2')
+    self.assertEqual(c.full_version, '1:1.4.1-2')
+
+    c.upstream_version = '1.4.2'
+    self.assertEqual(c.upstream_version, '1.4.2')
+    self.assertEqual(c.full_version, '1:1.4.2-2')
+
+    c.epoch = '2'
+    self.assertEqual(c.epoch, '2')
+    self.assertEqual(c.full_version, '2:1.4.2-2')
+
+    self.assertEqual(str(c.version), c.full_version)
+
+    c.full_version = '1:1.4.1-1'
+    self.assertEqual(c.full_version, '1:1.4.1-1')
+    self.assertEqual(c.epoch, '1')
+    self.assertEqual(c.upstream_version, '1.4.1')
+    self.assertEqual(c.debian_version, '1')
+
 class VersionTests(unittest.TestCase):
 
   def _test_version(self, full_version, epoch, upstream, debian):
@@ -362,7 +453,30 @@
     self._test_version('1.8RC4b', None, '1.8RC4b', None)
     self._test_version('0.9~rc1-1', None, '0.9~rc1', '1')
 
+  def test_version_updating(self):
+    v = Version('1:1.4.1-1')
+
+    v.debian_version = '2'
+    self.assertEqual(v.debian_version, '2')
+    self.assertEqual(v.full_version, '1:1.4.1-2')
+
+    v.upstream_version = '1.4.2'
+    self.assertEqual(v.upstream_version, '1.4.2')
+    self.assertEqual(v.full_version, '1:1.4.2-2')
+
+    v.epoch = '2'
+    self.assertEqual(v.epoch, '2')
+    self.assertEqual(v.full_version, '2:1.4.2-2')
+
+    self.assertEqual(str(v), v.full_version)
+
+    v.full_version = '1:1.4.1-1'
+    self.assertEqual(v.full_version, '1:1.4.1-1')
+    self.assertEqual(v.epoch, '1')
+    self.assertEqual(v.upstream_version, '1.4.1')
+    self.assertEqual(v.debian_version, '1')
 
 if __name__ == "__main__":
   _test()
 
+# vim:softtabstop=2 shiftwidth=2 expandtab

# revision id: john at movingsucks.org-20061125121731-37e08e221b869369
# sha1: af5b92d1769d0faebe81ced3b4b68b7906b71e4f
# inventory sha1: 0533899ba81e870d4075a253407f136bd6a23c2e
# parent ids:
#   john at movingsucks.org-20061122054417-2653ad3643f129e6
# base id: enrico at enricozini.org-20061120213648-cb925575bce6b414
# properties:
#   branch-nick: changelog_properties

# message:
#   Update the test suite
# committer: John Wright <john at movingsucks.org>
# date: Tue 2006-11-21 22:44:17.923000097 -0700

=== modified file debian_bundle/changelog.py // encoding:base64
LS0tIGRlYmlhbl9idW5kbGUvY2hhbmdlbG9nLnB5CisrKyBkZWJpYW5fYnVuZGxlL2NoYW5nZWxv
Zy5weQpAQCAtNzMsNiArNzMsOSBAQAogICBkZWYgX19zdHJfXyhzZWxmKToKICAgICByZXR1cm4g
c2VsZi5mdWxsX3ZlcnNpb24KIAorICBkZWYgX19lcV9fKHNlbGYsIG90aGVyKToKKyAgICByZXR1
cm4gc2VsZi5mdWxsX3ZlcnNpb24gPT0gb3RoZXIuZnVsbF92ZXJzaW9uCisKIGNsYXNzIENoYW5n
ZUJsb2NrKG9iamVjdCk6CiAgICIiIkhvbGRzIGFsbCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgb25l
IGJsb2NrIGZyb20gdGhlIGNoYW5nZWxvZy4iIiIKIApAQCAtMzE2LDEzICszMTksMTMgQEAKIAog
ICAgIGMgPSBvcGVuKCd0ZXN0X21vZGlmeV9jaGFuZ2Vsb2cxJykucmVhZCgpCiAgICAgY2wgPSBD
aGFuZ2Vsb2coYykKLSAgICBjbC5zZXRfcGFja2FnZSgnZ251dGxzMTQnKQotICAgIGNsLnNldF92
ZXJzaW9uKFZlcnNpb24oJzE6MS40LjEtMicpKQotICAgIGNsLnNldF9kaXN0cmlidXRpb25zKCdl
eHBlcmltZW50YWwnKQotICAgIGNsLnNldF91cmdlbmN5KCdtZWRpdW0nKQorICAgIGNsLnBhY2th
Z2UgPSAnZ251dGxzMTQnCisgICAgY2wudmVyc2lvbiA9ICcxOjEuNC4xLTInCisgICAgY2wuZGlz
dHJpYnV0aW9ucyA9ICdleHBlcmltZW50YWwnCisgICAgY2wudXJnZW5jeSA9ICdtZWRpdW0nCiAg
ICAgY2wuYWRkX2NoYW5nZSgnICAqIEFkZCBtYWdpYyBmb28nKQotICAgIGNsLnNldF9hdXRob3Io
J0phbWVzIFdlc3RieSA8ancrZGViaWFuQGphbWVzd2VzdGJ5Lm5ldD4nKQotICAgIGNsLnNldF9k
YXRlKCdTYXQsIDE2IEp1bCAyMDA4IDExOjExOjA4IC0wMjAwJykKKyAgICBjbC5hdXRob3IgPSAn
SmFtZXMgV2VzdGJ5IDxqdytkZWJpYW5AamFtZXN3ZXN0YnkubmV0PicKKyAgICBjbC5kYXRlID0g
J1NhdCwgMTYgSnVsIDIwMDggMTE6MTE6MDggLTAyMDAnCiAgICAgYyA9IG9wZW4oJ3Rlc3RfbW9k
aWZ5X2NoYW5nZWxvZzInKS5yZWFkKCkKICAgICBjbGluZXMgPSBjLnNwbGl0KCdcbicpCiAgICAg
Y3NsaW5lcyA9IHN0cihjbCkuc3BsaXQoJ1xuJykKQEAgLTM1MCw2ICszNTMsMTYgQEAKICAgICAg
IHNlbGYuYXNzZXJ0RXF1YWwoY2xpbmVzW2ldLCBjc2xpbmVzW2ldKQogICAgIHNlbGYuYXNzZXJ0
RXF1YWwobGVuKGNsaW5lcyksIGxlbihjc2xpbmVzKSwgIkRpZmZlcmVudCBsZW5ndGhzIikKIAor
ICBkZWYgdGVzdF9zZXRfdmVyc2lvbl93aXRoX3N0cmluZyhzZWxmKToKKyAgICBjMSA9IENoYW5n
ZWxvZyhvcGVuKCd0ZXN0X21vZGlmeV9jaGFuZ2Vsb2cxJykucmVhZCgpKQorICAgIGMyID0gQ2hh
bmdlbG9nKG9wZW4oJ3Rlc3RfbW9kaWZ5X2NoYW5nZWxvZzEnKS5yZWFkKCkpCisKKyAgICBjMS52
ZXJzaW9uID0gJzE6Mi4zLjUtMicKKyAgICBjMi52ZXJzaW9uID0gVmVyc2lvbignMToyLjMuNS0y
JykKKyAgICBzZWxmLmFzc2VydEVxdWFsKGMxLnZlcnNpb24sIGMyLnZlcnNpb24pCisgICAgc2Vs
Zi5hc3NlcnRFcXVhbCgoYzEuZnVsbF92ZXJzaW9uLCBjMS51cHN0cmVhbV92ZXJzaW9uLCBjMS5k
ZWJpYW5fdmVyc2lvbiksCisgICAgICAgICAgICAgICAgICAgICAoYzIuZnVsbF92ZXJzaW9uLCBj
Mi51cHN0cmVhbV92ZXJzaW9uLCBjMi5kZWJpYW5fdmVyc2lvbikpCisKIGNsYXNzIFZlcnNpb25U
ZXN0cyh1bml0dGVzdC5UZXN0Q2FzZSk6CiAKICAgZGVmIF90ZXN0X3ZlcnNpb24oc2VsZiwgZnVs
bF92ZXJzaW9uLCBlcG9jaCwgdXBzdHJlYW0sIGRlYmlhbik6CkBAIC0zNzksNiArMzkyLDExIEBA
CiAgICAgc2VsZi5fdGVzdF92ZXJzaW9uKCcxLjhSQzRiJywgTm9uZSwgJzEuOFJDNGInLCBOb25l
KQogICAgIHNlbGYuX3Rlc3RfdmVyc2lvbignMC45fnJjMS0xJywgTm9uZSwgJzAuOX5yYzEnLCAn
MScpCiAKKyAgZGVmIHRlc3RfZXF1YWxpdHkoc2VsZik6CisgICAgdjEgPSBWZXJzaW9uKCcxOjIu
My40LTInKQorICAgIHYyID0gVmVyc2lvbignMToyLjMuNC0yJykKKyAgICBzZWxmLmFzc2VydEVx
dWFsKHYxLCB2MikKKwogCiBpZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICBfdGVzdCgpCgo=

# revision id: john at movingsucks.org-20061122054417-2653ad3643f129e6
# sha1: 72bcbd627a6819d465300f977f438202e77acb3d
# inventory sha1: a659915a758c2e28dc834da7241691e144ffd3c7
# parent ids:
#   john at movingsucks.org-20061122052350-5253bb76e196f1dd
# properties:
#   branch-nick: trunk

# message:
#   * Make Version essentially immutable, to avoid mistakes of, e.g., setting the
#     debian_version attribute but not having it be reflected in the string
#     representation
#   * Expose lots of simple getter-setter methods in Changelog as attributes, using
#     property
#   
# committer: John Wright <john at movingsucks.org>
# date: Tue 2006-11-21 22:23:50.482000113 -0700

=== modified file debian_bundle/changelog.py // encoding:base64
LS0tIGRlYmlhbl9idW5kbGUvY2hhbmdlbG9nLnB5CisrKyBkZWJpYW5fYnVuZGxlL2NoYW5nZWxv
Zy5weQpAQCAtNTEsMTYgKzUxLDI0IEBACiAKICAgZGVmIF9faW5pdF9fKHNlbGYsIHZlcnNpb24p
OgogICAgIAotICAgIHNlbGYuZnVsbF92ZXJzaW9uID0gdmVyc2lvbgotICAgIHAgPSByZS5jb21w
aWxlKHInXig/OihcZCspOik/KFtBLVphLXowLTkuKzp+LV0rPyknCi0gICAgICAgICAgICAgICAg
ICAgKyByJyg/Oi0oW0EtWmEtejAtOS5+K10rKSk/JCcpCi0gICAgbSA9IHAubWF0Y2godmVyc2lv
bikKKyAgICBwID0gcmUuY29tcGlsZShyJ14oPzooP1A8ZXBvY2g+XGQrKTopPyg/UDx1cHN0cmVh
bT5bQS1aYS16MC05Lis6fi1dKz8pJworICAgICAgICAgICAgICAgICAgICsgcicoPzotKD9QPGRl
Ymlhbj5bQS1aYS16MC05Ln4rXSspKT8kJykKKyAgICBtID0gcC5tYXRjaChzdHIodmVyc2lvbikp
CiAgICAgaWYgbSBpcyBOb25lOgogICAgICAgcmFpc2UgVmVyc2lvbkVycm9yKHZlcnNpb24pCi0g
ICAgKGVwb2NoLCB1cHN0cmVhbSwgZGViaWFuKSA9IG0uZ3JvdXBzKCkKLSAgICBzZWxmLmVwb2No
ID0gZXBvY2gKLSAgICBzZWxmLnVwc3RyZWFtX3ZlcnNpb24gPSB1cHN0cmVhbQotICAgIHNlbGYu
ZGViaWFuX3ZlcnNpb24gPSBkZWJpYW4KKyAgICBzZWxmLl9fYXR0cnMgPSBtLmdyb3VwZGljdCgp
CisgICAgc2VsZi5fX2F0dHJzWydmdWxsJ10gPSBzdHIodmVyc2lvbikKKworICAjIEV4cG9zZSBz
b21lIGF0dHJpYnV0ZXMsIHJlYWQtb25seSAoc28gaXQncyBub3QgcG9zc2libGUgdG8gYWNjaWRl
bnRhbGx5CisgICMgb3ZlcnJpdGUsIHNheSwgZGViaWFuX3ZlcnNpb24gd2l0aG91dCByZWFsbHkg
Y2hhbmdpbmcgdGhlIHZlcnNpb24pCisKKyAgIyBGSVhNRTogV291bGQgaXQgYmUgYmV0dGVyIHRv
IG1ha2UgVmVyc2lvbiBvYmplY3RzIG11dGFibGUsIGJ1dCBoYXZlIHNtYXJ0CisgICMgbWV0aG9k
cyB0aGF0IGtub3cgaG93IHRvIGNvbnN0cnVjdCBhIHZlcnNpb24gZnJvbSB0aGVzZSB0aHJlZSBh
dHRyaWJ1dGVzPworICAKKyAgZnVsbF92ZXJzaW9uID0gcHJvcGVydHkobGFtYmRhIHNlbGY6IHNl
bGYuX19hdHRyc1snZnVsbCddKQorICBlcG9jaCA9IHByb3BlcnR5KGxhbWJkYSBzZWxmOiBzZWxm
Ll9fYXR0cnNbJ2Vwb2NoJ10pCisgIHVwc3RyZWFtX3ZlcnNpb24gPSBwcm9wZXJ0eShsYW1iZGEg
c2VsZjogc2VsZi5fX2F0dHJzWyd1cHN0cmVhbSddKQorICBkZWJpYW5fdmVyc2lvbiA9IHByb3Bl
cnR5KGxhbWJkYSBzZWxmOiBzZWxmLl9fYXR0cnNbJ2RlYmlhbiddKQogCiAgIGRlZiBfX3N0cl9f
KHNlbGYpOgogICAgIHJldHVybiBzZWxmLmZ1bGxfdmVyc2lvbgpAQCAtMjEzLDYxICsyMjEsNzAg
QEAKICAgICAgICNUT0RPOiBzaG91bGRuJ3QgYmUgcmVxdWlyZWQgc2hvdWxkIGl0PwogICAgICAg
c2VsZi5fYmxvY2tzWy0xXS5kZWxfdHJhaWxpbmdfbmV3bGluZSgpCiAKLSAgZGVmIGZ1bGxfdmVy
c2lvbihzZWxmKToKLSAgICAiIiJSZXR1cm5zIHRoZSBmdWxsIHZlcnNpb24gbnVtYmVyIG9mIHRo
ZSBsYXN0IHZlcnNpb24uIiIiCi0gICAgcmV0dXJuIHNlbGYuX2Jsb2Nrc1swXS52ZXJzaW9uLmZ1
bGxfdmVyc2lvbgotCi0gIGRlZiBkZWJpYW5fdmVyc2lvbihzZWxmKToKLSAgICAiIiJSZXR1cm5z
IHRoZSBkZWJpYW4gcGFydCBvZiB0aGUgdmVyc2lvbiBudW1iZXIgb2YgdGhlIGxhc3QgdmVyc2lv
bi4gCi0gICAgV2lsbCBiZSBOb25lIGlmIGl0IGlzIGEgbmF0aXZlIHBhY2thZ2UiIiIKLSAgICBy
ZXR1cm4gc2VsZi5fYmxvY2tzWzBdLnZlcnNpb24uZGViaWFuX3ZlcnNpb24KLQotICBkZWYgdXBz
dHJlYW1fdmVyc2lvbihzZWxmKToKLSAgICAiIiJSZXR1cm5zIHRoZSB1cHN0cmVhbSBwYXJ0IG9m
IHRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGUgbGFzdCB2ZXJzaW9uIiIiCi0gICAgcmV0dXJuIHNl
bGYuX2Jsb2Nrc1swXS52ZXJzaW9uLnVwc3RyZWFtX3ZlcnNpb24KLQotICBkZWYgZXBvY2goc2Vs
Zik6Ci0gICAgIiIiUmV0dXJucyB0aGUgZXBvY2ggbnVtYmVyIG9mIHRoZSBsYXN0IHJldmlzaW9u
LCBvciBOb25lIGlmIG5vIGVwb2NoIHdhcwotICAgIHVzZWQiIiIKLSAgICByZXR1cm4gc2VsZi5f
YmxvY2tzWzBdLnZlcnNpb24uZXBvY2gKLQotICBkZWYgcGFja2FnZShzZWxmKToKKyAgZGVmIGdl
dF92ZXJzaW9uKHNlbGYpOgorICAgICIiIlJldHVybiBhIFZlcnNpb24gb2JqZWN0IGZvciB0aGUg
bGFzdCB2ZXJzaW9uIiIiCisgICAgcmV0dXJuIHNlbGYuX2Jsb2Nrc1swXS52ZXJzaW9uCisKKyAg
ZGVmIHNldF92ZXJzaW9uKHNlbGYsIHZlcnNpb24pOgorICAgICIiIlNldCB0aGUgdmVyc2lvbiBv
ZiB0aGUgbGFzdCBjaGFuZ2Vsb2cgYmxvY2sKKworICAgIHZlcnNpb24gY2FuIGJlIGEgZnVsbCB2
ZXJzaW9uIHN0cmluZywgb3IgYSBWZXJzaW9uIG9iamVjdAorICAgICIiIgorICAgIHNlbGYuX2Js
b2Nrc1swXS52ZXJzaW9uID0gVmVyc2lvbih2ZXJzaW9uKQorCisgIHZlcnNpb24gPSBwcm9wZXJ0
eShnZXRfdmVyc2lvbiwgc2V0X3ZlcnNpb24sCisgICAgICAgICAgICAgICAgICAgICBkb2M9IlZl
cnNpb24gb2JqZWN0IGZvciBsYXN0IGNoYW5nZWxvZyBibG9jayIiIikKKworICAjIyMgRm9yIGNv
bnZlbmllbmNlLCBsZXQncyBleHBvc2Ugc29tZSBvZiB0aGUgdmVyc2lvbiBwcm9wZXJ0aWVzCisg
IGZ1bGxfdmVyc2lvbiA9IHByb3BlcnR5KGxhbWJkYSBzZWxmOiBzZWxmLnZlcnNpb24uZnVsbF92
ZXJzaW9uKQorICBkZWJpYW5fdmVyc2lvbiA9IHByb3BlcnR5KGxhbWJkYSBzZWxmOiBzZWxmLnZl
cnNpb24uZGViaWFuX3ZlcnNpb24pCisgIHVwc3RyZWFtX3ZlcnNpb24gPSBwcm9wZXJ0eShsYW1i
ZGEgc2VsZjogc2VsZi52ZXJzaW9uLnVwc3RyZWFtX3ZlcnNpb24pCisKKyAgZGVmIGdldF9wYWNr
YWdlKHNlbGYpOgogICAgICIiIlJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHBhY2thZ2UgaW4gdGhl
IGxhc3QgdmVyc2lvbi4iIiIKICAgICByZXR1cm4gc2VsZi5fYmxvY2tzWzBdLnBhY2thZ2UKLQot
ICBkZWYgdmVyc2lvbnMoc2VsZik6CisgIAorICBkZWYgc2V0X3BhY2thZ2Uoc2VsZiwgcGFja2Fn
ZSk6CisgICAgc2VsZi5fYmxvY2tzWzBdLnBhY2thZ2UgPSBwYWNrYWdlCisKKyAgcGFja2FnZSA9
IHByb3BlcnR5KGdldF9wYWNrYWdlLCBzZXRfcGFja2FnZSwKKyAgICAgICAgICAgICAgICAgICAg
IGRvYz0iTmFtZSBvZiB0aGUgcGFja2FnZSBpbiB0aGUgbGFzdCB2ZXJzaW9uIikKKworICBkZWYg
Z2V0X3ZlcnNpb25zKHNlbGYpOgogICAgICIiIlJldHVybnMgYSBsaXN0IG9mIHZlcnNpb24gb2Jq
ZWN0cyB0aGF0IHRoZSBwYWNrYWdlIHdlbnQgdGhyb3VnaC4iIiIKICAgICB2ZXJzaW9ucyA9IFtd
CiAgICAgZm9yIGJsb2NrIGluIHNlbGYuX2Jsb2NrczoKICAgICAgIHZlcnNpb25zLmFwcGVuZFti
bG9jay52ZXJzaW9uXQogICAgIHJldHVybiB2ZXJzaW9ucwogCisgIHZlcnNpb25zID0gcHJvcGVy
dHkoZ2V0X3ZlcnNpb25zLAorICAgICAgICAgICAgICAgICAgICAgIGRvYz0iTGlzdCBvZiB2ZXJz
aW9uIG9iamVjdHMgdGhlIHBhY2thZ2Ugd2VudCB0aHJvdWdoIikKKwogICBkZWYgX19zdHJfXyhz
ZWxmKToKICAgICBjbCA9ICIiCiAgICAgZm9yIGJsb2NrIGluIHNlbGYuX2Jsb2NrczoKICAgICAg
IGNsICs9IHN0cihibG9jaykKICAgICByZXR1cm4gY2wKIAotICBkZWYgc2V0X3BhY2thZ2Uoc2Vs
ZiwgcGFja2FnZSk6Ci0gICAgc2VsZi5fYmxvY2tzWzBdLnBhY2thZ2UgPSBwYWNrYWdlCi0KLSAg
ZGVmIHNldF92ZXJzaW9uKHNlbGYsIHZlcnNpb24pOgotICAgIHNlbGYuX2Jsb2Nrc1swXS52ZXJz
aW9uID0gdmVyc2lvbgotCiAgIGRlZiBzZXRfZGlzdHJpYnV0aW9ucyhzZWxmLCBkaXN0cmlidXRp
b25zKToKICAgICBzZWxmLl9ibG9ja3NbMF0uZGlzdHJpYnV0aW9ucyA9IGRpc3RyaWJ1dGlvbnMK
KyAgZGlzdHJpYnV0aW9ucyA9IHByb3BlcnR5KGxhbWJkYSBzZWxmOiBzZWxmLl9ibG9ja3NbMF0u
ZGlzdHJpYnV0aW9ucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldF9kaXN0cmlidXRp
b25zKQogCiAgIGRlZiBzZXRfdXJnZW5jeShzZWxmLCB1cmdlbmN5KToKICAgICBzZWxmLl9ibG9j
a3NbMF0udXJnZW5jeSA9IHVyZ2VuY3kKKyAgdXJnZW5jeSA9IHByb3BlcnR5KGxhbWJkYSBzZWxm
OiBzZWxmLl9ibG9ja3NbMF0udXJnZW5jeSwgc2V0X3VyZ2VuY3kpCiAKICAgZGVmIGFkZF9jaGFu
Z2Uoc2VsZiwgY2hhbmdlKToKICAgICBzZWxmLl9ibG9ja3NbMF0uYWRkX2NoYW5nZShjaGFuZ2Up
CiAKICAgZGVmIHNldF9hdXRob3Ioc2VsZiwgYXV0aG9yKToKICAgICBzZWxmLl9ibG9ja3NbMF0u
YXV0aG9yID0gYXV0aG9yCisgIGF1dGhvciA9IHByb3BlcnR5KGxhbWJkYSBzZWxmOiBzZWxmLl9i
bG9ja3NbMF0uYXV0aG9yLCBzZXRfYXV0aG9yKQogCiAgIGRlZiBzZXRfZGF0ZShzZWxmLCBkYXRl
KToKICAgICBzZWxmLl9ibG9ja3NbMF0uZGF0ZSA9IGRhdGUKKyAgZGF0ZSA9IHByb3BlcnR5KGxh
bWJkYSBzZWxmOiBzZWxmLl9ibG9ja3NbMF0uZGF0ZSwgc2V0X2RhdGUpCiAKICAgZGVmIG5ld19i
bG9jayhzZWxmLCBwYWNrYWdlPU5vbmUsIHZlcnNpb249Tm9uZSwgZGlzdHJpYnV0aW9ucz1Ob25l
LAogICAgICAgICAgICAgICAgIHVyZ2VuY3k9Tm9uZSwgY2hhbmdlcz1Ob25lLCBhdXRob3I9Tm9u
ZSwgZGF0ZT1Ob25lKToKCg==

# revision id: john at movingsucks.org-20061122052350-5253bb76e196f1dd
# sha1: bfe249f1f9855c395aaaa0b9e86934c9c866413c
# inventory sha1: cd461b20df5ec225a8f5483bfca16526c80391ad
# parent ids:
#   enrico at enricozini.org-20061120213648-cb925575bce6b414
# properties:
#   branch-nick: trunk



More information about the pkg-python-debian-discuss mailing list