mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
bpo-42500: Fix recursion in or after except (GH-23568)
* Use counter, rather boolean state when handling soft overflows.
This commit is contained in:
parent
93a0ef7647
commit
4e7a69bdb6
9 changed files with 76 additions and 72 deletions
|
@ -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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue