This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients nedbat, scoder, serhiy.storchaka, vstinner
Date 2018-07-11.15:00:31
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1531321231.92.0.56676864532.issue34068@psf.upfronthosting.co.za>
In-reply-to
Content
I'm able to reproduce the bug on my Fedora using:

vstinner@apu$ gdb -args ENV/bin/python -m coverage run  --pylib -m test --fail-env-changed -uall,-cpu  test_urllib -F
(gdb) run

python: Objects/typeobject.c:3086: _PyType_Lookup: Assertion `!PyErr_Occurred()' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff7093f2b in raise () from /lib64/libc.so.6

(gdb) py-bt
Traceback (most recent call first):
  <built-in method close of HTTPResponse object at remote 0x7fffe581ff50>
  File "/home/vstinner/prog/python/master/Lib/http/client.py", line 405, in close
    super().close() # set "closed" flag
  File "/home/vstinner/prog/python/master/Lib/traceback.py", line 216, in clear_frames
    tb.tb_frame.clear()
  File "/home/vstinner/prog/python/master/Lib/unittest/case.py", line 205, in __exit__
    traceback.clear_frames(tb)
  File "/home/vstinner/prog/python/master/Lib/unittest/case.py", line 178, in handle
    callable_obj(*args, **kwargs)
  File "/home/vstinner/prog/python/master/Lib/unittest/case.py", line 743, in assertRaises
    return context.handle('assertRaises', args, kwargs)
  File "/home/vstinner/prog/python/master/Lib/test/test_urllib.py", line 382, in test_redirect_limit_independent
    "http://something")
  (...)

(gdb) where
#0  0x00007ffff7093f2b in raise () from /lib64/libc.so.6
#1  0x00007ffff707e561 in abort () from /lib64/libc.so.6
#2  0x00007ffff707e431 in __assert_fail_base.cold.0 () from /lib64/libc.so.6
#3  0x00007ffff708c692 in __assert_fail () from /lib64/libc.so.6
#4  0x00000000004aa2ea in _PyType_Lookup (type=0xdc1b30, name='__IOBase_closed') at Objects/typeobject.c:3086
#5  0x00000000004883ff in _PyObject_GenericSetAttrWithDict (
    obj=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 0x7fffe553efb0>, _headers=[('Location', 'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], _unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', length=None, will_close=True, code=302, _finalizing=True) at remote 0x7fffe581ff50>, name='__IOBase_closed', value=True, dict=0x0) at Objects/object.c:1292
#6  0x000000000048871a in PyObject_GenericSetAttr (
    obj=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 0x7fffe553efb0>, _headers=[('Location', 'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], _unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', length=None, will_close=True, code=302, _finalizing=True) at remote 0x7fffe581ff50>, name='__IOBase_closed', value=True) at Objects/object.c:1340
#7  0x00000000004873a0 in PyObject_SetAttr (
    v=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 0x7fffe553efb0>, _headers=[('Location', 'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], _unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', length=None, will_close=True, code=302, _finalizing=True) at remote 0x7fffe581ff50>, name='__IOBase_closed', value=True) at Objects/object.c:977
#8  0x0000000000486f03 in _PyObject_SetAttrId (
    v=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 0x7fffe553efb0>, _headers=[('Location', 'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], _unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', length=None, will_close=True, code=302, _finalizing=True) at remote 0x7fffe581ff50>, name=0x9d4330 <PyId___IOBase_closed>, w=True) at Objects/object.c:857
#9  0x0000000000625d9c in _io__IOBase_close_impl (
    self=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 0x7fffe553efb0>, _headers=[('Location', 'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], _unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', length=None, will_close=True, code=302, _finalizing=---T---Type ---Type <return>---Type <ret---Type <ret---Type ---Type ---Type <return>---Type <ret---Type <return> to ---Type <return>---Type ---T---Type <return>---Type ---T---Type <return> to continue, or q <return> to quit---
) at remote 0x7fffe581ff50>) at ./Modules/_io/iobase.c:239
#10 0x0000000000627e12 in _io__IOBase_close (
    self=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 0x7fffe553efb0>, _headers=[('Location', 'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], _unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', length=None, will_close=True, code=302, _finalizing=True) at remote 0x7fffe581ff50>, _unused_ignored=0x0) at ./Modules/_io/clinic/iobase.c.h:60
#11 0x0000000000438cb3 in _PyMethodDef_RawFastCallKeywords (method=0x9d4d40 <iobase_methods+128>, 
    self=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 0x7fffe553efb0>, _headers=[('Location', 'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], _unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', length=None, will_close=True, code=302, _finalizing=True) at remote 0x7fffe581ff50>, args=0x7fffe4e793e8, nargs=0, kwnames=0x0) at Objects/call.c:629
#12 0x000000000043910d in _PyCFunction_FastCallKeywords (func=<built-in method close of HTTPResponse object at remote 0x7fffe581ff50>, args=0x7fffe4e793e8, nargs=0, kwnames=0x0)
    at Objects/call.c:730
#13 0x00000000005500e9 in call_function (pp_stack=0x7ffffffb7da0, oparg=0, kwnames=0x0) at Python/ceval.c:4565
#14 0x0000000000548e1d in _PyEval_EvalFrameDefault (
    f=Frame 0x7fffe4e79250, for file /home/vstinner/prog/python/master/Lib/http/client.py, line 405, in close (self=<HTTPResponse(fp=<FakeSocket(io_refs=0) at remote 0x7fffe4e2f1d0>, debuglevel=0, _method='GET', headers=<HTTPMessage(policy=<Compat32 at remote 0x7fffe553efb0>, _headers=[('Location', 'file://guidocomputer.athome.com:/python/license'), ('Connection', 'close')], _unixfrom=None, _payload='', _charset=None, preamble=None, epilogue=None, defects=[], _default_type='text/plain') at remote 0x7fffe542f4d0>, msg=<...>, version=11, status=302, reason='Found', chunked=False, chunk_left='UNKNOWN', length=None, will_close=True, code=302, _finalizing=True) at remote 0x7fffe581ff50>), throwflag=0)
    at Python/ceval.c:3159
(...)


The bug is in _io__IOBase_close_impl(). I modified the code:

    assert(!PyErr_Occurred());

    res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL);

    assert(!PyErr_Occurred());     /* <---- THIS ASSERTION FAILS */

    if (_PyObject_SetAttrId(self, &PyId___IOBase_closed, Py_True) < 0) {
        Py_XDECREF(res);
        return NULL;
    }

The problem is that _PyObject_SetAttrId() is called while the flush() method raised an exception.

We need something like PyErr_Fetch/PyErr_Store to set the attribute.
History
Date User Action Args
2018-07-11 15:00:32vstinnersetrecipients: + vstinner, scoder, nedbat, serhiy.storchaka
2018-07-11 15:00:31vstinnersetmessageid: <1531321231.92.0.56676864532.issue34068@psf.upfronthosting.co.za>
2018-07-11 15:00:31vstinnerlinkissue34068 messages
2018-07-11 15:00:31vstinnercreate