8000 Works for functions · python/cpython@b12663d · GitHub
[go: up one dir, main page]

Skip to content

Commit b12663d

Browse files
committed
Works for functions
1 parent 3cd026a commit b12663d

File tree

3 files changed

+134
-15
lines changed

3 files changed

+134
-15
lines changed

Include/internal/pycore_symtable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ typedef struct _symtable_entry {
4949
PyObject *ste_varnames; /* list of function parameters */
5050
PyObject *ste_children; /* list of child blocks */
5151
PyObject *ste_directives;/* locations of global and nonlocal statements */
52+
PyObject *ste_typeparam_overlays; /* dict: map AST node addresses to symtable entries
53+
that represent typeparam overlays */
54+
PyObject *ste_current_typeparam_overlay; /* active typeparam overlay
55+
(key in ste_typeparam_overlays) */
5256
_Py_block_ty ste_type; /* module, class, function or annotation */
5357
int ste_nested; /* true if block is nested */
5458
unsigned ste_free : 1; /* true if block has free variables */

Python/compile.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,8 +2129,19 @@ compiler_type_params(struct compiler *c, asdl_typeparam_seq *typeparams)
21292129

21302130
for (Py_ssize_t i = 0; i < asdl_seq_LEN(typeparams); i++) {
21312131
typeparam_ty typeparam = asdl_seq_GET(typeparams, i);
2132-
RETURN_IF_ERROR(compiler_visit_expr(c, typeparam->constraint));
2133-
RETURN_IF_ERROR(compiler_visit_expr(c, typeparam->bound));
2132+
// TODO(PEP 695): Actually emit a TypeVar
2133+
ADDOP_LOAD_CONST(c, LOC(typeparam), Py_None);
2134+
switch(typeparam->kind) {
2135+
case TypeVar_kind:
2136+
compiler_nameop(c, LOC(typeparam), typeparam->v.TypeVar.name, Store);
2137+
break;
2138+
case TypeVarTuple_kind:
2139+
compiler_nameop(c, LOC(typeparam), typeparam->v.TypeVarTuple.name, Store);
2140+
break;
2141+
case ParamSpec_kind:
2142+
compiler_nameop(c, LOC(typeparam), typeparam->v.ParamSpec.name, Store);
2143+
break;
2144+
}
21342145
}
21352146
return SUCCESS;
21362147
}
@@ -2190,9 +2201,12 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
21902201
}
21912202

21922203
if (typeparams) {
2193-
RETURN_IF_ERROR(
2194-
compiler_enter_scope(c, name, COMPILER_SCOPE_TYPE_PARAMS, (void *)typeparams, firstlineno)
2195-
);
2204+
assert(c->u->u_ste->ste_current_typeparam_overlay == NULL);
2205+
PyObject *ptr = PyLong_FromVoidPtr((void *)typeparams);
2206+
if (ptr == NULL) {
2207+
return ERROR;
2208+
}
2209+
c->u->u_ste->ste_current_typeparam_overlay = ptr;
21962210
RETURN_IF_ERROR(compiler_type_params(c, typeparams));
21972211
}
21982212

@@ -2227,10 +2241,10 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
22272241
}
22282242
}
22292243
co = assemble(c, 1);
2244+
compiler_exit_scope(c);
22302245
if (typeparams) {
2231-
compiler_exit_scope(c);
2246+
Py_CLEAR(c->u->u_ste->ste_current_typeparam_overlay);
22322247
}
2233-
compiler_exit_scope(c);
22342248
if (co == NULL) {
22352249
Py_XDECREF(co);
22362250
return ERROR;
@@ -2242,6 +2256,7 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
22422256
Py_DECREF(co);
22432257

22442258
RETURN_IF_ERROR(compiler_apply_decorators(c, decos));
2259+
assert(c->u->u_ste->ste_current_typeparam_overlay == NULL);
22452260
return compiler_nameop(c, loc, name, Store);
22462261
}
22472262

Python/symtable.c

Lines changed: 108 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
7878
ste->ste_symbols = NULL;
7979
ste->ste_varnames = NULL;
8080
ste->ste_children = NULL;
81+
ste->ste_current_typeparam_overlay = NULL;
82+
ste->ste_typeparam_overlays = NULL;
8183

8284
ste->ste_directives = NULL;
8385

@@ -141,6 +143,8 @@ ste_dealloc(PySTEntryObject *ste)
141143
Py_XDECREF(ste->ste_varnames);
142144
Py_XDECREF(ste->ste_children);
143145
Py_XDECREF(ste->ste_directives);
146+
Py_XDECREF(ste->ste_typeparam_overlays);
147+
Py_XDECREF(ste->ste_current_typeparam_overlay);
144148
PyObject_Free(ste);
145149
}
146150

@@ -389,7 +393,21 @@ PySymtable_Lookup(struct symtable *st, void *key)
389393
long
390394
_PyST_GetSymbol(PySTEntryObject *ste, PyObject *name)
391395
{
392-
PyObject *v = PyDict_GetItemWithError(ste->ste_symbols, name);
396+
PyObject *v;
397+
if (ste->ste_current_typeparam_overlay) {
398+
assert(ste->ste_typeparam_overlays != NULL);
399+
PyObject *inner_ste = PyDict_GetItemWithError(ste->ste_typeparam_overlays,
400+
ste->ste_current_typeparam_overlay);
401+
if (inner_ste == NULL) {
402+
assert(PyErr_Occurred());
403+
return 0;
404+
}
405+
v = PyDict_GetItemWithError(((PySTEntryObject *)inner_ste)->ste_symbols, name);
406+
assert(v != NULL);
407+
}
408+
else {
409+
v = PyDict_GetItemWithError(ste->ste_symbols, name);
410+
}
393411
if (!v)
394412
return 0;
395413
assert(PyLong_Check(v));
@@ -400,6 +418,7 @@ int
400418
_PyST_GetScope(PySTEntryObject *ste, PyObject *name)
401419
{
402420
long symbol = _PyST_GetSymbol(ste, name);
421+
assert(!PyErr_Occurred());
403422
return (symbol >> SCOPE_OFFSET) & SCOPE_MASK;
404423
}
405424

@@ -959,6 +978,46 @@ symtable_exit_block(struct symtable *st)
959978
return 1;
960979
}
961980

981+
static int
982+
symtable_enter_typeparam_overlay(struct symtable *st, identifier name,
983+
void *ast, int lineno, int col_offset,
984+
int end_lineno, int end_col_offset)
985+
{
986+
PySTEntryObject *ste = ste_new(st, name, TypeParamBlock, ast, lineno, col_offset,
987+
end_lineno, end_col_offset);
988+
if (ste == NULL) {
989+
return 0;
990+
}
991+
PyObject *key = PyLong_FromVoidPtr(ast);
992+
if (key == NULL) {
993+
Py_DECREF(ste);
994+
return 0;
995+
}
996+
struct _symtable_entry *cur = st->st_cur;
997+
cur->ste_current_typeparam_overlay = Py_NewRef(key);
998+
if (cur->ste_typeparam_overlays == NULL) {
999+
cur->ste_typeparam_overlays = PyDict_New();
1000+
if (cur->ste_typeparam_overlays == NULL) {
1001+
Py_DECREF(key);
1002+
Py_DECREF(ste);
1003+
return 0;
1004+
}
1005+
}
1006+
if (PyDict_SetItem(cur->ste_typeparam_overlays, key, (PyObject *)ste) < 0) {
1007+
Py_DECREF(key);
1008+
Py_DECREF(ste);
1009+
return 0;
1010+
}
1011+
Py_DECREF(key);
1012+
Py_DECREF(ste);
1013+
return 1;
1014+
}
1015+
1016+
static int symtable_leave_typeparam_overlay(struct symtable *st) {
1017+
Py_CLEAR(st->st_cur->ste_current_typeparam_overlay);
1018+
return 1;
1019+
}
1020+
9621021
static int
9631022
symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,
9641023
void *ast, int lineno, int col_offset,
@@ -1014,6 +1073,47 @@ symtable_lookup(struct symtable *st, PyObject *name)
10141073
return ret;
10151074
}
10161075

1076+
static int
1077+
symtable_add_typeparam(struct symtable *st, PyObject *name,
1078+
int lineno, int col_offset, int end_lineno, int end_col_offset)
1079+
{
1080+
PyObject *typeparams;
1081+
PyObject *current;
1082+
if (!(typeparams = PyDict_GetItemWithError(st->st_cur->ste_typeparam_overlays,
1083+
st->st_cur->ste_current_typeparam_overlay))) {
1084+
if (PyErr_Occurred()) {
1085+
return 0;
1086+
}
1087+
else {
1088+
PyErr_SetString(PyExc_SystemError, "Invalid typeparam overlay");
1089+
return 0;
1090+
}
1091+
}
1092+
assert(Py_IS_TYPE(typeparams, &PySTEntry_Type));
1093+
struct _symtable_entry *ste = (struct _symtable_entry *)typeparams;
1094+
PyObject *dict = ste->ste_symbols;
1095+
if ((current = PyDict_GetItemWithError(dict, name))) {
1096+
PyErr_Format(PyExc_SyntaxError, "duplicate type parameter '%U'", name);
1097+
PyErr_RangedSyntaxLocationObject(st->st_filename,
1098+
lineno, col_offset + 1,
1099+
end_lineno, end_col_offset + 1);
1100+
return 0;
1101+
}
1102+
else if (PyErr_Occurred()) {
1103+
return 0;
1104+
}
1105+
PyObject *flags = PyLong_FromLong(CELL << SCOPE_OFFSET);
1106+
if (flags == NULL) {
1107+
return 0;
1108+
}
1109+
if (PyDict_SetItem(dict, name, flags) < 0) {
1110+
Py_DECREF(flags);
1111+
return 0;
1112+
}
1113+
Py_DECREF(flags);
1114+
return 1;
1115+
}
1116+
10171117
static int
10181118
symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _symtable_entry *ste,
10191119
int lineno, int col_offset, int end_lineno, int end_col_offset)
@@ -1199,9 +1299,9 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
11991299
if (s->v.FunctionDef.decorator_list)
12001300
VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list);
12011301
if (s->v.FunctionDef.typeparams) {
1202-
if (!symtable_enter_block(st, s->v.FunctionDef.name,
1203-
TypeParamBlock, (void *)s,
1204-
LOCATION(s))) {
1302+
if (!symtable_enter_typeparam_overlay(st, s->v.FunctionDef.name,
1303+
(void *)s->v.FunctionDef.typeparams,
1304+
LOCATION(s))) {
12051305
VISIT_QUIT(st, 0);
12061306
}
12071307
VISIT_SEQ(st, typeparam, s->v.FunctionDef.typeparams);
@@ -1218,7 +1318,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
12181318
if (!symtable_exit_block(st))
12191319
VISIT_QUIT(st, 0);
12201320
if (s->v.FunctionDef.typeparams &&
1221-
!symtable_exit_block(st)) {
1321+
!symtable_leave_typeparam_overlay(st)) {
12221322
VISIT_QUIT(st, 0);
12231323
}
12241324
break;
@@ -1749,17 +1849,17 @@ symtable_visit_typeparam(struct symtable *st, typeparam_ty tp)
17491849
}
17501850
switch(tp->kind) {
17511851
case TypeVar_kind:
1752-
if (!symtable_add_def(st, tp->v.TypeVar.name, DEF_PARAM, LOCATION(tp)))
1852+
if (!symtable_add_typeparam(st, tp->v.TypeVar.name, LOCATION(tp)))
17531853
VISIT_QUIT(st, 0);
17541854
if (tp->v.TypeVar.bound)
17551855
VISIT(st, expr, tp->v.TypeVar.bound);
17561856
break;
17571857
case TypeVarTuple_kind:
1758-
if (!symtable_add_def(st, tp->v.TypeVarTuple.name, DEF_PARAM, LOCATION(tp)))
1858+
if (!symtable_add_typeparam(st, tp->v.TypeVarTuple.name, LOCATION(tp)))
17591859
VISIT_QUIT(st, 0);
17601860
break;
17611861
case ParamSpec_kind:
1762-
if (!symtable_add_def(st, tp->v.ParamSpec.name, DEF_PARAM, LOCATION(tp)))
1862+
if (!symtable_add_typeparam(st, tp->v.ParamSpec.name, LOCATION(tp)))
17631863
VISIT_QUIT(st, 0);
17641864
break;
17651865
}

0 commit comments

Comments
 (0)
0