-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
Exception context set to string by BufferedWriter.close() #65876
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
Comments
I made a writer class whose write() and flush() methods (unintentionally) triggered exceptions. I wrapped this in a BufferedWriter. When close() is called, the resulting exception has a string object in its __context__ attribute. Although the original error was my fault, it created a confusing chain reaction of exception reports. >>> from io import BufferedWriter, RawIOBase
>>> import sys
>>>
>>> class BuggyWriter(RawIOBase):
... def writable(self): return True
... def write(self, b): in_write # Initial exception
... def flush(self): raise Exception("In flush()")
...
>>> output = BufferedWriter(BuggyWriter())
>>> output.write(b"data")
4
>>> output.close() # Note the TypeError printed at the top
TypeError: print_exception(): Exception expected for value, str found
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in flush
Exception: In flush()
>>>
>>> sys.last_value
Exception('In flush()',)
>>> sys.last_value.__context__ # Should be exception, not string object
"name 'in_write' is not defined"
>>>
>>> import traceback
>>> traceback.print_exception(sys.last_type, sys.last_value, sys.last_traceback)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/traceback.py", line 169, in print_exception
for line in _format_exception_iter(etype, value, tb, limit, chain):
File "/usr/lib/python3.4/traceback.py", line 146, in _format_exception_iter
for value, tb in values:
File "/usr/lib/python3.4/traceback.py", line 138, in _iter_chain
yield from it
File "/usr/lib/python3.4/traceback.py", line 125, in _iter_chain
context = exc.__context__
AttributeError: 'str' object has no attribute '__context__' |
Here is a patch. It fixes also the same error in TextIOWrapper. |
New changeset a3b7b89da34f by Serhiy Storchaka in branch '3.4': New changeset d6ac4b6020b9 by Serhiy Storchaka in branch 'default': |
Thank you Martin for your report. |
This changeset crashes test_io here: test_close_error_on_close (test.test_io.CBufferedReaderTest) ... python: Objects/abstract.c:2091: PyObject_Call: Assertion `(result != ((void *)0) && !PyErr_Occurred()) || (result == ((void *)0) && PyErr_Occurred())' failed. Current thread 0x00007ff1b3264740 (most recent call first): |
gdb backtrace: #0 0x00007ffff711ff79 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007ffff7123388 in __GI_abort () at abort.c:89
#2 0x00007ffff7118e36 in __assert_fail_base (fmt=0x7ffff726a718 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
assertion=assertion@entry=0x670d48 "(result != ((void *)0) && !PyErr_Occurred()) || (result == ((void *)0) && PyErr_Occurred())", file=file@entry=0x670332 "Objects/abstract.c", line=line@entry=2077,
function=function@entry=0x670ff6 <__PRETTY_FUNCTION__.10598> "PyObject_Call") at assert.c:92
#3 0x00007ffff7118ee2 in __GI___assert_fail (
assertion=0x670d48 "(result != ((void *)0) && !PyErr_Occurred()) || (result == ((void *)0) && PyErr_Occurred())",
file=0x670332 "Objects/abstract.c", line=2077, function=0x670ff6 <__PRETTY_FUNCTION__.10598> "PyObject_Call") at assert.c:101
#4 0x0000000000461e89 in PyObject_Call (func=0x7ffff27013d8, arg=0x7ffff6638ef8, kw=0x0) at Objects/abstract.c:2076
#5 0x0000000000462f62 in PyObject_CallFunctionObjArgs
(callable=0x7ffff27013d8) at Objects/abstract.c:2362
#6 0x0000000000463c46 in PyObject_IsSubclass (derived=0x911140 <_PyExc_OSError>, cls=0x911140 <_PyExc_OSError>)
at Objects/abstract.c:2617
#7 0x00000000005cc591 in PyErr_NormalizeException (exc=0x7ffffffdc578, val=0x7ffffffdc580, tb=0x7ffffffdc588)
at Python/errors.c:254
#8 0x0000000000639bc6 in buffered_close (self=0x7ffff7e6ad78, args=0x0) at ./Modules/_io/bufferedio.c:552 It seems PyErr_NormalizeException doesn't like being called with an exception set. |
New changeset a98fd4eeed40 by Serhiy Storchaka in branch '3.4': New changeset 55c50c570098 by Serhiy Storchaka in branch 'default': |
Thank you Antoine. Perhaps this non-trivial code for chaining exceptions (repeated at least three times) should be extracted to separate function. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: