From b5a6db9111562454617b6771b61f2734ea0420c9 Mon Sep 17 00:00:00 2001 From: Ethan Furman Date: Sat, 12 Dec 2020 13:26:44 -0800 Subject: bpo-39717: [tarfile] update nested exception raising (GH-23739) - `from None` if the new exception uses, or doesn't need, the previous one - `from e` if the previous exception is still relevant --- Lib/tarfile.py | 65 +++++++++++----------- .../2020-12-10-18-36-52.bpo-39717.sK2u0w.rst | 1 + 2 files changed, 34 insertions(+), 32 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-12-10-18-36-52.bpo-39717.sK2u0w.rst diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 1d15612..395c0f1 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -200,6 +200,7 @@ def itn(n, digits=8, format=DEFAULT_FORMAT): # base-256 representation. This allows values up to (256**(digits-1))-1. # A 0o200 byte indicates a positive number, a 0o377 byte a negative # number. + original_n = n n = int(n) if 0 <= n < 8 ** (digits - 1): s = bytes("%0*o" % (digits - 1, n), "ascii") + NUL @@ -363,7 +364,7 @@ class _Stream: try: import zlib except ImportError: - raise CompressionError("zlib module is not available") + raise CompressionError("zlib module is not available") from None self.zlib = zlib self.crc = zlib.crc32(b"") if mode == "r": @@ -376,7 +377,7 @@ class _Stream: try: import bz2 except ImportError: - raise CompressionError("bz2 module is not available") + raise CompressionError("bz2 module is not available") from None if mode == "r": self.dbuf = b"" self.cmp = bz2.BZ2Decompressor() @@ -388,7 +389,7 @@ class _Stream: try: import lzma except ImportError: - raise CompressionError("lzma module is not available") + raise CompressionError("lzma module is not available") from None if mode == "r": self.dbuf = b"" self.cmp = lzma.LZMADecompressor() @@ -541,8 +542,8 @@ class _Stream: break try: buf = self.cmp.decompress(buf) - except self.exception: - raise ReadError("invalid compressed data") + except self.exception as e: + raise ReadError("invalid compressed data") from e t.append(buf) c += len(buf) t = b"".join(t) @@ -1164,8 +1165,8 @@ class TarInfo(object): # Fetch the next header and process it. try: next = self.fromtarfile(tarfile) - except HeaderError: - raise SubsequentHeaderError("missing or bad subsequent header") + except HeaderError as e: + raise SubsequentHeaderError(str(e)) from None # Patch the TarInfo object from the next header with # the longname information. @@ -1277,8 +1278,8 @@ class TarInfo(object): # Fetch the next header. try: next = self.fromtarfile(tarfile) - except HeaderError: - raise SubsequentHeaderError("missing or bad subsequent header") + except HeaderError as e: + raise SubsequentHeaderError(str(e)) from None # Process GNU sparse information. if "GNU.sparse.map" in pax_headers: @@ -1533,7 +1534,7 @@ class TarFile(object): self.fileobj.seek(self.offset) break except HeaderError as e: - raise ReadError(str(e)) + raise ReadError(str(e)) from None if self.mode in ("a", "w", "x"): self._loaded = True @@ -1669,21 +1670,21 @@ class TarFile(object): try: from gzip import GzipFile except ImportError: - raise CompressionError("gzip module is not available") + raise CompressionError("gzip module is not available") from None try: fileobj = GzipFile(name, mode + "b", compresslevel, fileobj) - except OSError: + except OSError as e: if fileobj is not None and mode == 'r': - raise ReadError("not a gzip file") + raise ReadError("not a gzip file") from e raise try: t = cls.taropen(name, mode, fileobj, **kwargs) - except OSError: + except OSError as e: fileobj.close() if mode == 'r': - raise ReadError("not a gzip file") + raise ReadError("not a gzip file") from e raise except: fileobj.close() @@ -1702,16 +1703,16 @@ class TarFile(object): try: from bz2 import BZ2File except ImportError: - raise CompressionError("bz2 module is not available") + raise CompressionError("bz2 module is not available") from None fileobj = BZ2File(fileobj or name, mode, compresslevel=compresslevel) try: t = cls.taropen(name, mode, fileobj, **kwargs) - except (OSError, EOFError): + except (OSError, EOFError) as e: fileobj.close() if mode == 'r': - raise ReadError("not a bzip2 file") + raise ReadError("not a bzip2 file") from e raise except: fileobj.close() @@ -1730,16 +1731,16 @@ class TarFile(object): try: from lzma import LZMAFile, LZMAError except ImportError: - raise CompressionError("lzma module is not available") + raise CompressionError("lzma module is not available") from None fileobj = LZMAFile(fileobj or name, mode, preset=preset) try: t = cls.taropen(name, mode, fileobj, **kwargs) - except (LZMAError, EOFError): + except (LZMAError, EOFError) as e: fileobj.close() if mode == 'r': - raise ReadError("not an lzma file") + raise ReadError("not an lzma file") from e raise except: fileobj.close() @@ -2253,7 +2254,7 @@ class TarFile(object): self._extract_member(self._find_link_target(tarinfo), targetpath) except KeyError: - raise ExtractError("unable to resolve link inside archive") + raise ExtractError("unable to resolve link inside archive") from None def chown(self, tarinfo, targetpath, numeric_owner): """Set owner of targetpath according to tarinfo. If numeric_owner @@ -2281,16 +2282,16 @@ class TarFile(object): os.lchown(targetpath, u, g) else: os.chown(targetpath, u, g) - except OSError: - raise ExtractError("could not change owner") + except OSError as e: + raise ExtractError("could not change owner") from e def chmod(self, tarinfo, targetpath): """Set file permissions of targetpath according to tarinfo. """ try: os.chmod(targetpath, tarinfo.mode) - except OSError: - raise ExtractError("could not change mode") + except OSError as e: + raise ExtractError("could not change mode") from e def utime(self, tarinfo, targetpath): """Set modification time of targetpath according to tarinfo. @@ -2299,8 +2300,8 @@ class TarFile(object): return try: os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) - except OSError: - raise ExtractError("could not change modification time") + except OSError as e: + raise ExtractError("could not change modification time") from e #-------------------------------------------------------------------------- def next(self): @@ -2336,15 +2337,15 @@ class TarFile(object): self.offset += BLOCKSIZE continue elif self.offset == 0: - raise ReadError(str(e)) + raise ReadError(str(e)) from None except EmptyHeaderError: if self.offset == 0: - raise ReadError("empty file") + raise ReadError("empty file") from None except TruncatedHeaderError as e: if self.offset == 0: - raise ReadError(str(e)) + raise ReadError(str(e)) from None except SubsequentHeaderError as e: - raise ReadError(str(e)) + raise ReadError(str(e)) from None break if tarinfo is not None: diff --git a/Misc/NEWS.d/next/Library/2020-12-10-18-36-52.bpo-39717.sK2u0w.rst b/Misc/NEWS.d/next/Library/2020-12-10-18-36-52.bpo-39717.sK2u0w.rst new file mode 100644 index 0000000..fcbf999 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-12-10-18-36-52.bpo-39717.sK2u0w.rst @@ -0,0 +1 @@ +[tarfile] update nested exception raising to use `from None` or `from e` -- cgit v0.12