Ignore:
Timestamp:
Mar 19, 2014, 11:11:30 AM (11 years ago)
Author:
dmik
Message:

python: Update vendor to 2.7.6.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • python/vendor/current/Lib/tarfile.py

    r2 r388  
    3131"""
    3232
    33 __version__ = "$Revision: 76386 $"
     33__version__ = "$Revision: 85213 $"
    3434# $Source$
    3535
    3636version     = "0.9.0"
    3737__author__  = "Lars Gustäbel (lars@gustaebel.de)"
    38 __date__    = "$Date: 2009-11-18 16:09:35 -0500 (Wed, 18 Nov 2009) $"
    39 __cvsid__   = "$Id: tarfile.py 76386 2009-11-18 21:09:35Z lars.gustaebel $"
     38__date__    = "$Date$"
     39__cvsid__   = "$Id$"
    4040__credits__ = "Gustavo Niemeyer, Niels Gustäbel, Richard Townsend."
    4141
     
    5454import operator
    5555
    56 if sys.platform == 'mac':
    57     # This module needs work for MacOS9, especially in the area of pathname
    58     # handling. In many places it is assumed a simple substitution of / by the
    59     # local os.path.sep is good enough to convert pathnames, but this does not
    60     # work with the mac rooted:path:name versus :nonrooted:path:name syntax
    61     raise ImportError, "tarfile does not work for platform==mac"
    62 
    6356try:
    6457    import grp, pwd
     
    196189            n = int(nts(s) or "0", 8)
    197190        except ValueError:
    198             raise HeaderError("invalid header")
     191            raise InvalidHeaderError("invalid header")
    199192    else:
    200193        n = 0L
     
    331324    return "".join(perm)
    332325
    333 if os.sep != "/":
    334     normpath = lambda path: os.path.normpath(path).replace(os.sep, "/")
    335 else:
    336     normpath = os.path.normpath
    337 
    338326class TarError(Exception):
    339327    """Base exception."""
     
    343331    pass
    344332class ReadError(TarError):
    345     """Exception for unreadble tar archives."""
     333    """Exception for unreadable tar archives."""
    346334    pass
    347335class CompressionError(TarError):
     
    352340    pass
    353341class HeaderError(TarError):
     342    """Base exception for header errors."""
     343    pass
     344class EmptyHeaderError(HeaderError):
     345    """Exception for empty headers."""
     346    pass
     347class TruncatedHeaderError(HeaderError):
     348    """Exception for truncated headers."""
     349    pass
     350class EOFHeaderError(HeaderError):
     351    """Exception for end of file headers."""
     352    pass
     353class InvalidHeaderError(HeaderError):
    354354    """Exception for invalid headers."""
     355    pass
     356class SubsequentHeaderError(HeaderError):
     357    """Exception for missing and invalid extended headers."""
    355358    pass
    356359
     
    371374        if hasattr(os, "O_BINARY"):
    372375            mode |= os.O_BINARY
    373         self.fd = os.open(name, mode)
     376        self.fd = os.open(name, mode, 0666)
    374377
    375378    def close(self):
     
    452455        timestamp = struct.pack("<L", long(time.time()))
    453456        self.__write("\037\213\010\010%s\002\377" % timestamp)
     457        if type(self.name) is unicode:
     458            self.name = self.name.encode("iso-8859-1", "replace")
    454459        if self.name.endswith(".gz"):
    455460            self.name = self.name[:-3]
     
    625630        if self.buf.startswith("\037\213\010"):
    626631            return "gz"
    627         if self.buf.startswith("BZh91"):
     632        if self.buf[0:3] == "BZh" and self.buf[4:10] == "1AY&SY":
    628633            return "bz2"
    629634        return "tar"
     
    666671            if not raw:
    667672                break
    668             try:
    669                 data = self.bz2obj.decompress(raw)
    670             except EOFError:
    671                 break
     673            data = self.bz2obj.decompress(raw)
    672674            b.append(data)
    673675            x += len(data)
     
    929931        self.type = REGTYPE     # member type
    930932        self.linkname = ""      # link name
    931         self.uname = "root"     # user name
    932         self.gname = "root"     # group name
     933        self.uname = ""         # user name
     934        self.gname = ""         # group name
    933935        self.devmajor = 0       # device major number
    934936        self.devminor = 0       # device minor number
     
    960962        """
    961963        info = {
    962             "name":     normpath(self.name),
     964            "name":     self.name,
    963965            "mode":     self.mode & 07777,
    964966            "uid":      self.uid,
     
    968970            "chksum":   self.chksum,
    969971            "type":     self.type,
    970             "linkname": normpath(self.linkname) if self.linkname else "",
     972            "linkname": self.linkname,
    971973            "uname":    self.uname,
    972974            "gname":    self.gname,
     
    11131115            stn(info.get("linkname", ""), 100),
    11141116            stn(info.get("magic", POSIX_MAGIC), 8),
    1115             stn(info.get("uname", "root"), 32),
    1116             stn(info.get("gname", "root"), 32),
     1117            stn(info.get("uname", ""), 32),
     1118            stn(info.get("gname", ""), 32),
    11171119            itn(info.get("devmajor", 0), 8, format),
    11181120            itn(info.get("devminor", 0), 8, format),
     
    11881190        """Construct a TarInfo object from a 512 byte string buffer.
    11891191        """
     1192        if len(buf) == 0:
     1193            raise EmptyHeaderError("empty header")
    11901194        if len(buf) != BLOCKSIZE:
    1191             raise HeaderError("truncated header")
     1195            raise TruncatedHeaderError("truncated header")
    11921196        if buf.count(NUL) == BLOCKSIZE:
    1193             raise HeaderError("empty header")
     1197            raise EOFHeaderError("end of file header")
    11941198
    11951199        chksum = nti(buf[148:156])
    11961200        if chksum not in calc_chksums(buf):
    1197             raise HeaderError("bad checksum")
     1201            raise InvalidHeaderError("bad checksum")
    11981202
    11991203        obj = cls()
     
    12341238        """
    12351239        buf = tarfile.fileobj.read(BLOCKSIZE)
    1236         if not buf:
    1237             return
    12381240        obj = cls.frombuf(buf)
    12391241        obj.offset = tarfile.fileobj.tell() - BLOCKSIZE
     
    12881290
    12891291        # Fetch the next header and process it.
    1290         next = self.fromtarfile(tarfile)
    1291         if next is None:
    1292             raise HeaderError("missing subsequent header")
     1292        try:
     1293            next = self.fromtarfile(tarfile)
     1294        except HeaderError:
     1295            raise SubsequentHeaderError("missing or bad subsequent header")
    12931296
    12941297        # Patch the TarInfo object from the next header with
     
    13951398
    13961399        # Fetch the next header.
    1397         next = self.fromtarfile(tarfile)
     1400        try:
     1401            next = self.fromtarfile(tarfile)
     1402        except HeaderError:
     1403            raise SubsequentHeaderError("missing or bad subsequent header")
    13981404
    13991405        if self.type in (XHDTYPE, SOLARIS_XHDTYPE):
    1400             if next is None:
    1401                 raise HeaderError("missing subsequent header")
    1402 
    14031406            # Patch the TarInfo object with the extended header info.
    14041407            next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors)
     
    14821485                                # continues processing.
    14831486
    1484     errorlevel = 0              # If 0, fatal errors only appear in debug
     1487    errorlevel = 1              # If 0, fatal errors only appear in debug
    14851488                                # messages (if debug >= 0). If > 0, errors
    14861489                                # are passed to the caller as exceptions.
     
    15741577                # Move to the end of the archive,
    15751578                # before the first empty block.
    1576                 self.firstmember = None
    15771579                while True:
    1578                     if self.next() is None:
    1579                         if self.offset > 0:
    1580                             self.fileobj.seek(- BLOCKSIZE, 1)
     1580                    self.fileobj.seek(self.offset)
     1581                    try:
     1582                        tarinfo = self.tarinfo.fromtarfile(self)
     1583                        self.members.append(tarinfo)
     1584                    except EOFHeaderError:
     1585                        self.fileobj.seek(self.offset)
    15811586                        break
     1587                    except HeaderError, e:
     1588                        raise ReadError(str(e))
    15821589
    15831590            if self.mode in "aw":
     
    17441751        try:
    17451752            t = cls.taropen(name, mode, fileobj, **kwargs)
    1746         except IOError:
     1753        except (IOError, EOFError):
    17471754            raise ReadError("not a bzip2 file")
    17481755        t._extfileobj = False
     
    18251832        if arcname is None:
    18261833            arcname = name
    1827         arcname = normpath(arcname)
    18281834        drv, arcname = os.path.splitdrive(arcname)
    1829         while arcname[0:1] == "/":
    1830             arcname = arcname[1:]
     1835        arcname = arcname.replace(os.sep, "/")
     1836        arcname = arcname.lstrip("/")
    18311837
    18321838        # Now, fill the TarInfo object with
     
    18811887        tarinfo.uid = statres.st_uid
    18821888        tarinfo.gid = statres.st_gid
    1883         if stat.S_ISREG(stmd):
     1889        if type == REGTYPE:
    18841890            tarinfo.size = statres.st_size
    18851891        else:
     
    19341940            print
    19351941
    1936     def add(self, name, arcname=None, recursive=True, exclude=None):
     1942    def add(self, name, arcname=None, recursive=True, exclude=None, filter=None):
    19371943        """Add the file `name' to the archive. `name' may be any type of file
    19381944           (directory, fifo, symbolic link, etc.). If given, `arcname'
     
    19401946           Directories are added recursively by default. This can be avoided by
    19411947           setting `recursive' to False. `exclude' is a function that should
    1942            return True for each filename to be excluded.
     1948           return True for each filename to be excluded. `filter' is a function
     1949           that expects a TarInfo object argument and returns the changed
     1950           TarInfo object, if it returns None the TarInfo object will be
     1951           excluded from the archive.
    19431952        """
    19441953        self._check("aw")
     
    19481957
    19491958        # Exclude pathnames.
    1950         if exclude is not None and exclude(name):
    1951             self._dbg(2, "tarfile: Excluded %r" % name)
    1952             return
     1959        if exclude is not None:
     1960            import warnings
     1961            warnings.warn("use the filter argument instead",
     1962                    DeprecationWarning, 2)
     1963            if exclude(name):
     1964                self._dbg(2, "tarfile: Excluded %r" % name)
     1965                return
    19531966
    19541967        # Skip if somebody tries to archive the archive...
     
    19571970            return
    19581971
    1959         # Special case: The user wants to add the current
    1960         # working directory.
    1961         if name == ".":
    1962             if recursive:
    1963                 if arcname == ".":
    1964                     arcname = ""
    1965                 for f in os.listdir(name):
    1966                     self.add(f, os.path.join(arcname, f), recursive, exclude)
    1967             return
    1968 
    19691972        self._dbg(1, name)
    19701973
     
    19761979            return
    19771980
     1981        # Change or exclude the TarInfo object.
     1982        if filter is not None:
     1983            tarinfo = filter(tarinfo)
     1984            if tarinfo is None:
     1985                self._dbg(2, "tarfile: Excluded %r" % name)
     1986                return
     1987
    19781988        # Append the tar header and data to the archive.
    19791989        if tarinfo.isreg():
    1980             f = bltn_open(name, "rb")
    1981             self.addfile(tarinfo, f)
    1982             f.close()
     1990            with bltn_open(name, "rb") as f:
     1991                self.addfile(tarinfo, f)
    19831992
    19841993        elif tarinfo.isdir():
     
    19861995            if recursive:
    19871996                for f in os.listdir(name):
    1988                     self.add(os.path.join(name, f), os.path.join(arcname, f), recursive, exclude)
     1997                    self.add(os.path.join(name, f), os.path.join(arcname, f),
     1998                            recursive, exclude, filter)
    19891999
    19902000        else:
     
    21192129            else:
    21202130                # A (sym)link's file object is its target's file object.
    2121                 return self.extractfile(self._getmember(tarinfo.linkname,
    2122                                                         tarinfo))
     2131                return self.extractfile(self._find_link_target(tarinfo))
    21232132        else:
    21242133            # If there's no data associated with the member (directory, chrdev,
     
    21332142        # and build the destination pathname, replacing
    21342143        # forward slashes to platform specific separators.
    2135         if targetpath[-1:] == "/":
    2136             targetpath = targetpath[:-1]
    2137         targetpath = os.path.normpath(targetpath)
     2144        targetpath = targetpath.rstrip("/")
     2145        targetpath = targetpath.replace("/", os.sep)
    21382146
    21392147        # Create all upper directories.
     
    21892197        """
    21902198        source = self.extractfile(tarinfo)
    2191         target = bltn_open(targetpath, "wb")
    2192         copyfileobj(source, target)
    2193         source.close()
    2194         target.close()
     2199        try:
     2200            with bltn_open(targetpath, "wb") as target:
     2201                copyfileobj(source, target)
     2202        finally:
     2203            source.close()
    21952204
    21962205    def makeunknown(self, tarinfo, targetpath):
     
    22302239          instead of a link.
    22312240        """
    2232         linkpath = tarinfo.linkname
    2233         try:
     2241        if hasattr(os, "symlink") and hasattr(os, "link"):
     2242            # For systems that support symbolic and hard links.
    22342243            if tarinfo.issym():
    2235                 os.symlink(linkpath, targetpath)
     2244                if os.path.lexists(targetpath):
     2245                    os.unlink(targetpath)
     2246                os.symlink(tarinfo.linkname, targetpath)
    22362247            else:
    22372248                # See extract().
    2238                 os.link(tarinfo._link_target, targetpath)
    2239         except AttributeError:
    2240             if tarinfo.issym():
    2241                 linkpath = os.path.join(os.path.dirname(tarinfo.name),
    2242                                         linkpath)
    2243                 linkpath = normpath(linkpath)
    2244 
     2249                if os.path.exists(tarinfo._link_target):
     2250                    if os.path.lexists(targetpath):
     2251                        os.unlink(targetpath)
     2252                    os.link(tarinfo._link_target, targetpath)
     2253                else:
     2254                    self._extract_member(self._find_link_target(tarinfo), targetpath)
     2255        else:
    22452256            try:
    2246                 self._extract_member(self.getmember(linkpath), targetpath)
    2247             except (EnvironmentError, KeyError), e:
    2248                 linkpath = os.path.normpath(linkpath)
    2249                 try:
    2250                     shutil.copy2(linkpath, targetpath)
    2251                 except EnvironmentError, e:
    2252                     raise IOError("link could not be created")
     2257                self._extract_member(self._find_link_target(tarinfo), targetpath)
     2258            except KeyError:
     2259                raise ExtractError("unable to resolve link inside archive")
    22532260
    22542261    def chown(self, tarinfo, targetpath):
     
    22602267                g = grp.getgrnam(tarinfo.gname)[2]
    22612268            except KeyError:
    2262                 try:
    2263                     g = grp.getgrgid(tarinfo.gid)[2]
    2264                 except KeyError:
    2265                     g = os.getgid()
     2269                g = tarinfo.gid
    22662270            try:
    22672271                u = pwd.getpwnam(tarinfo.uname)[2]
    22682272            except KeyError:
    2269                 try:
    2270                     u = pwd.getpwuid(tarinfo.uid)[2]
    2271                 except KeyError:
    2272                     u = os.getuid()
     2273                u = tarinfo.uid
    22732274            try:
    22742275                if tarinfo.issym() and hasattr(os, "lchown"):
     
    23132314        # Read the next block.
    23142315        self.fileobj.seek(self.offset)
     2316        tarinfo = None
    23152317        while True:
    23162318            try:
    23172319                tarinfo = self.tarinfo.fromtarfile(self)
    2318                 if tarinfo is None:
    2319                     return
    2320                 self.members.append(tarinfo)
    2321 
    2322             except HeaderError, e:
     2320            except EOFHeaderError, e:
    23232321                if self.ignore_zeros:
    23242322                    self._dbg(2, "0x%X: %s" % (self.offset, e))
    23252323                    self.offset += BLOCKSIZE
    23262324                    continue
    2327                 else:
    2328                     if self.offset == 0:
    2329                         raise ReadError(str(e))
    2330                     return None
     2325            except InvalidHeaderError, e:
     2326                if self.ignore_zeros:
     2327                    self._dbg(2, "0x%X: %s" % (self.offset, e))
     2328                    self.offset += BLOCKSIZE
     2329                    continue
     2330                elif self.offset == 0:
     2331                    raise ReadError(str(e))
     2332            except EmptyHeaderError:
     2333                if self.offset == 0:
     2334                    raise ReadError("empty file")
     2335            except TruncatedHeaderError, e:
     2336                if self.offset == 0:
     2337                    raise ReadError(str(e))
     2338            except SubsequentHeaderError, e:
     2339                raise ReadError(str(e))
    23312340            break
     2341
     2342        if tarinfo is not None:
     2343            self.members.append(tarinfo)
     2344        else:
     2345            self._loaded = True
    23322346
    23332347        return tarinfo
     
    23362350    # Little helper methods:
    23372351
    2338     def _getmember(self, name, tarinfo=None):
     2352    def _getmember(self, name, tarinfo=None, normalize=False):
    23392353        """Find an archive member by name from bottom to top.
    23402354           If tarinfo is given, it is used as the starting point.
     
    23432357        members = self.getmembers()
    23442358
    2345         if tarinfo is None:
    2346             end = len(members)
    2347         else:
    2348             end = members.index(tarinfo)
    2349 
    2350         for i in xrange(end - 1, -1, -1):
    2351             if name == members[i].name:
    2352                 return members[i]
     2359        # Limit the member search list up to tarinfo.
     2360        if tarinfo is not None:
     2361            members = members[:members.index(tarinfo)]
     2362
     2363        if normalize:
     2364            name = os.path.normpath(name)
     2365
     2366        for member in reversed(members):
     2367            if normalize:
     2368                member_name = os.path.normpath(member.name)
     2369            else:
     2370                member_name = member.name
     2371
     2372            if name == member_name:
     2373                return member
    23532374
    23542375    def _load(self):
     
    23712392            raise IOError("bad operation for mode %r" % self.mode)
    23722393
     2394    def _find_link_target(self, tarinfo):
     2395        """Find the target member of a symlink or hardlink member in the
     2396           archive.
     2397        """
     2398        if tarinfo.issym():
     2399            # Always search the entire archive.
     2400            linkname = "/".join(filter(None, (os.path.dirname(tarinfo.name), tarinfo.linkname)))
     2401            limit = None
     2402        else:
     2403            # Search the archive before the link, because a hard link is
     2404            # just a reference to an already archived file.
     2405            linkname = tarinfo.linkname
     2406            limit = tarinfo
     2407
     2408        member = self._getmember(linkname, tarinfo=limit, normalize=True)
     2409        if member is None:
     2410            raise KeyError("linkname %r not found" % linkname)
     2411        return member
     2412
    23732413    def __iter__(self):
    23742414        """Provide an iterator object.
     
    23842424        if level <= self.debug:
    23852425            print >> sys.stderr, msg
     2426
     2427    def __enter__(self):
     2428        self._check()
     2429        return self
     2430
     2431    def __exit__(self, type, value, traceback):
     2432        if type is None:
     2433            self.close()
     2434        else:
     2435            # An exception occurred. We must not call close() because
     2436            # it would try to write end-of-archive blocks and padding.
     2437            if not self._extfileobj:
     2438                self.fileobj.close()
     2439            self.closed = True
    23862440# class TarFile
    23872441
     
    24092463        # happen that getmembers() is called during iteration,
    24102464        # which will cause TarIter to stop prematurely.
    2411         if not self.tarfile._loaded:
     2465
     2466        if self.index == 0 and self.tarfile.firstmember is not None:
     2467            tarinfo = self.tarfile.next()
     2468        elif self.index < len(self.tarfile.members):
     2469            tarinfo = self.tarfile.members[self.index]
     2470        elif not self.tarfile._loaded:
    24122471            tarinfo = self.tarfile.next()
    24132472            if not tarinfo:
     
    24152474                raise StopIteration
    24162475        else:
    2417             try:
    2418                 tarinfo = self.tarfile.members[self.index]
    2419             except IndexError:
    2420                 raise StopIteration
     2476            raise StopIteration
    24212477        self.index += 1
    24222478        return tarinfo
Note: See TracChangeset for help on using the changeset viewer.