bpo-42500: Fix recursion in or after except (GH-23568) (#24501) · python/cpython@8b795ab

@@ -219,7 +219,7 @@ def test_recursionlimit_recovery(self):

219219

def f():

220220

f()

221221

try:

222-

for depth in (10, 25, 50, 75, 100, 250, 1000):

222+

for depth in (50, 75, 100, 250, 1000):

223223

try:

224224

sys.setrecursionlimit(depth)

225225

except RecursionError:

@@ -229,17 +229,17 @@ def f():

229229230230

# Issue #5392: test stack overflow after hitting recursion

231231

# limit twice

232-

self.assertRaises(RecursionError, f)

233-

self.assertRaises(RecursionError, f)

232+

with self.assertRaises(RecursionError):

233+

f()

234+

with self.assertRaises(RecursionError):

235+

f()

234236

finally:

235237

sys.setrecursionlimit(oldlimit)

236238237239

@test.support.cpython_only

238240

def test_setrecursionlimit_recursion_depth(self):

239241

# Issue #25274: Setting a low recursion limit must be blocked if the

240-

# current recursion depth is already higher than the "lower-water

241-

# mark". Otherwise, it may not be possible anymore to

242-

# reset the overflowed flag to 0.

242+

# current recursion depth is already higher than limit.

243243244244

from _testinternalcapi import get_recursion_depth

245245

@@ -260,42 +260,10 @@ def set_recursion_limit_at_depth(depth, limit):

260260

sys.setrecursionlimit(1000)

261261262262

for limit in (10, 25, 50, 75, 100, 150, 200):

263-

# formula extracted from _Py_RecursionLimitLowerWaterMark()

264-

if limit > 200:

265-

depth = limit - 50

266-

else:

267-

depth = limit * 3 // 4

268-

set_recursion_limit_at_depth(depth, limit)

263+

set_recursion_limit_at_depth(limit, limit)

269264

finally:

270265

sys.setrecursionlimit(oldlimit)

271266272-

# The error message is specific to CPython

273-

@test.support.cpython_only

274-

def test_recursionlimit_fatalerror(self):

275-

# A fatal error occurs if a second recursion limit is hit when recovering

276-

# from a first one.

277-

code = textwrap.dedent("""

278-

import sys

279-280-

def f():

281-

try:

282-

f()

283-

except RecursionError:

284-

f()

285-286-

sys.setrecursionlimit(%d)

287-

f()""")

288-

with test.support.SuppressCrashReport():

289-

for i in (50, 1000):

290-

sub = subprocess.Popen([sys.executable, '-c', code % i],

291-

stderr=subprocess.PIPE)

292-

err = sub.communicate()[1]

293-

self.assertTrue(sub.returncode, sub.returncode)

294-

self.assertIn(

295-

b"Fatal Python error: _Py_CheckRecursiveCall: "

296-

b"Cannot recover from stack overflow",

297-

err)

298-299267

def test_getwindowsversion(self):

300268

# Raise SkipTest if sys doesn't have getwindowsversion attribute

301269

test.support.get_attribute(sys, "getwindowsversion")