bpo-42500: Fix recursion in or after except (GH-23568)

* Use counter, rather boolean state when handling soft overflows.
This commit is contained in:
Mark Shannon 2020-12-02 13:30:55 +00:00 committed by GitHub
parent 93a0ef7647
commit 4e7a69bdb6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 76 additions and 72 deletions

View file

@ -1046,7 +1046,7 @@ class ExceptionTests(unittest.TestCase):
# tstate->recursion_depth is equal to (recursion_limit - 1)
# and is equal to recursion_limit when _gen_throw() calls
# PyErr_NormalizeException().
recurse(setrecursionlimit(depth + 2) - depth - 1)
recurse(setrecursionlimit(depth + 2) - depth)
finally:
sys.setrecursionlimit(recursionlimit)
print('Done.')
@ -1076,6 +1076,54 @@ class ExceptionTests(unittest.TestCase):
b'while normalizing an exception', err)
self.assertIn(b'Done.', out)
def test_recursion_in_except_handler(self):
def set_relative_recursion_limit(n):
depth = 1
while True:
try:
sys.setrecursionlimit(depth)
except RecursionError:
depth += 1
else:
break
sys.setrecursionlimit(depth+n)
def recurse_in_except():
try:
1/0
except:
recurse_in_except()
def recurse_after_except():
try:
1/0
except:
pass
recurse_after_except()
def recurse_in_body_and_except():
try:
recurse_in_body_and_except()
except:
recurse_in_body_and_except()
recursionlimit = sys.getrecursionlimit()
try:
set_relative_recursion_limit(10)
for func in (recurse_in_except, recurse_after_except, recurse_in_body_and_except):
with self.subTest(func=func):
try:
func()
except RecursionError:
pass
else:
self.fail("Should have raised a RecursionError")
finally:
sys.setrecursionlimit(recursionlimit)
@cpython_only
def test_recursion_normalizing_with_no_memory(self):
# Issue #30697. Test that in the abort that occurs when there is no
@ -1112,7 +1160,7 @@ class ExceptionTests(unittest.TestCase):
except MemoryError as e:
tb = e.__traceback__
else:
self.fail("Should have raises a MemoryError")
self.fail("Should have raised a MemoryError")
return traceback.format_tb(tb)
tb1 = raiseMemError()