From 8ee9793de7c298fcf66168ec8cd936750cee018b Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 20 Jun 2023 19:02:16 +0100 Subject: [PATCH 1/2] Make sure that frame stack is in valid state should a recursion error happen when calling a class. --- Lib/test/test_class.py | 19 +++++ Python/bytecodes.c | 7 +- Python/generated_cases.c.h | 157 +++++++++++++++++++------------------ 3 files changed, 102 insertions(+), 81 deletions(-) diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index d7a48e55b10180..f02795d411f136 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -740,6 +740,25 @@ class A(0, 1, 2, 3, 4, 5, 6, 7, **d): pass class A(0, *range(1, 8), **d, foo='bar'): pass self.assertEqual(A, (tuple(range(8)), {'foo': 'bar'})) + def testClassCallRecursionLimit(self): + class C: + def __init__(self): + self.c = C() + + try: + C() + except RecursionError: + # OK + pass + def add_one_level(): + #Each call to C() consumes 2 levels, so offset by 1. + C() + try: + add_one_level() + except RecursionError: + # OK + pass + if __name__ == '__main__': unittest.main() diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 3ef8ed0ccaafdc..e10cf12b94a741 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2924,9 +2924,6 @@ dummy_func( goto error; } Py_DECREF(tp); - if (_Py_EnterRecursivePy(tstate)) { - goto exit_unwind; - } _PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked( tstate, (PyCodeObject *)&_Py_InitCleanup, 1, 0); assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[1].op.code == EXIT_INIT_CHECK); @@ -2950,6 +2947,10 @@ dummy_func( shim->previous = frame; frame = cframe.current_frame = init_frame; CALL_STAT_INC(inlined_py_calls); + /* Account for pushing the extra frame. + * We don't check recursion depth here, + * as it will be checked after start_frame */ + tstate->py_recursion_remaining--; goto start_frame; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 11ca535adfb19b..ce4981be45b252 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -4051,9 +4051,6 @@ goto error; } Py_DECREF(tp); - if (_Py_EnterRecursivePy(tstate)) { - goto exit_unwind; - } _PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked( tstate, (PyCodeObject *)&_Py_InitCleanup, 1, 0); assert(_PyCode_CODE((PyCodeObject *)shim->f_executable)[1].op.code == EXIT_INIT_CHECK); @@ -4077,13 +4074,17 @@ shim->previous = frame; frame = cframe.current_frame = init_frame; CALL_STAT_INC(inlined_py_calls); + /* Account for pushing the extra frame. + * We don't check recursion depth here, + * as it will be checked after start_frame */ + tstate->py_recursion_remaining--; goto start_frame; - #line 4082 "Python/generated_cases.c.h" + #line 4083 "Python/generated_cases.c.h" } TARGET(EXIT_INIT_CHECK) { PyObject *should_be_none = stack_pointer[-1]; - #line 2957 "Python/bytecodes.c" + #line 2958 "Python/bytecodes.c" assert(STACK_LEVEL() == 2); if (should_be_none != Py_None) { PyErr_Format(PyExc_TypeError, @@ -4091,7 +4092,7 @@ Py_TYPE(should_be_none)->tp_name); goto error; } - #line 4095 "Python/generated_cases.c.h" + #line 4096 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } @@ -4101,7 +4102,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2967 "Python/bytecodes.c" + #line 2968 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4123,7 +4124,7 @@ } Py_DECREF(tp); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4127 "Python/generated_cases.c.h" + #line 4128 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4137,7 +4138,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2992 "Python/bytecodes.c" + #line 2993 "Python/bytecodes.c" /* Builtin METH_O functions */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -4165,7 +4166,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4169 "Python/generated_cases.c.h" + #line 4170 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4179,7 +4180,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3023 "Python/bytecodes.c" + #line 3024 "Python/bytecodes.c" /* Builtin METH_FASTCALL functions, without keywords */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -4211,7 +4212,7 @@ 'invalid'). In those cases an exception is set, so we must handle it. */ - #line 4215 "Python/generated_cases.c.h" + #line 4216 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4225,7 +4226,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3058 "Python/bytecodes.c" + #line 3059 "Python/bytecodes.c" /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ int is_meth = method != NULL; int total_args = oparg; @@ -4257,7 +4258,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4261 "Python/generated_cases.c.h" + #line 4262 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4271,7 +4272,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3093 "Python/bytecodes.c" + #line 3094 "Python/bytecodes.c" assert(kwnames == NULL); /* len(o) */ int is_meth = method != NULL; @@ -4296,7 +4297,7 @@ Py_DECREF(callable); Py_DECREF(arg); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4300 "Python/generated_cases.c.h" + #line 4301 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4309,7 +4310,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3120 "Python/bytecodes.c" + #line 3121 "Python/bytecodes.c" assert(kwnames == NULL); /* isinstance(o, o2) */ int is_meth = method != NULL; @@ -4336,7 +4337,7 @@ Py_DECREF(cls); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4340 "Python/generated_cases.c.h" + #line 4341 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4348,7 +4349,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *self = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 3150 "Python/bytecodes.c" + #line 3151 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); assert(method != NULL); @@ -4366,14 +4367,14 @@ SKIP_OVER(INLINE_CACHE_ENTRIES_CALL + 1); assert(next_instr[-1].op.code == POP_TOP); DISPATCH(); - #line 4370 "Python/generated_cases.c.h" + #line 4371 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3170 "Python/bytecodes.c" + #line 3171 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4404,7 +4405,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4408 "Python/generated_cases.c.h" + #line 4409 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4417,7 +4418,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3204 "Python/bytecodes.c" + #line 3205 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4446,7 +4447,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4450 "Python/generated_cases.c.h" + #line 4451 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4459,7 +4460,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3236 "Python/bytecodes.c" + #line 3237 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 0 || oparg == 1); int is_meth = method != NULL; @@ -4488,7 +4489,7 @@ Py_DECREF(self); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4492 "Python/generated_cases.c.h" + #line 4493 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4501,7 +4502,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3268 "Python/bytecodes.c" + #line 3269 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4529,7 +4530,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4533 "Python/generated_cases.c.h" + #line 4534 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4539,9 +4540,9 @@ } TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { - #line 3299 "Python/bytecodes.c" + #line 3300 "Python/bytecodes.c" GO_TO_INSTRUCTION(CALL_FUNCTION_EX); - #line 4545 "Python/generated_cases.c.h" + #line 4546 "Python/generated_cases.c.h" } TARGET(CALL_FUNCTION_EX) { @@ -4550,7 +4551,7 @@ PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))]; PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))]; PyObject *result; - #line 3303 "Python/bytecodes.c" + #line 3304 "Python/bytecodes.c" // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); @@ -4612,14 +4613,14 @@ } result = PyObject_Call(func, callargs, kwargs); } - #line 4616 "Python/generated_cases.c.h" + #line 4617 "Python/generated_cases.c.h" Py_DECREF(func); Py_DECREF(callargs); Py_XDECREF(kwargs); - #line 3365 "Python/bytecodes.c" + #line 3366 "Python/bytecodes.c" assert(PEEK(3 + (oparg & 1)) == NULL); if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; } - #line 4623 "Python/generated_cases.c.h" + #line 4624 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 1) ? 1 : 0)); STACK_SHRINK(2); stack_pointer[-1] = result; @@ -4630,7 +4631,7 @@ TARGET(MAKE_FUNCTION) { PyObject *codeobj = stack_pointer[-1]; PyObject *func; - #line 3371 "Python/bytecodes.c" + #line 3372 "Python/bytecodes.c" PyFunctionObject *func_obj = (PyFunctionObject *) PyFunction_New(codeobj, GLOBALS()); @@ -4642,7 +4643,7 @@ func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; func = (PyObject *)func_obj; - #line 4646 "Python/generated_cases.c.h" + #line 4647 "Python/generated_cases.c.h" stack_pointer[-1] = func; DISPATCH(); } @@ -4650,7 +4651,7 @@ TARGET(SET_FUNCTION_ATTRIBUTE) { PyObject *func = stack_pointer[-1]; PyObject *attr = stack_pointer[-2]; - #line 3385 "Python/bytecodes.c" + #line 3386 "Python/bytecodes.c" assert(PyFunction_Check(func)); PyFunctionObject *func_obj = (PyFunctionObject *)func; switch(oparg) { @@ -4675,14 +4676,14 @@ default: Py_UNREACHABLE(); } - #line 4679 "Python/generated_cases.c.h" + #line 4680 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = func; DISPATCH(); } TARGET(RETURN_GENERATOR) { - #line 3412 "Python/bytecodes.c" + #line 3413 "Python/bytecodes.c" assert(PyFunction_Check(frame->f_funcobj)); PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); @@ -4703,7 +4704,7 @@ frame = cframe.current_frame = prev; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; - #line 4707 "Python/generated_cases.c.h" + #line 4708 "Python/generated_cases.c.h" } TARGET(BUILD_SLICE) { @@ -4711,15 +4712,15 @@ PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))]; PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))]; PyObject *slice; - #line 3435 "Python/bytecodes.c" + #line 3436 "Python/bytecodes.c" slice = PySlice_New(start, stop, step); - #line 4717 "Python/generated_cases.c.h" + #line 4718 "Python/generated_cases.c.h" Py_DECREF(start); Py_DECREF(stop); Py_XDECREF(step); - #line 3437 "Python/bytecodes.c" + #line 3438 "Python/bytecodes.c" if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; } - #line 4723 "Python/generated_cases.c.h" + #line 4724 "Python/generated_cases.c.h" STACK_SHRINK(((oparg == 3) ? 1 : 0)); STACK_SHRINK(1); stack_pointer[-1] = slice; @@ -4729,14 +4730,14 @@ TARGET(CONVERT_VALUE) { PyObject *value = stack_pointer[-1]; PyObject *result; - #line 3441 "Python/bytecodes.c" + #line 3442 "Python/bytecodes.c" convertion_func_ptr conv_fn; assert(oparg >= FVC_STR && oparg <= FVC_ASCII); conv_fn = CONVERSION_FUNCTIONS[oparg]; result = conv_fn(value); Py_DECREF(value); if (result == NULL) goto pop_1_error; - #line 4740 "Python/generated_cases.c.h" + #line 4741 "Python/generated_cases.c.h" stack_pointer[-1] = result; DISPATCH(); } @@ -4744,7 +4745,7 @@ TARGET(FORMAT_SIMPLE) { PyObject *value = stack_pointer[-1]; PyObject *res; - #line 3450 "Python/bytecodes.c" + #line 3451 "Python/bytecodes.c" /* If value is a unicode object, then we know the result * of format(value) is value itself. */ if (!PyUnicode_CheckExact(value)) { @@ -4755,7 +4756,7 @@ else { res = value; } - #line 4759 "Python/generated_cases.c.h" + #line 4760 "Python/generated_cases.c.h" stack_pointer[-1] = res; DISPATCH(); } @@ -4764,12 +4765,12 @@ PyObject *fmt_spec = stack_pointer[-1]; PyObject *value = stack_pointer[-2]; PyObject *res; - #line 3463 "Python/bytecodes.c" + #line 3464 "Python/bytecodes.c" res = PyObject_Format(value, fmt_spec); Py_DECREF(value); Py_DECREF(fmt_spec); if (res == NULL) goto pop_2_error; - #line 4773 "Python/generated_cases.c.h" + #line 4774 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; DISPATCH(); @@ -4778,10 +4779,10 @@ TARGET(COPY) { PyObject *bottom = stack_pointer[-(1 + (oparg-1))]; PyObject *top; - #line 3470 "Python/bytecodes.c" + #line 3471 "Python/bytecodes.c" assert(oparg > 0); top = Py_NewRef(bottom); - #line 4785 "Python/generated_cases.c.h" + #line 4786 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = top; DISPATCH(); @@ -4793,7 +4794,7 @@ PyObject *rhs = stack_pointer[-1]; PyObject *lhs = stack_pointer[-2]; PyObject *res; - #line 3475 "Python/bytecodes.c" + #line 3476 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -4808,12 +4809,12 @@ assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); assert(binary_ops[oparg]); res = binary_ops[oparg](lhs, rhs); - #line 4812 "Python/generated_cases.c.h" + #line 4813 "Python/generated_cases.c.h" Py_DECREF(lhs); Py_DECREF(rhs); - #line 3490 "Python/bytecodes.c" + #line 3491 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 4817 "Python/generated_cases.c.h" + #line 4818 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -4823,16 +4824,16 @@ TARGET(SWAP) { PyObject *top = stack_pointer[-1]; PyObject *bottom = stack_pointer[-(2 + (oparg-2))]; - #line 3495 "Python/bytecodes.c" + #line 3496 "Python/bytecodes.c" assert(oparg >= 2); - #line 4829 "Python/generated_cases.c.h" + #line 4830 "Python/generated_cases.c.h" stack_pointer[-1] = bottom; stack_pointer[-(2 + (oparg-2))] = top; DISPATCH(); } TARGET(INSTRUMENTED_INSTRUCTION) { - #line 3499 "Python/bytecodes.c" + #line 3500 "Python/bytecodes.c" int next_opcode = _Py_call_instrumentation_instruction( tstate, frame, next_instr-1); if (next_opcode < 0) goto error; @@ -4844,26 +4845,26 @@ assert(next_opcode > 0 && next_opcode < 256); opcode = next_opcode; DISPATCH_GOTO(); - #line 4848 "Python/generated_cases.c.h" + #line 4849 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_JUMP_FORWARD) { - #line 3513 "Python/bytecodes.c" + #line 3514 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); - #line 4854 "Python/generated_cases.c.h" + #line 4855 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_JUMP_BACKWARD) { - #line 3517 "Python/bytecodes.c" + #line 3518 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP); - #line 4861 "Python/generated_cases.c.h" + #line 4862 "Python/generated_cases.c.h" CHECK_EVAL_BREAKER(); DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) { - #line 3522 "Python/bytecodes.c" + #line 3523 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4872,12 +4873,12 @@ assert(err == 0 || err == 1); int offset = err*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4876 "Python/generated_cases.c.h" + #line 4877 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) { - #line 3533 "Python/bytecodes.c" + #line 3534 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4886,12 +4887,12 @@ assert(err == 0 || err == 1); int offset = (1-err)*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4890 "Python/generated_cases.c.h" + #line 4891 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { - #line 3544 "Python/bytecodes.c" + #line 3545 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4903,12 +4904,12 @@ offset = 0; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4907 "Python/generated_cases.c.h" + #line 4908 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) { - #line 3558 "Python/bytecodes.c" + #line 3559 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4920,30 +4921,30 @@ offset = oparg; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4924 "Python/generated_cases.c.h" + #line 4925 "Python/generated_cases.c.h" DISPATCH(); } TARGET(EXTENDED_ARG) { - #line 3572 "Python/bytecodes.c" + #line 3573 "Python/bytecodes.c" assert(oparg); opcode = next_instr->op.code; oparg = oparg << 8 | next_instr->op.arg; PRE_DISPATCH_GOTO(); DISPATCH_GOTO(); - #line 4935 "Python/generated_cases.c.h" + #line 4936 "Python/generated_cases.c.h" } TARGET(CACHE) { - #line 3580 "Python/bytecodes.c" + #line 3581 "Python/bytecodes.c" assert(0 && "Executing a cache."); Py_UNREACHABLE(); - #line 4942 "Python/generated_cases.c.h" + #line 4943 "Python/generated_cases.c.h" } TARGET(RESERVED) { - #line 3585 "Python/bytecodes.c" + #line 3586 "Python/bytecodes.c" assert(0 && "Executing RESERVED instruction."); Py_UNREACHABLE(); - #line 4949 "Python/generated_cases.c.h" + #line 4950 "Python/generated_cases.c.h" } From 246616f1cabe21439ae7496db12ca8040b2b3cd6 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 5 Jul 2023 16:01:32 +0100 Subject: [PATCH 2/2] Tidy up test --- Lib/test/test_class.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index f02795d411f136..894e0ca67deabc 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -745,19 +745,15 @@ class C: def __init__(self): self.c = C() - try: + with self.assertRaises(RecursionError): C() - except RecursionError: - # OK - pass + def add_one_level(): #Each call to C() consumes 2 levels, so offset by 1. C() - try: + + with self.assertRaises(RecursionError): add_one_level() - except RecursionError: - # OK - pass if __name__ == '__main__':