mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
gh-116126: Implement PEP 696 (#116129)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com> Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com>
This commit is contained in:
parent
852263e108
commit
ca269e58c2
28 changed files with 1924 additions and 623 deletions
|
@ -2275,6 +2275,24 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
|
|||
VISIT_QUIT(st, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
symtable_visit_type_param_bound_or_default(struct symtable *st, expr_ty e, identifier name, void *key)
|
||||
{
|
||||
if (e) {
|
||||
int is_in_class = st->st_cur->ste_can_see_class_scope;
|
||||
if (!symtable_enter_block(st, name, TypeVarBoundBlock, key, LOCATION(e)))
|
||||
return 0;
|
||||
st->st_cur->ste_can_see_class_scope = is_in_class;
|
||||
if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(e))) {
|
||||
VISIT_QUIT(st, 0);
|
||||
}
|
||||
VISIT(st, expr, e);
|
||||
if (!symtable_exit_block(st))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
symtable_visit_type_param(struct symtable *st, type_param_ty tp)
|
||||
{
|
||||
|
@ -2287,28 +2305,39 @@ symtable_visit_type_param(struct symtable *st, type_param_ty tp)
|
|||
case TypeVar_kind:
|
||||
if (!symtable_add_def(st, tp->v.TypeVar.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp)))
|
||||
VISIT_QUIT(st, 0);
|
||||
if (tp->v.TypeVar.bound) {
|
||||
int is_in_class = st->st_cur->ste_can_see_class_scope;
|
||||
if (!symtable_enter_block(st, tp->v.TypeVar.name,
|
||||
TypeVarBoundBlock, (void *)tp,
|
||||
LOCATION(tp)))
|
||||
VISIT_QUIT(st, 0);
|
||||
st->st_cur->ste_can_see_class_scope = is_in_class;
|
||||
if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(tp->v.TypeVar.bound))) {
|
||||
VISIT_QUIT(st, 0);
|
||||
}
|
||||
VISIT(st, expr, tp->v.TypeVar.bound);
|
||||
if (!symtable_exit_block(st))
|
||||
VISIT_QUIT(st, 0);
|
||||
|
||||
// We must use a different key for the bound and default. The obvious choice would be to
|
||||
// use the .bound and .default_value pointers, but that fails when the expression immediately
|
||||
// inside the bound or default is a comprehension: we would reuse the same key for
|
||||
// the comprehension scope. Therefore, use the address + 1 as the second key.
|
||||
// The only requirement for the key is that it is unique and it matches the logic in
|
||||
// compile.c where the scope is retrieved.
|
||||
if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVar.bound, tp->v.TypeVar.name,
|
||||
(void *)tp)) {
|
||||
VISIT_QUIT(st, 0);
|
||||
}
|
||||
if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVar.default_value, tp->v.TypeVar.name,
|
||||
(void *)((uintptr_t)tp + 1))) {
|
||||
VISIT_QUIT(st, 0);
|
||||
}
|
||||
break;
|
||||
case TypeVarTuple_kind:
|
||||
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);
|
||||
}
|
||||
if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVarTuple.default_value, tp->v.TypeVarTuple.name,
|
||||
(void *)tp)) {
|
||||
VISIT_QUIT(st, 0);
|
||||
}
|
||||
break;
|
||||
case ParamSpec_kind:
|
||||
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);
|
||||
}
|
||||
if (!symtable_visit_type_param_bound_or_default(st, tp->v.ParamSpec.default_value, tp->v.ParamSpec.name,
|
||||
(void *)tp)) {
|
||||
VISIT_QUIT(st, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
VISIT_QUIT(st, 1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue