Skip to content

Commit 5521c7d

Browse files
committed
Support inheriting from Generic
1 parent 59e6fa0 commit 5521c7d

File tree

6 files changed

+51
-12
lines changed

6 files changed

+51
-12
lines changed

Include/internal/pycore_global_objects_fini_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct _Py_global_strings {
5252
STRUCT_FOR_STR(open_br, "{")
5353
STRUCT_FOR_STR(percent, "%")
5454
STRUCT_FOR_STR(shim_name, "<shim>")
55+
STRUCT_FOR_STR(type_params, ".type_params")
5556
STRUCT_FOR_STR(utf_8, "utf-8")
5657
} literals;
5758

Include/internal/pycore_intrinsics.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#define INTRINSIC_TYPEVARTUPLE 9
1313
#define INTRINSIC_SUBSCRIPT_GENERIC 10
1414

15-
#define MAX_INTRINSIC_1 9
15+
#define MAX_INTRINSIC_1 10
1616

1717

1818
/* Binary Functions: */

Include/internal/pycore_runtime_init_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/compile.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,8 @@ static int compiler_call_simple_kw_helper(struct compiler *c,
544544
Py_ssize_t nkwelts);
545545
static int compiler_call_helper(struct compiler *c, location loc,
546546
int n, asdl_expr_seq *args,
547-
asdl_keyword_seq *keywords);
547+
asdl_keyword_seq *keywords,
548+
PyObject *extra_positional_arg);
548549
static int compiler_try_except(struct compiler *, stmt_ty);
549550
static int compiler_try_star_except(struct compiler *, stmt_ty);
550551
static int compiler_set_qualname(struct compiler *);
@@ -2361,7 +2362,9 @@ compiler_class(struct compiler *c, stmt_ty s)
23612362
}
23622363
Py_DECREF(typeparams_name);
23632364
RETURN_IF_ERROR(compiler_type_params(c, typeparams));
2364-
ADDOP(c, loc, POP_TOP);
2365+
_Py_DECLARE_STR(type_params, ".type_params");
2366+
RETURN_IF_ERROR(compiler_nameop(c, loc, &_Py_STR(type_params), Store));
2367+
//ADDOP(c, loc, POP_TOP);
23652368
}
23662369

23672370
/* ultimately generate code for:
@@ -2452,11 +2455,14 @@ compiler_class(struct compiler *c, stmt_ty s)
24522455
ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name);
24532456

24542457
/* 5. generate the rest of the code for the call */
2455-
RETURN_IF_ERROR(compiler_call_helper(c, loc, 2,
2456-
s->v.ClassDef.bases,
2457-
s->v.ClassDef.keywords));
24582458

24592459
if (typeparams) {
2460+
_Py_DECLARE_STR(type_params, ".type_params");
2461+
RETURN_IF_ERROR(compiler_call_helper(c, loc, 2,
2462+
s->v.ClassDef.bases,
2463+
s->v.ClassDef.keywords,
2464+
&_Py_STR(type_params)));
2465+
24602466
int is_in_class = c->u->u_ste->ste_type_params_in_class;
24612467
c->u->u_argcount = is_in_class;
24622468
PyCodeObject *co = assemble(c, 0);
@@ -2473,6 +2479,11 @@ compiler_class(struct compiler *c, stmt_ty s)
24732479
ADDOP(c, loc, LOAD_LOCALS);
24742480
}
24752481
ADDOP_I(c, loc, CALL, is_in_class);
2482+
} else {
2483+
RETURN_IF_ERROR(compiler_call_helper(c, loc, 2,
2484+
s->v.ClassDef.bases,
2485+
s->v.ClassDef.keywords,
2486+
NULL));
24762487
}
24772488

24782489
/* 6. apply decorators */
@@ -4575,7 +4586,8 @@ compiler_call(struct compiler *c, expr_ty e)
45754586
loc = LOC(e);
45764587
return compiler_call_helper(c, loc, 0,
45774588
e->v.Call.args,
4578-
e->v.Call.keywords);
4589+
e->v.Call.keywords,
4590+
NULL);
45794591
}
45804592

45814593
static int
@@ -4725,16 +4737,18 @@ static int
47254737
compiler_call_helper(struct compiler *c, location loc,
47264738
int n, /* Args already pushed */
47274739
asdl_expr_seq *args,
4728-
asdl_keyword_seq *keywords)
4740+
asdl_keyword_seq *keywords,
4741+
PyObject *extra_positional_arg)
47294742
{
4730-
Py_ssize_t i, nseen, nelts, nkwelts;
4743+
Py_ssize_t i, nseen, nelts, nkwelts, real_nelts;
47314744

47324745
RETURN_IF_ERROR(validate_keywords(c, keywords));
47334746

47344747
nelts = asdl_seq_LEN(args);
47354748
nkwelts = asdl_seq_LEN(keywords);
4749+
real_nelts = extra_positional_arg == NULL ? nelts : nelts + 1;
47364750

4737-
if (nelts + nkwelts*2 > STACK_USE_GUIDELINE) {
4751+
if (real_nelts + nkwelts*2 > STACK_USE_GUIDELINE) {
47384752
goto ex_call;
47394753
}
47404754
for (i = 0; i < nelts; i++) {
@@ -4756,16 +4770,22 @@ compiler_call_helper(struct compiler *c, location loc,
47564770
assert(elt->kind != Starred_kind);
47574771
VISIT(c, expr, elt);
47584772
}
4773+
if (extra_positional_arg != NULL) {
4774+
RETURN_IF_ERROR(compiler_nameop(c, loc, extra_positional_arg, Load));
4775+
ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_SUBSCRIPT_GENERIC);
4776+
}
47594777
if (nkwelts) {
47604778
VISIT_SEQ(c, keyword, keywords);
47614779
RETURN_IF_ERROR(
47624780
compiler_call_simple_kw_helper(c, loc, keywords, nkwelts));
47634781
}
4764-
ADDOP_I(c, loc, CALL, n + nelts + nkwelts);
4782+
ADDOP_I(c, loc, CALL, n + real_nelts + nkwelts);
47654783
return SUCCESS;
47664784

47674785
ex_call:
47684786

4787+
assert(extra_positional_arg == NULL); // TODO(PEP 695)
4788+
47694789
/* Do positional arguments. */
47704790
if (n ==0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
47714791
VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);

Python/symtable.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,7 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag,
11261126
static int
11271127
symtable_enter_typeparam_block(struct symtable *st, identifier name,
11281128
void *ast, int has_defaults, int has_kwdefaults,
1129+
int is_class,
11291130
int lineno, int col_offset,
11301131
int end_lineno, int end_col_offset)
11311132
{
@@ -1142,6 +1143,19 @@ symtable_enter_typeparam_block(struct symtable *st, identifier name,
11421143
return 0;
11431144
}
11441145
}
1146+
if (is_class) {
1147+
_Py_DECLARE_STR(type_params, ".type_params");
1148+
// It gets "set" when we create the type params tuple and
1149+
// "used" when we build up the bases.
1150+
if (!symtable_add_def(st, &_Py_STR(type_params), DEF_LOCAL,
1151+
lineno, col_offset, end_lineno, end_col_offset)) {
1152+
return 0;
1153+
}
1154+
if (!symtable_add_def(st, &_Py_STR(type_params), USE,
1155+
lineno, col_offset, end_lineno, end_col_offset)) {
1156+
return 0;
1157+
}
1158+
}
11451159
if (has_defaults) {
11461160
_Py_DECLARE_STR(defaults, ".defaults");
11471161
if (!symtable_add_def(st, &_Py_STR(defaults), DEF_PARAM,
@@ -1267,6 +1281,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
12671281
s->v.FunctionDef.args->defaults != NULL,
12681282
has_kwonlydefaults(s->v.FunctionDef.args->kwonlyargs,
12691283
s->v.FunctionDef.args->kw_defaults),
1284+
false,
12701285
LOCATION(s))) {
12711286
VISIT_QUIT(st, 0);
12721287
}
@@ -1298,7 +1313,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
12981313
if (s->v.ClassDef.typeparams) {
12991314
if (!symtable_enter_typeparam_block(st, s->v.ClassDef.name,
13001315
(void *)s->v.ClassDef.typeparams,
1301-
false, false,
1316+
false, false, true,
13021317
LOCATION(s))) {
13031318
VISIT_QUIT(st, 0);
13041319
}
@@ -1558,6 +1573,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
15581573
st, s->v.AsyncFunctionDef.name,
15591574
(void *)s->v.AsyncFunctionDef.typeparams,
15601575
s->v.AsyncFunctionDef.args->defaults != NULL,
1576+
false,
15611577
has_kwonlydefaults(s->v.AsyncFunctionDef.args->kwonlyargs,
15621578
s->v.AsyncFunctionDef.args->kw_defaults),
15631579
LOCATION(s))) {

0 commit comments

Comments
 (0)