[Pkg-python-debian-commits] r73 trunk: - support both the (buggy) file naming scheme for TarFile of python << 2.5

Stefano Zacchiroli zack at bononia.it
Sat Aug 18 15:25:26 UTC 2007


------------------------------------------------------------
revno: 73
committer: Stefano Zacchiroli <zack at bononia.it>
branch nick: pkg-python-debian
timestamp: Sat 2007-08-18 17:25:26 +0200
message:
    - support both the (buggy) file naming scheme for TarFile of python << 2.5
      (e.g. "control") and of python >= 2.5 (e.g. "./control"). In addition,
      enable users to specify file members in three equivalent formats:
      "file", "./file", and "/file" (closes: #438603)
modified:
  debian/changelog
  debian_bundle/debfile.py
  debian_bundle/test_debfile.py
-------------- next part --------------
=== modified file 'debian/changelog'
--- a/debian/changelog	2007-08-17 13:03:32 +0000
+++ b/debian/changelog	2007-08-18 15:25:26 +0000
@@ -5,8 +5,12 @@
     - do not fail if extra ar members exist in a .deb, according to deb(5)
       extra ar members should be ignored (closes: #438486). Also add the
       corresponding regression test to test_debfile.py
+    - support both the (buggy) file naming scheme for TarFile of python << 2.5
+      (e.g. "control") and of python >= 2.5 (e.g. "./control"). In addition,
+      enable users to specify file members in three equivalent formats:
+      "file", "./file", and "/file" (closes: #438603)
 
- -- Stefano Zacchiroli <zack at debian.org>  Fri, 17 Aug 2007 14:59:34 +0200
+ -- Stefano Zacchiroli <zack at debian.org>  Sat, 18 Aug 2007 17:20:44 +0200
 
 python-debian (0.1.4) unstable; urgency=low
 

=== modified file 'debian_bundle/debfile.py'
--- a/debian_bundle/debfile.py	2007-08-17 13:03:32 +0000
+++ b/debian_bundle/debfile.py	2007-08-18 15:25:26 +0000
@@ -34,6 +34,7 @@
 CHANGELOG_DEBIAN = 'usr/share/doc/%s/changelog.Debian.gz'
 MD5_FILE = 'md5sums'
 
+
 class DebError(ArError):
     pass
 
@@ -43,7 +44,16 @@
     
     A .deb package is considered as made of 2 parts: a 'data' part
     (corresponding to the 'data.tar.gz' archive embedded in a .deb) and a
-    'control' part (the 'control.tar.gz' archive)."""
+    'control' part (the 'control.tar.gz' archive). Each of them is represented
+    by an instance of this class.
+
+    When referring to file members of the underlying .tar.gz archive, file
+    names can be specified in one of 3 formats "file", "./file", "/file". In
+    all cases the file is considered relative to the root of the archive. For
+    the control part the preferred mechanism is the first one (as in
+    deb.control.get_content('control') ); for the data part the preferred
+    mechanism is the third one (as in deb.data.get_file('/etc/vim/vimrc') ).
+    """
 
     def __init__(self, member):
         self.__member = member  # arfile.ArMember file member
@@ -58,21 +68,45 @@
             self.__tgz = tarfile.TarFile(fileobj=gz, mode='r')
         return self.__tgz
 
+    @staticmethod
+    def __normalize_member(fname):
+        """ try (not so hard) to obtain a member file name in a form relative
+        to the .tar.gz root and with no heading '.' """
+
+        if fname.startswith('./'):
+            fname = fname[2:]
+        elif fname.startswith('/'):
+            fname = fname[1:]
+        return fname
+
+    # XXX in some of the following methods, compatibility among >= 2.5 and <<
+    # 2.5 python versions had to be taken into account. TarFile << 2.5 indeed
+    # was buggied and returned member file names with an heading './' only for
+    # the *first* file member. TarFile >= 2.5 fixed this and has the heading
+    # './' for all file members.
+
     def has_file(self, fname):
         """Check if this part contains a given file name."""
 
-        return (fname in self.tgz().getnames())
+        fname = DebPart.__normalize_member(fname)
+        names = self.tgz().getnames()
+        return (('./' + fname in names) \
+                or (fname in names)) # XXX python << 2.5 TarFile compatibility
 
     def get_file(self, fname):
         """Return a file object corresponding to a given file name."""
 
-        return (self.tgz().extractfile(fname))
+        fname = DebPart.__normalize_member(fname)
+        try:
+            return (self.tgz().extractfile('./' + fname))
+        except KeyError:    # XXX python << 2.5 TarFile compatibility
+            return (self.tgz().extractfile(fname))
 
     def get_content(self, fname):
         """Return the string content of a given file, or None (e.g. for
         directories)."""
 
-        f = self.tgz().extractfile(fname)
+        f = self.get_file(fname)
         content = None
         if f:   # can be None for non regular or link files
             content = f.read()
@@ -95,6 +129,7 @@
 
     pass
 
+
 class DebControl(DebPart):
 
     def scripts(self):
@@ -133,6 +168,7 @@
         md5_file.close()
         return sums
 
+
 class DebFile(ArFile):
     """Representation of a .deb file (a Debian binary package)
 
@@ -201,6 +237,7 @@
                 return Changelog(raw_changelog)
         return None
 
+
 if __name__ == '__main__':
     import sys
     deb = DebFile(filename=sys.argv[1])

=== modified file 'debian_bundle/test_debfile.py'
--- a/debian_bundle/test_debfile.py	2007-08-17 13:03:32 +0000
+++ b/debian_bundle/test_debfile.py	2007-08-18 15:25:26 +0000
@@ -19,6 +19,7 @@
 
 import unittest
 import os
+import re
 import stat
 import sys
 import tempfile
@@ -128,14 +129,16 @@
 
     def test_data_names(self):
         """ test for file list equality """ 
+        strip_dot_slash = lambda s: re.sub(r'^\./', '', s)
         tgz = self.d.data.tgz()
-        filelist = [ x.strip()[2:] # remove "./"
-                for x in
-                os.popen("dpkg-deb --fsys-tarfile %s | tar t" %
-                    self.debname).readlines() ]
+        dpkg_names = map(strip_dot_slash,
+                [ x.strip() for x in
+                    os.popen("dpkg-deb --fsys-tarfile %s | tar t" %
+                        self.debname).readlines() ])
+        debfile_names = map(strip_dot_slash, tgz.getnames())
         
         # skip the root
-        self.assertEqual(tgz.getnames()[1:], filelist[1:])
+        self.assertEqual(debfile_names[1:], dpkg_names[1:])
 
     def test_control(self):
         """ test for control equality """



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