New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bpo-39717: [tarfile] update nested exception raising #23739
Conversation
- `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
Outdated
| @@ -214,7 +215,7 @@ def itn(n, digits=8, format=DEFAULT_FORMAT): | |||
| s.insert(1, n & 0o377) | |||
| n >>= 8 | |||
| else: | |||
| raise ValueError("overflow in number field") | |||
| raise ValueError("overflow in number field processing %r as %r" % (original_n, format)) | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think it is useful. It would be more helpful to report which kind of value (size, mtime, etc) is overflowed instead of just its numerical value without connection to the name, but this information is not available here. format is not informative either. It is an integer 0 to 2, and the user usually know what format is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some future date I hope to make format a symbolic constant similar to Enum. I agree that "kind" would be more useful, but that would be a bigger change than I am ready to do at the moment.
| @@ -1533,7 +1534,7 @@ def __init__(self, name=None, mode="r", fileobj=None, format=None, | |||
| self.fileobj.seek(self.offset) | |||
| break | |||
| except HeaderError as e: | |||
| raise ReadError(str(e)) | |||
| raise ReadError(str(e)) from None | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why from None? It can remove useful information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The str(e) should be preserving the useful bits, while from None alters the traceback to indicate that the error handler is not broken.
Lib/tarfile.py
Outdated
| except HeaderError: | ||
| raise SubsequentHeaderError("missing or bad subsequent header") | ||
| except HeaderError as exc: | ||
| raise SubsequentHeaderError(str(exc)) from None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HeaderError is generic (could be any of EmptyHeaderError, TruncatedHeaderError, EOFHeaderError, InvalidHeaderError, or even SubsequentHeaderError) and the specific error could be useful, so I'm saving the text from the specific error when converting to SubsequentHeaderError.
I do need to go back and change as exc to as e to match the rest of module.
|
|
||
| try: | ||
| fileobj = GzipFile(name, mode + "b", compresslevel, fileobj) | ||
| except OSError: | ||
| except OSError as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not it be more specific BadGzipFile and additionally EOFError?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so -- both of those are more specific and more informative than ReadError.
| if fileobj is not None and mode == 'r': | ||
| raise ReadError("not a gzip file") | ||
| raise ReadError("not a gzip file") from e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why set __cause__? The initial exception is already linked as __context__.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the traceback correctly identifies that the first exception is the cause, and the second (current) exception is not a bug in the exception handler.
|
Thanks, Serhiy! |
- `from None` if the new exception uses, or doesn't need, the previous one - `from e` if the previous exception is still relevant
from Noneif the new exception uses, or doesn't need, the previous onefrom eif the previous exception is still relevanthttps://bugs.python.org/issue39717