Skip to content

Commit 3dfbaf5

Browse files
bpo-32372: Move __debug__ optimization to the AST level. (#4925)
1 parent 1b3029a commit 3dfbaf5

File tree

3 files changed

+47
-52
lines changed

3 files changed

+47
-52
lines changed

Include/compile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name);
7575
#define PY_INVALID_STACK_EFFECT INT_MAX
7676
PyAPI_FUNC(int) PyCompile_OpcodeStackEffect(int opcode, int oparg);
7777

78-
PyAPI_FUNC(int) _PyAST_Optimize(struct _mod *, PyArena *arena);
78+
PyAPI_FUNC(int) _PyAST_Optimize(struct _mod *, PyArena *arena, int optimize);
7979

8080
#ifdef __cplusplus
8181
}

Python/ast_opt.c

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ unary_not(PyObject *v)
7575
}
7676

7777
static int
78-
fold_unaryop(expr_ty node, PyArena *arena)
78+
fold_unaryop(expr_ty node, PyArena *arena, int optimize)
7979
{
8080
expr_ty arg = node->v.UnaryOp.operand;
8181

@@ -252,7 +252,7 @@ safe_mod(PyObject *v, PyObject *w)
252252
}
253253

254254
static int
255-
fold_binop(expr_ty node, PyArena *arena)
255+
fold_binop(expr_ty node, PyArena *arena, int optimize)
256256
{
257257
expr_ty lhs, rhs;
258258
lhs = node->v.BinOp.left;
@@ -334,7 +334,7 @@ make_const_tuple(asdl_seq *elts)
334334
}
335335

336336
static int
337-
fold_tuple(expr_ty node, PyArena *arena)
337+
fold_tuple(expr_ty node, PyArena *arena, int optimize)
338338
{
339339
PyObject *newval;
340340

@@ -346,7 +346,7 @@ fold_tuple(expr_ty node, PyArena *arena)
346346
}
347347

348348
static int
349-
fold_subscr(expr_ty node, PyArena *arena)
349+
fold_subscr(expr_ty node, PyArena *arena, int optimize)
350350
{
351351
PyObject *newval;
352352
expr_ty arg, idx;
@@ -374,7 +374,7 @@ fold_subscr(expr_ty node, PyArena *arena)
374374
in "for" loop and comprehensions.
375375
*/
376376
static int
377-
fold_iter(expr_ty arg, PyArena *arena)
377+
fold_iter(expr_ty arg, PyArena *arena, int optimize)
378378
{
379379
PyObject *newval;
380380
if (arg->kind == List_kind) {
@@ -393,7 +393,7 @@ fold_iter(expr_ty arg, PyArena *arena)
393393
}
394394

395395
static int
396-
fold_compare(expr_ty node, PyArena *arena)
396+
fold_compare(expr_ty node, PyArena *arena, int optimize)
397397
{
398398
asdl_int_seq *ops;
399399
asdl_seq *args;
@@ -407,37 +407,37 @@ fold_compare(expr_ty node, PyArena *arena)
407407
i = asdl_seq_LEN(ops) - 1;
408408
int op = asdl_seq_GET(ops, i);
409409
if (op == In || op == NotIn) {
410-
if (!fold_iter((expr_ty)asdl_seq_GET(args, i), arena)) {
410+
if (!fold_iter((expr_ty)asdl_seq_GET(args, i), arena, optimize)) {
411411
return 0;
412412
}
413413
}
414414
return 1;
415415
}
416416

417-
static int astfold_mod(mod_ty node_, PyArena* ctx_);
418-
static int astfold_stmt(stmt_ty node_, PyArena* ctx_);
419-
static int astfold_expr(expr_ty node_, PyArena* ctx_);
420-
static int astfold_arguments(arguments_ty node_, PyArena* ctx_);
421-
static int astfold_comprehension(comprehension_ty node_, PyArena* ctx_);
422-
static int astfold_keyword(keyword_ty node_, PyArena* ctx_);
423-
static int astfold_slice(slice_ty node_, PyArena* ctx_);
424-
static int astfold_arg(arg_ty node_, PyArena* ctx_);
425-
static int astfold_withitem(withitem_ty node_, PyArena* ctx_);
426-
static int astfold_excepthandler(excepthandler_ty node_, PyArena* ctx_);
417+
static int astfold_mod(mod_ty node_, PyArena *ctx_, int optimize_);
418+
static int astfold_stmt(stmt_ty node_, PyArena *ctx_, int optimize_);
419+
static int astfold_expr(expr_ty node_, PyArena *ctx_, int optimize_);
420+
static int astfold_arguments(arguments_ty node_, PyArena *ctx_, int optimize_);
421+
static int astfold_comprehension(comprehension_ty node_, PyArena *ctx_, int optimize_);
422+
static int astfold_keyword(keyword_ty node_, PyArena *ctx_, int optimize_);
423+
static int astfold_slice(slice_ty node_, PyArena *ctx_, int optimize_);
424+
static int astfold_arg(arg_ty node_, PyArena *ctx_, int optimize_);
425+
static int astfold_withitem(withitem_ty node_, PyArena *ctx_, int optimize_);
426+
static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, int optimize_);
427427
#define CALL(FUNC, TYPE, ARG) \
428-
if (!FUNC((ARG), ctx_)) \
428+
if (!FUNC((ARG), ctx_, optimize_)) \
429429
return 0;
430430

431431
#define CALL_OPT(FUNC, TYPE, ARG) \
432-
if ((ARG) != NULL && !FUNC((ARG), ctx_)) \
432+
if ((ARG) != NULL && !FUNC((ARG), ctx_, optimize_)) \
433433
return 0;
434434

435435
#define CALL_SEQ(FUNC, TYPE, ARG) { \
436436
int i; \
437437
asdl_seq *seq = (ARG); /* avoid variable capture */ \
438438
for (i = 0; i < asdl_seq_LEN(seq); i++) { \
439439
TYPE elt = (TYPE)asdl_seq_GET(seq, i); \
440-
if (elt != NULL && !FUNC(elt, ctx_)) \
440+
if (elt != NULL && !FUNC(elt, ctx_, optimize_)) \
441441
return 0; \
442442
} \
443443
}
@@ -447,13 +447,13 @@ static int astfold_excepthandler(excepthandler_ty node_, PyArena* ctx_);
447447
asdl_int_seq *seq = (ARG); /* avoid variable capture */ \
448448
for (i = 0; i < asdl_seq_LEN(seq); i++) { \
449449
TYPE elt = (TYPE)asdl_seq_GET(seq, i); \
450-
if (!FUNC(elt, ctx_)) \
450+
if (!FUNC(elt, ctx_, optimize_)) \
451451
return 0; \
452452
} \
453453
}
454454

455455
static int
456-
astfold_mod(mod_ty node_, PyArena* ctx_)
456+
astfold_mod(mod_ty node_, PyArena *ctx_, int optimize_)
457457
{
458458
switch (node_->kind) {
459459
case Module_kind:
@@ -475,7 +475,7 @@ astfold_mod(mod_ty node_, PyArena* ctx_)
475475
}
476476

477477
static int
478-
astfold_expr(expr_ty node_, PyArena* ctx_)
478+
astfold_expr(expr_ty node_, PyArena *ctx_, int optimize_)
479479
{
480480
switch (node_->kind) {
481481
case BoolOp_kind:
@@ -567,14 +567,19 @@ astfold_expr(expr_ty node_, PyArena* ctx_)
567567
CALL_SEQ(astfold_expr, expr_ty, node_->v.Tuple.elts);
568568
CALL(fold_tuple, expr_ty, node_);
569569
break;
570+
case Name_kind:
571+
if (_PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) {
572+
return make_const(node_, PyBool_FromLong(!optimize_), ctx_);
573+
}
574+
break;
570575
default:
571576
break;
572577
}
573578
return 1;
574579
}
575580

576581
static int
577-
astfold_slice(slice_ty node_, PyArena* ctx_)
582+
astfold_slice(slice_ty node_, PyArena *ctx_, int optimize_)
578583
{
579584
switch (node_->kind) {
580585
case Slice_kind:
@@ -595,14 +600,14 @@ astfold_slice(slice_ty node_, PyArena* ctx_)
595600
}
596601

597602
static int
598-
astfold_keyword(keyword_ty node_, PyArena* ctx_)
603+
astfold_keyword(keyword_ty node_, PyArena *ctx_, int optimize_)
599604
{
600605
CALL(astfold_expr, expr_ty, node_->value);
601606
return 1;
602607
}
603608

604609
static int
605-
astfold_comprehension(comprehension_ty node_, PyArena* ctx_)
610+
astfold_comprehension(comprehension_ty node_, PyArena *ctx_, int optimize_)
606611
{
607612
CALL(astfold_expr, expr_ty, node_->target);
608613
CALL(astfold_expr, expr_ty, node_->iter);
@@ -613,7 +618,7 @@ astfold_comprehension(comprehension_ty node_, PyArena* ctx_)
613618
}
614619

615620
static int
616-
astfold_arguments(arguments_ty node_, PyArena* ctx_)
621+
astfold_arguments(arguments_ty node_, PyArena *ctx_, int optimize_)
617622
{
618623
CALL_SEQ(astfold_arg, arg_ty, node_->args);
619624
CALL_OPT(astfold_arg, arg_ty, node_->vararg);
@@ -625,14 +630,14 @@ astfold_arguments(arguments_ty node_, PyArena* ctx_)
625630
}
626631

627632
static int
628-
astfold_arg(arg_ty node_, PyArena* ctx_)
633+
astfold_arg(arg_ty node_, PyArena *ctx_, int optimize_)
629634
{
630635
CALL_OPT(astfold_expr, expr_ty, node_->annotation);
631636
return 1;
632637
}
633638

634639
static int
635-
astfold_stmt(stmt_ty node_, PyArena* ctx_)
640+
astfold_stmt(stmt_ty node_, PyArena *ctx_, int optimize_)
636641
{
637642
switch (node_->kind) {
638643
case FunctionDef_kind:
@@ -728,7 +733,7 @@ astfold_stmt(stmt_ty node_, PyArena* ctx_)
728733
}
729734

730735
static int
731-
astfold_excepthandler(excepthandler_ty node_, PyArena* ctx_)
736+
astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, int optimize_)
732737
{
733738
switch (node_->kind) {
734739
case ExceptHandler_kind:
@@ -742,7 +747,7 @@ astfold_excepthandler(excepthandler_ty node_, PyArena* ctx_)
742747
}
743748

744749
static int
745-
astfold_withitem(withitem_ty node_, PyArena* ctx_)
750+
astfold_withitem(withitem_ty node_, PyArena *ctx_, int optimize_)
746751
{
747752
CALL(astfold_expr, expr_ty, node_->context_expr);
748753
CALL_OPT(astfold_expr, expr_ty, node_->optional_vars);
@@ -755,9 +760,9 @@ astfold_withitem(withitem_ty node_, PyArena* ctx_)
755760
#undef CALL_INT_SEQ
756761

757762
int
758-
_PyAST_Optimize(mod_ty mod, PyArena *arena)
763+
_PyAST_Optimize(mod_ty mod, PyArena *arena, int optimize)
759764
{
760-
int ret = astfold_mod(mod, arena);
765+
int ret = astfold_mod(mod, arena, optimize);
761766
assert(ret || PyErr_Occurred());
762767
return ret;
763768
}

Python/compile.c

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ static void compiler_pop_fblock(struct compiler *, enum fblocktype,
191191
static int compiler_in_loop(struct compiler *);
192192

193193
static int inplace_binop(struct compiler *, operator_ty);
194-
static int expr_constant(struct compiler *, expr_ty);
194+
static int expr_constant(expr_ty);
195195

196196
static int compiler_with(struct compiler *, stmt_ty, int);
197197
static int compiler_async_with(struct compiler *, stmt_ty, int);
@@ -331,7 +331,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags,
331331
c.c_optimize = (optimize == -1) ? Py_OptimizeFlag : optimize;
332332
c.c_nestlevel = 0;
333333

334-
if (!_PyAST_Optimize(mod, arena)) {
334+
if (!_PyAST_Optimize(mod, arena, c.c_optimize)) {
335335
goto finally;
336336
}
337337

@@ -1332,15 +1332,13 @@ is_const(expr_ty e)
13321332
case Ellipsis_kind:
13331333
case NameConstant_kind:
13341334
return 1;
1335-
case Name_kind:
1336-
return _PyUnicode_EqualToASCIIString(e->v.Name.id, "__debug__");
13371335
default:
13381336
return 0;
13391337
}
13401338
}
13411339

13421340
static PyObject *
1343-
get_const_value(struct compiler *c, expr_ty e)
1341+
get_const_value(expr_ty e)
13441342
{
13451343
switch (e->kind) {
13461344
case Constant_kind:
@@ -1355,9 +1353,6 @@ get_const_value(struct compiler *c, expr_ty e)
13551353
return Py_Ellipsis;
13561354
case NameConstant_kind:
13571355
return e->v.NameConstant.value;
1358-
case Name_kind:
1359-
assert(_PyUnicode_EqualToASCIIString(e->v.Name.id, "__debug__"));
1360-
return c->c_optimize ? Py_False : Py_True;
13611356
default:
13621357
Py_UNREACHABLE();
13631358
}
@@ -2217,7 +2212,7 @@ compiler_if(struct compiler *c, stmt_ty s)
22172212
if (end == NULL)
22182213
return 0;
22192214

2220-
constant = expr_constant(c, s->v.If.test);
2215+
constant = expr_constant(s->v.If.test);
22212216
/* constant = 0: "if 0"
22222217
* constant = 1: "if 1", "if 2", ...
22232218
* constant = -1: rest */
@@ -2363,7 +2358,7 @@ static int
23632358
compiler_while(struct compiler *c, stmt_ty s)
23642359
{
23652360
basicblock *loop, *orelse, *end, *anchor = NULL;
2366-
int constant = expr_constant(c, s->v.While.test);
2361+
int constant = expr_constant(s->v.While.test);
23672362

23682363
if (constant == 0) {
23692364
if (s->v.While.orelse)
@@ -3098,11 +3093,6 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
30983093
!_PyUnicode_EqualToASCIIString(name, "True") &&
30993094
!_PyUnicode_EqualToASCIIString(name, "False"));
31003095

3101-
if (ctx == Load && _PyUnicode_EqualToASCIIString(name, "__debug__")) {
3102-
ADDOP_O(c, LOAD_CONST, c->c_optimize ? Py_False : Py_True, consts);
3103-
return 1;
3104-
}
3105-
31063096
mangled = _Py_Mangle(c->u->u_private, name);
31073097
if (!mangled)
31083098
return 0;
@@ -3370,7 +3360,7 @@ compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end
33703360
return 0;
33713361
}
33723362
for (i = begin; i < end; i++) {
3373-
key = get_const_value(c, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
3363+
key = get_const_value((expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
33743364
Py_INCREF(key);
33753365
PyTuple_SET_ITEM(keys, i - begin, key);
33763366
}
@@ -4140,10 +4130,10 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k)
41404130
*/
41414131

41424132
static int
4143-
expr_constant(struct compiler *c, expr_ty e)
4133+
expr_constant(expr_ty e)
41444134
{
41454135
if (is_const(e)) {
4146-
return PyObject_IsTrue(get_const_value(c, e));
4136+
return PyObject_IsTrue(get_const_value(e));
41474137
}
41484138
return -1;
41494139
}

0 commit comments

Comments
 (0)