aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2014-01-22 23:04:37 +1000
committerNick Coghlan <ncoghlan@gmail.com>2014-01-22 23:04:37 +1000
commitd58831e6886ce457626448c6c2efd1f4cd05dd3a (patch)
tree2571c8d98d76f8ed944de9a517c546c53a25cf61 /Lib/contextlib.py
parentasyncio: Cleanup logging in BaseEventLoop._run_once() (diff)
parentIssue #20317: Don't create a reference loop in ExitStack (diff)
downloadcpython-d58831e6886ce457626448c6c2efd1f4cd05dd3a.tar.gz
cpython-d58831e6886ce457626448c6c2efd1f4cd05dd3a.tar.bz2
cpython-d58831e6886ce457626448c6c2efd1f4cd05dd3a.zip
Merge #20317 from 3.3
Diffstat (limited to 'Lib/contextlib.py')
-rw-r--r--Lib/contextlib.py10
1 files changed, 9 insertions, 1 deletions
diff --git a/Lib/contextlib.py b/Lib/contextlib.py
index d3219f6c150..ca7a79ddd19 100644
--- a/Lib/contextlib.py
+++ b/Lib/contextlib.py
@@ -298,11 +298,19 @@ class ExitStack(object):
# we were actually nesting multiple with statements
frame_exc = sys.exc_info()[1]
def _fix_exception_context(new_exc, old_exc):
+ # Context isn't what we want, so find the end of the chain
while 1:
exc_context = new_exc.__context__
- if exc_context in (None, frame_exc):
+ if exc_context is old_exc:
+ # Context is already set correctly (see issue 20317)
+ return
+ if exc_context is None or exc_context is frame_exc:
break
+ details = id(new_exc), id(old_exc), id(exc_context)
+ raise Exception(str(details))
new_exc = exc_context
+ # Change the end of the chain to point to the exception
+ # we expect it to reference
new_exc.__context__ = old_exc
# Callbacks are invoked in LIFO order to match the behaviour of