[Python-checkins] r53648 - in python/trunk: Doc/lib/libtarfile.tex Lib/tarfile.py Lib/test/test_tarfile.py Misc/NEWS

lars.gustaebel python-checkins at python.org
Tue Feb 6 19:38:15 CET 2007


Author: lars.gustaebel
Date: Tue Feb  6 19:38:13 2007
New Revision: 53648

Modified:
   python/trunk/Doc/lib/libtarfile.tex
   python/trunk/Lib/tarfile.py
   python/trunk/Lib/test/test_tarfile.py
   python/trunk/Misc/NEWS
Log:
Patch #1652681: create nonexistent files in append mode and
allow appending to empty files.



Modified: python/trunk/Doc/lib/libtarfile.tex
==============================================================================
--- python/trunk/Doc/lib/libtarfile.tex	(original)
+++ python/trunk/Doc/lib/libtarfile.tex	Tue Feb  6 19:38:13 2007
@@ -36,7 +36,8 @@
     \lineii{'r:'}{Open for reading exclusively without compression.}
     \lineii{'r:gz'}{Open for reading with gzip compression.}
     \lineii{'r:bz2'}{Open for reading with bzip2 compression.}
-    \lineii{'a' or 'a:'}{Open for appending with no compression.}
+    \lineii{'a' or 'a:'}{Open for appending with no compression. The file
+        is created if it does not exist.}
     \lineii{'w' or 'w:'}{Open for uncompressed writing.}
     \lineii{'w:gz'}{Open for gzip compressed writing.}
     \lineii{'w:bz2'}{Open for bzip2 compressed writing.}

Modified: python/trunk/Lib/tarfile.py
==============================================================================
--- python/trunk/Lib/tarfile.py	(original)
+++ python/trunk/Lib/tarfile.py	Tue Feb  6 19:38:13 2007
@@ -1060,6 +1060,10 @@
         self.mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode]
 
         if not fileobj:
+            if self._mode == "a" and not os.path.exists(self.name):
+                # Create nonexistent files in append mode.
+                self._mode = "w"
+                self.mode = "wb"
             fileobj = file(self.name, self.mode)
             self._extfileobj = False
         else:
@@ -1093,7 +1097,8 @@
                     self.fileobj.seek(0)
                     break
                 if tarinfo is None:
-                    self.fileobj.seek(- BLOCKSIZE, 1)
+                    if self.offset > 0:
+                        self.fileobj.seek(- BLOCKSIZE, 1)
                     break
 
         if self._mode in "aw":
@@ -1120,7 +1125,7 @@
            'r:'         open for reading exclusively uncompressed
            'r:gz'       open for reading with gzip compression
            'r:bz2'      open for reading with bzip2 compression
-           'a' or 'a:'  open for appending
+           'a' or 'a:'  open for appending, creating the file if necessary
            'w' or 'w:'  open for writing without compression
            'w:gz'       open for writing with gzip compression
            'w:bz2'      open for writing with bzip2 compression

Modified: python/trunk/Lib/test/test_tarfile.py
==============================================================================
--- python/trunk/Lib/test/test_tarfile.py	(original)
+++ python/trunk/Lib/test/test_tarfile.py	Tue Feb  6 19:38:13 2007
@@ -305,6 +305,61 @@
         self.assertEqual(self.dst.getnames(), [], "added the archive to itself")
 
 
+class AppendTest(unittest.TestCase):
+    # Test append mode (cp. patch #1652681).
+
+    def setUp(self):
+        self.tarname = tmpname()
+        if os.path.exists(self.tarname):
+            os.remove(self.tarname)
+
+    def _add_testfile(self, fileobj=None):
+        tar = tarfile.open(self.tarname, "a", fileobj=fileobj)
+        tar.addfile(tarfile.TarInfo("bar"))
+        tar.close()
+
+    def _create_testtar(self):
+        src = tarfile.open(tarname())
+        t = src.getmember("0-REGTYPE")
+        t.name = "foo"
+        f = src.extractfile(t)
+        tar = tarfile.open(self.tarname, "w")
+        tar.addfile(t, f)
+        tar.close()
+
+    def _test(self, names=["bar"], fileobj=None):
+        tar = tarfile.open(self.tarname, fileobj=fileobj)
+        self.assert_(tar.getnames() == names)
+
+    def test_non_existing(self):
+        self._add_testfile()
+        self._test()
+
+    def test_empty(self):
+        open(self.tarname, "w").close()
+        self._add_testfile()
+        self._test()
+
+    def test_empty_fileobj(self):
+        fobj = StringIO.StringIO()
+        self._add_testfile(fobj)
+        fobj.seek(0)
+        self._test(fileobj=fobj)
+
+    def test_fileobj(self):
+        self._create_testtar()
+        data = open(self.tarname).read()
+        fobj = StringIO.StringIO(data)
+        self._add_testfile(fobj)
+        fobj.seek(0)
+        self._test(names=["foo", "bar"], fileobj=fobj)
+
+    def test_existing(self):
+        self._create_testtar()
+        self._add_testfile()
+        self._test(names=["foo", "bar"])
+
+
 class Write100Test(BaseTest):
     # The name field in a tar header stores strings of at most 100 chars.
     # If a string is shorter than 100 chars it has to be padded with '\0',
@@ -711,6 +766,7 @@
         ReadAsteriskTest,
         ReadStreamAsteriskTest,
         WriteTest,
+        AppendTest,
         Write100Test,
         WriteSize0Test,
         WriteStreamTest,

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Tue Feb  6 19:38:13 2007
@@ -126,6 +126,9 @@
 Library
 -------
 
+- Patch #1652681: tarfile.py: create nonexistent files in append mode and
+  allow appending to empty files.
+
 - Bug #1124861: Automatically create pipes if GetStdHandle fails in
   subprocess. 
 


More information about the Python-checkins mailing list