]> granicus.if.org Git - python/commitdiff
Patch #1043890: tarfile: add extractall() method.
authorMartin v. Löwis <martin@v.loewis.de>
Fri, 4 Mar 2005 19:40:34 +0000 (19:40 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Fri, 4 Mar 2005 19:40:34 +0000 (19:40 +0000)
Doc/lib/libtarfile.tex
Lib/tarfile.py
Misc/NEWS

index f7800ded2dc43b65187be7e64a94c320759370b7..018e8b93afc420aa42e3ef2f8ebfe45c88df27d5 100644 (file)
@@ -196,12 +196,29 @@ tar archive several times. Each archive member is represented by a
     more available.
 \end{methoddesc}
 
+\begin{methoddesc}{extractall}{\optional{path\optional{, members}}}
+    Extract all members from the archive to the current working directory
+    or directory \var{path}. If optional \var{members} is given, it must be
+    a subset of the list returned by \method{getmembers()}.
+    Directory informations like owner, modification time and permissions are
+    set after all members have been extracted. This is done to work around two
+    problems: A directory's modification time is reset each time a file is
+    created in it. And, if a directory's permissions do not allow writing,
+    extracting files to it will fail.
+    \versionadded{2.5}
+\end{methoddesc}
+
 \begin{methoddesc}{extract}{member\optional{, path}}
     Extract a member from the archive to the current working directory,
     using its full name. Its file information is extracted as accurately as
     possible.
     \var{member} may be a filename or a \class{TarInfo} object.
     You can specify a different directory using \var{path}.
+    \begin{notice}
+    Because the \method{extract()} method allows random access to a tar
+    archive there are some issues you must take care of yourself. See the
+    description for \method{extractall()} above.
+    \end{notice}
 \end{methoddesc}
 
 \begin{methoddesc}{extractfile}{member}
@@ -416,6 +433,14 @@ A \class{TarInfo} object also provides some convenient query methods:
 
 \subsection{Examples \label{tar-examples}}
 
+How to extract an entire tar archive to the current working directory:
+\begin{verbatim}
+import tarfile
+tar = tarfile.open("sample.tar.gz")
+tar.extractall()
+tar.close()
+\end{verbatim}
+
 How to create an uncompressed tar archive from a list of filenames:
 \begin{verbatim}
 import tarfile
index 06f3ab35d012c37002d0dbecc8e08ebe17d848b0..8bce5d007542b7704efc4e87cb22324a36c802ac 100644 (file)
@@ -1321,6 +1321,47 @@ class TarFile(object):
 
         self.members.append(tarinfo)
 
+    def extractall(self, path=".", members=None):
+        """Extract all members from the archive to the current working
+           directory and set owner, modification time and permissions on
+           directories afterwards. `path' specifies a different directory
+           to extract to. `members' is optional and must be a subset of the
+           list returned by getmembers().
+        """
+        directories = []
+
+        if members is None:
+            members = self
+
+        for tarinfo in members:
+            if tarinfo.isdir():
+                # Extract directory with a safe mode, so that
+                # all files below can be extracted as well.
+                try:
+                    os.makedirs(os.path.join(path, tarinfo.name), 0777)
+                except EnvironmentError:
+                    pass
+                directories.append(tarinfo)
+            else:
+                self.extract(tarinfo, path)
+
+        # Reverse sort directories.
+        directories.sort(lambda a, b: cmp(a.name, b.name))
+        directories.reverse()
+
+        # Set correct owner, mtime and filemode on directories.
+        for tarinfo in directories:
+            path = os.path.join(path, tarinfo.name)
+            try:
+                self.chown(tarinfo, path)
+                self.utime(tarinfo, path)
+                self.chmod(tarinfo, path)
+            except ExtractError, e:
+                if self.errorlevel > 1:
+                    raise
+                else:
+                    self._dbg(1, "tarfile: %s" % e)
+
     def extract(self, member, path=""):
         """Extract a member from the archive to the current working directory,
            using its full name. Its file information is extracted as accurately
index 9f7dbddec95e19921c5527e1de8625983e9b303f..59c630dd00fc3c735364aca6817ab96bd3476bd2 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -75,6 +75,8 @@ Extension Modules
 Library
 -------
 
+- Patch #1043890: Add extractall method to tarfile.
+
 - Patch #1075887: Don't require MSVC in distutils if there is nothing
   to build.