mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
bpo-40696: Fix a hang that can arise after gen.throw() (GH-20287)
This updates _PyErr_ChainStackItem() to use _PyErr_SetObject()
instead of _PyErr_ChainExceptions(). This prevents a hang in
certain circumstances because _PyErr_SetObject() performs checks
to prevent cycles in the exception context chain while
_PyErr_ChainExceptions() doesn't.
(cherry picked from commit 7c30d12bd5
)
Co-authored-by: Chris Jerdonek <chris.jerdonek@gmail.com>
This commit is contained in:
parent
a08b7c3bb0
commit
7f77ac463c
7 changed files with 130 additions and 23 deletions
|
@ -371,6 +371,32 @@ class GeneratorThrowTest(unittest.TestCase):
|
|||
context = cm.exception.__context__
|
||||
self.assertEqual((type(context), context.args), (KeyError, ('a',)))
|
||||
|
||||
def test_exception_context_with_yield_from_with_context_cycle(self):
|
||||
# Check trying to create an exception context cycle:
|
||||
# https://bugs.python.org/issue40696
|
||||
has_cycle = None
|
||||
|
||||
def f():
|
||||
yield
|
||||
|
||||
def g(exc):
|
||||
nonlocal has_cycle
|
||||
try:
|
||||
raise exc
|
||||
except Exception:
|
||||
try:
|
||||
yield from f()
|
||||
except Exception as exc:
|
||||
has_cycle = (exc is exc.__context__)
|
||||
yield
|
||||
|
||||
exc = KeyError('a')
|
||||
gen = g(exc)
|
||||
gen.send(None)
|
||||
gen.throw(exc)
|
||||
# This also distinguishes from the initial has_cycle=None.
|
||||
self.assertEqual(has_cycle, False)
|
||||
|
||||
def test_throw_after_none_exc_type(self):
|
||||
def g():
|
||||
try:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue