homepage

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.

classification
Title: ExitStack hang if enough nested exceptions
Type: crash Stage: resolved
Components: Library (Lib) Versions: Python 3.3
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: jcflack, ncoghlan, python-dev
Priority: normal Keywords:

Created on 2014年01月20日 20:08 by jcflack, last changed 2022年04月11日 14:57 by admin. This issue is now closed.

Messages (5)
msg208574 - (view) Author: (jcflack) Date: 2014年01月20日 20:08
Python 3.3.2 (default, Dec 4 2013, 20:19:27) 
[GCC 4.7.3] on linux (gentoo)
Suppose we create a context manager that will fail during exit because of a simple coding error:
@contextmanager
def f():
 try:
 yield 6
 finally:
 throdbog() # woops, forgot to define this
Now let's stack up a few of these:
with ExitStack() as stack:
 i = stack.enter_context(f())
 i = stack.enter_context(f())
 i = stack.enter_context(f())
 print(i)
... prints 6, then hangs, won't respond to ^C, can be killed.
Three levels on the stack seems to be the magic number. With one or two it works as expected ("During handling of the above exception, another exception occurred", etc.).
Is the ExitStack code somehow creating a circularly-linked exception structure when there are three levels?
msg208793 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2014年01月22日 12:33
New changeset b3c2472c12a1 by Nick Coghlan in branch '3.3':
Issue #20317: Don't create a reference loop in ExitStack
http://hg.python.org/cpython/rev/b3c2472c12a1 
msg208794 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2014年01月22日 12:39
Oh, that's quite neat. Because of the way _GeneratorContextManager works, the context is actually already set correctly on the thrown exceptions, but ExitStack is assuming it will be wrong.
This means _fix_exception (part of ExitStack.__exit__) ends up setting the first exception's context to itself while handling the second exception, which then creates an infinite loop when attempting to handle the third exception. Hence why three is the magic number :)
The existing tests didn't pick this up, because they just used callbacks for simplicity, and hence the context was wrong as expected.
Commit incoming.
msg208798 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2014年01月22日 13:05
New changeset 46c3ea358784 by Nick Coghlan in branch 'default':
Merge #20317 from 3.3
http://hg.python.org/cpython/rev/46c3ea358784 
msg209068 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2014年01月24日 13:07
New changeset b3eaeb4bdf84 by Nick Coghlan in branch '3.3':
Issue 20317: Remove debugging code from contextlib
http://hg.python.org/cpython/rev/b3eaeb4bdf84
New changeset a0bf53afedfa by Nick Coghlan in branch 'default':
Merge removal of issue 20317 debugging code from 3.3
http://hg.python.org/cpython/rev/a0bf53afedfa 
History
Date User Action Args
2022年04月11日 14:57:57adminsetgithub: 64516
2014年01月25日 08:06:40ncoghlansetstatus: open -> closed
resolution: fixed
stage: resolved
2014年01月24日 13:07:29python-devsetmessages: + msg209068
2014年01月22日 13:05:03python-devsetmessages: + msg208798
2014年01月22日 12:39:05ncoghlansetmessages: + msg208794
2014年01月22日 12:33:31python-devsetnosy: + python-dev
messages: + msg208793
2014年01月20日 20:13:11r.david.murraysetnosy: + ncoghlan
2014年01月20日 20:08:09jcflackcreate

AltStyle によって変換されたページ (->オリジナル) /