mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
[3.12] gh-128632: fix segfault on nested __classdict__ type param (GH… (#132090)
(cherry picked from commit 891c61c1fa
)
Co-authored-by: Tomasz Pytel <tompytel@gmail.com>
This commit is contained in:
parent
05213afaa7
commit
3d3e7b0ada
3 changed files with 45 additions and 0 deletions
|
@ -2244,6 +2244,25 @@ if x:
|
||||||
|
|
||||||
self.assertRaises(IndentationError, exec, code)
|
self.assertRaises(IndentationError, exec, code)
|
||||||
|
|
||||||
|
@support.cpython_only
|
||||||
|
def test_disallowed_type_param_names(self):
|
||||||
|
# See gh-128632
|
||||||
|
|
||||||
|
self._check_error(f"class A[__classdict__]: pass",
|
||||||
|
f"reserved name '__classdict__' cannot be used for type parameter")
|
||||||
|
self._check_error(f"def f[__classdict__](): pass",
|
||||||
|
f"reserved name '__classdict__' cannot be used for type parameter")
|
||||||
|
self._check_error(f"type T[__classdict__] = tuple[__classdict__]",
|
||||||
|
f"reserved name '__classdict__' cannot be used for type parameter")
|
||||||
|
|
||||||
|
# These compilations are here to make sure __class__, __classcell__ and __classdictcell__
|
||||||
|
# don't break in the future like __classdict__ did in this case.
|
||||||
|
for name in ('__class__', '__classcell__', '__classdictcell__'):
|
||||||
|
compile(f"""
|
||||||
|
class A:
|
||||||
|
class B[{name}]: pass
|
||||||
|
""", "<testcase>", mode="exec")
|
||||||
|
|
||||||
@support.cpython_only
|
@support.cpython_only
|
||||||
def test_nested_named_except_blocks(self):
|
def test_nested_named_except_blocks(self):
|
||||||
code = ""
|
code = ""
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Disallow ``__classdict__`` as the name of a type parameter. Using this
|
||||||
|
name would previously crash the interpreter in some circumstances.
|
|
@ -2191,6 +2191,24 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
||||||
VISIT_QUIT(st, 1);
|
VISIT_QUIT(st, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
symtable_visit_type_param_check_reserved_name(struct symtable *st, type_param_ty tp, identifier name)
|
||||||
|
{
|
||||||
|
if (_PyUnicode_Equal(name, &_Py_ID(__classdict__))) {
|
||||||
|
PyObject *error_msg = PyUnicode_FromFormat("reserved name '%U' cannot be "
|
||||||
|
"used for type parameter", name);
|
||||||
|
PyErr_SetObject(PyExc_SyntaxError, error_msg);
|
||||||
|
Py_DECREF(error_msg);
|
||||||
|
PyErr_RangedSyntaxLocationObject(st->st_filename,
|
||||||
|
tp->lineno,
|
||||||
|
tp->col_offset + 1,
|
||||||
|
tp->end_lineno,
|
||||||
|
tp->end_col_offset + 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
symtable_visit_type_param(struct symtable *st, type_param_ty tp)
|
symtable_visit_type_param(struct symtable *st, type_param_ty tp)
|
||||||
{
|
{
|
||||||
|
@ -2201,6 +2219,8 @@ symtable_visit_type_param(struct symtable *st, type_param_ty tp)
|
||||||
}
|
}
|
||||||
switch(tp->kind) {
|
switch(tp->kind) {
|
||||||
case TypeVar_kind:
|
case TypeVar_kind:
|
||||||
|
if (!symtable_visit_type_param_check_reserved_name(st, tp, tp->v.TypeVar.name))
|
||||||
|
VISIT_QUIT(st, 0);
|
||||||
if (!symtable_add_def(st, tp->v.TypeVar.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp)))
|
if (!symtable_add_def(st, tp->v.TypeVar.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp)))
|
||||||
VISIT_QUIT(st, 0);
|
VISIT_QUIT(st, 0);
|
||||||
if (tp->v.TypeVar.bound) {
|
if (tp->v.TypeVar.bound) {
|
||||||
|
@ -2219,10 +2239,14 @@ symtable_visit_type_param(struct symtable *st, type_param_ty tp)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeVarTuple_kind:
|
case TypeVarTuple_kind:
|
||||||
|
if (!symtable_visit_type_param_check_reserved_name(st, tp, tp->v.TypeVarTuple.name))
|
||||||
|
VISIT_QUIT(st, 0);
|
||||||
if (!symtable_add_def(st, tp->v.TypeVarTuple.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp)))
|
if (!symtable_add_def(st, tp->v.TypeVarTuple.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp)))
|
||||||
VISIT_QUIT(st, 0);
|
VISIT_QUIT(st, 0);
|
||||||
break;
|
break;
|
||||||
case ParamSpec_kind:
|
case ParamSpec_kind:
|
||||||
|
if (!symtable_visit_type_param_check_reserved_name(st, tp, tp->v.ParamSpec.name))
|
||||||
|
VISIT_QUIT(st, 0);
|
||||||
if (!symtable_add_def(st, tp->v.ParamSpec.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp)))
|
if (!symtable_add_def(st, tp->v.ParamSpec.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp)))
|
||||||
VISIT_QUIT(st, 0);
|
VISIT_QUIT(st, 0);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue