bpo-42500: Fix recursion in or after except (GH-23568) · python/cpython@4e7a69b

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

221221

def f():

222222

f()

223223

try:

224-

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

224+

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

225225

try:

226226

sys.setrecursionlimit(depth)

227227

except RecursionError:

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

231231232232

# Issue #5392: test stack overflow after hitting recursion

233233

# limit twice

234-

self.assertRaises(RecursionError, f)

235-

self.assertRaises(RecursionError, f)

234+

with self.assertRaises(RecursionError):

235+

f()

236+

with self.assertRaises(RecursionError):

237+

f()

236238

finally:

237239

sys.setrecursionlimit(oldlimit)

238240239241

@test.support.cpython_only

240242

def test_setrecursionlimit_recursion_depth(self):

241243

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

242-

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

243-

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

244-

# reset the overflowed flag to 0.

244+

# current recursion depth is already higher than limit.

245245246246

from _testinternalcapi import get_recursion_depth

247247

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

262262

sys.setrecursionlimit(1000)

263263264264

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

265-

# formula extracted from _Py_RecursionLimitLowerWaterMark()

266-

if limit > 200:

267-

depth = limit - 50

268-

else:

269-

depth = limit * 3 // 4

270-

set_recursion_limit_at_depth(depth, limit)

265+

set_recursion_limit_at_depth(limit, limit)

271266

finally:

272267

sys.setrecursionlimit(oldlimit)

273268274-

# The error message is specific to CPython

275-

@test.support.cpython_only

276-

def test_recursionlimit_fatalerror(self):

277-

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

278-

# from a first one.

279-

code = textwrap.dedent("""

280-

import sys

281-282-

def f():

283-

try:

284-

f()

285-

except RecursionError:

286-

f()

287-288-

sys.setrecursionlimit(%d)

289-

f()""")

290-

with test.support.SuppressCrashReport():

291-

for i in (50, 1000):

292-

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

293-

stderr=subprocess.PIPE)

294-

err = sub.communicate()[1]

295-

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

296-

self.assertIn(

297-

b"Fatal Python error: _Py_CheckRecursiveCall: "

298-

b"Cannot recover from stack overflow",

299-

err)

300-301269

def test_getwindowsversion(self):

302270

# Raise SkipTest if sys doesn't have getwindowsversion attribute

303271

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