from test.support import (
captured_stderr, cpython_only, requires_docstrings, import_helper, run_code,
subTests, EqualToForwardRef,
+ exceeds_recursion_limit, skip_if_huge_c_stack, skip_wasi_stack_overflow,
+ skip_emscripten_stack_overflow,
)
from test.typinganndata import (
ann_module695, mod_generics_cache, _typed_dict_helper,
pass
self.assertEqual(MM2.__bases__, (collections.abc.MutableMapping, Generic))
+ @cpython_only
+ @skip_if_huge_c_stack()
+ @skip_wasi_stack_overflow()
+ @skip_emscripten_stack_overflow()
+ def test_parameters_deep_recursion(self):
+ x = [0]
+ for _ in range(exceeds_recursion_limit()):
+ x = [x]
+ with self.assertRaisesRegex(RecursionError, "in __parameter__ calculation"):
+ list[x].__parameters__
+
def test_orig_bases(self):
T = TypeVar('T')
class C(typing.Dict[str, T]): ...
_Py_make_parameters(PyObject *args)
{
assert(PyTuple_Check(args) || PyList_Check(args));
+ if (Py_EnterRecursiveCall(" in __parameter__ calculation")) {
+ return NULL;
+ }
+
const bool is_args_list = PyList_Check(args);
PyObject *tuple_args = NULL;
if (is_args_list) {
}
int rc = PyObject_HasAttrWithError(t, &_Py_ID(__typing_subst__));
if (rc < 0) {
- Py_DECREF(parameters);
- Py_XDECREF(tuple_args);
- return NULL;
+ goto error;
}
if (rc) {
iparam += tuple_add(parameters, iparam, t);
PyObject *subparams;
if (PyObject_GetOptionalAttr(t, &_Py_ID(__parameters__),
&subparams) < 0) {
- Py_DECREF(parameters);
- Py_XDECREF(tuple_args);
- return NULL;
+ goto error;
}
if (!subparams && (PyTuple_Check(t) || PyList_Check(t))) {
// Recursively call _Py_make_parameters for lists/tuples and
// add the results to the current parameters.
subparams = _Py_make_parameters(t);
if (subparams == NULL) {
- Py_DECREF(parameters);
- Py_XDECREF(tuple_args);
- return NULL;
+ goto error;
}
}
if (subparams && PyTuple_Check(subparams)) {
if (_PyTuple_Resize(¶meters, len) < 0) {
Py_DECREF(subparams);
Py_XDECREF(tuple_args);
- return NULL;
+ goto cleanup;
}
}
for (Py_ssize_t j = 0; j < len2; j++) {
}
if (iparam < len) {
if (_PyTuple_Resize(¶meters, iparam) < 0) {
- Py_XDECREF(parameters);
- Py_XDECREF(tuple_args);
- return NULL;
+ goto error;
}
}
Py_XDECREF(tuple_args);
+ Py_LeaveRecursiveCall();
return parameters;
+
+error:
+ Py_XDECREF(parameters);
+ Py_XDECREF(tuple_args);
+cleanup:
+ Py_LeaveRecursiveCall();
+ return NULL;
}
/* If obj is a generic alias, substitute type variables params