blob: 311e0c7a8aa38afcf91148583f1b81e490a6e784 [file] [log] [blame]
INADA Naoki7ea143a2017-12-14 16:47:20 +09001/* AST Optimizer */
2#include "Python.h"
Victor Stinner526fdeb2021-03-17 23:50:50 +01003#include "pycore_ast.h" // _PyAST_GetDocString()
Victor Stinnera81fca62021-03-24 00:51:50 +01004#include "pycore_compile.h" // _PyASTOptimizeState
INADA Naoki7ea143a2017-12-14 16:47:20 +09005
6
INADA Naoki7ea143a2017-12-14 16:47:20 +09007static int
8make_const(expr_ty node, PyObject *val, PyArena *arena)
9{
Nick Coghlan8805a4d2020-11-07 22:35:17 +100010 // Even if no new value was calculated, make_const may still
11 // need to clear an error (e.g. for division by zero)
INADA Naoki7ea143a2017-12-14 16:47:20 +090012 if (val == NULL) {
13 if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) {
14 return 0;
15 }
16 PyErr_Clear();
17 return 1;
18 }
Victor Stinner8370e072021-03-24 02:23:01 +010019 if (_PyArena_AddPyObject(arena, val) < 0) {
INADA Naoki7ea143a2017-12-14 16:47:20 +090020 Py_DECREF(val);
21 return 0;
22 }
23 node->kind = Constant_kind;
Pablo Galindo33986462020-04-14 21:40:41 +010024 node->v.Constant.kind = NULL;
INADA Naoki7ea143a2017-12-14 16:47:20 +090025 node->v.Constant.value = val;
26 return 1;
27}
28
29#define COPY_NODE(TO, FROM) (memcpy((TO), (FROM), sizeof(struct _expr)))
30
31static PyObject*
32unary_not(PyObject *v)
33{
34 int r = PyObject_IsTrue(v);
35 if (r < 0)
36 return NULL;
37 return PyBool_FromLong(!r);
38}
39
40static int
Pablo Galindod112c602020-03-18 23:02:09 +000041fold_unaryop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +090042{
43 expr_ty arg = node->v.UnaryOp.operand;
44
Serhiy Storchaka3f228112018-09-27 17:42:37 +030045 if (arg->kind != Constant_kind) {
INADA Naoki7ea143a2017-12-14 16:47:20 +090046 /* Fold not into comparison */
47 if (node->v.UnaryOp.op == Not && arg->kind == Compare_kind &&
48 asdl_seq_LEN(arg->v.Compare.ops) == 1) {
49 /* Eq and NotEq are often implemented in terms of one another, so
50 folding not (self == other) into self != other breaks implementation
51 of !=. Detecting such cases doesn't seem worthwhile.
52 Python uses </> for 'is subset'/'is superset' operations on sets.
53 They don't satisfy not folding laws. */
Nick Coghlan8805a4d2020-11-07 22:35:17 +100054 cmpop_ty op = asdl_seq_GET(arg->v.Compare.ops, 0);
INADA Naoki7ea143a2017-12-14 16:47:20 +090055 switch (op) {
56 case Is:
57 op = IsNot;
58 break;
59 case IsNot:
60 op = Is;
61 break;
62 case In:
63 op = NotIn;
64 break;
65 case NotIn:
66 op = In;
67 break;
Nick Coghlan8805a4d2020-11-07 22:35:17 +100068 // The remaining comparison operators can't be safely inverted
69 case Eq:
70 case NotEq:
71 case Lt:
72 case LtE:
73 case Gt:
74 case GtE:
75 op = 0; // The AST enums leave "0" free as an "unused" marker
76 break;
77 // No default case, so the compiler will emit a warning if new
78 // comparison operators are added without being handled here
INADA Naoki7ea143a2017-12-14 16:47:20 +090079 }
80 if (op) {
81 asdl_seq_SET(arg->v.Compare.ops, 0, op);
82 COPY_NODE(node, arg);
83 return 1;
84 }
85 }
86 return 1;
87 }
88
89 typedef PyObject *(*unary_op)(PyObject*);
90 static const unary_op ops[] = {
91 [Invert] = PyNumber_Invert,
92 [Not] = unary_not,
93 [UAdd] = PyNumber_Positive,
94 [USub] = PyNumber_Negative,
95 };
Serhiy Storchaka3f228112018-09-27 17:42:37 +030096 PyObject *newval = ops[node->v.UnaryOp.op](arg->v.Constant.value);
INADA Naoki7ea143a2017-12-14 16:47:20 +090097 return make_const(node, newval, arena);
98}
99
Serhiy Storchaka2e3f5702017-12-15 14:11:43 +0200100/* Check whether a collection doesn't containing too much items (including
101 subcollections). This protects from creating a constant that needs
102 too much time for calculating a hash.
103 "limit" is the maximal number of items.
104 Returns the negative number if the total number of items exceeds the
105 limit. Otherwise returns the limit minus the total number of items.
106*/
107
108static Py_ssize_t
109check_complexity(PyObject *obj, Py_ssize_t limit)
110{
111 if (PyTuple_Check(obj)) {
112 Py_ssize_t i;
113 limit -= PyTuple_GET_SIZE(obj);
114 for (i = 0; limit >= 0 && i < PyTuple_GET_SIZE(obj); i++) {
115 limit = check_complexity(PyTuple_GET_ITEM(obj, i), limit);
116 }
117 return limit;
118 }
119 else if (PyFrozenSet_Check(obj)) {
120 Py_ssize_t i = 0;
121 PyObject *item;
122 Py_hash_t hash;
123 limit -= PySet_GET_SIZE(obj);
124 while (limit >= 0 && _PySet_NextEntry(obj, &i, &item, &hash)) {
125 limit = check_complexity(item, limit);
126 }
127 }
128 return limit;
129}
130
131#define MAX_INT_SIZE 128 /* bits */
132#define MAX_COLLECTION_SIZE 256 /* items */
133#define MAX_STR_SIZE 4096 /* characters */
134#define MAX_TOTAL_ITEMS 1024 /* including nested collections */
135
136static PyObject *
137safe_multiply(PyObject *v, PyObject *w)
138{
139 if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) {
140 size_t vbits = _PyLong_NumBits(v);
141 size_t wbits = _PyLong_NumBits(w);
142 if (vbits == (size_t)-1 || wbits == (size_t)-1) {
143 return NULL;
144 }
145 if (vbits + wbits > MAX_INT_SIZE) {
146 return NULL;
147 }
148 }
149 else if (PyLong_Check(v) && (PyTuple_Check(w) || PyFrozenSet_Check(w))) {
150 Py_ssize_t size = PyTuple_Check(w) ? PyTuple_GET_SIZE(w) :
151 PySet_GET_SIZE(w);
152 if (size) {
153 long n = PyLong_AsLong(v);
154 if (n < 0 || n > MAX_COLLECTION_SIZE / size) {
155 return NULL;
156 }
157 if (n && check_complexity(w, MAX_TOTAL_ITEMS / n) < 0) {
158 return NULL;
159 }
160 }
161 }
162 else if (PyLong_Check(v) && (PyUnicode_Check(w) || PyBytes_Check(w))) {
163 Py_ssize_t size = PyUnicode_Check(w) ? PyUnicode_GET_LENGTH(w) :
164 PyBytes_GET_SIZE(w);
165 if (size) {
166 long n = PyLong_AsLong(v);
167 if (n < 0 || n > MAX_STR_SIZE / size) {
168 return NULL;
169 }
170 }
171 }
172 else if (PyLong_Check(w) &&
173 (PyTuple_Check(v) || PyFrozenSet_Check(v) ||
174 PyUnicode_Check(v) || PyBytes_Check(v)))
175 {
176 return safe_multiply(w, v);
177 }
178
179 return PyNumber_Multiply(v, w);
180}
181
182static PyObject *
183safe_power(PyObject *v, PyObject *w)
184{
185 if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w) > 0) {
186 size_t vbits = _PyLong_NumBits(v);
187 size_t wbits = PyLong_AsSize_t(w);
188 if (vbits == (size_t)-1 || wbits == (size_t)-1) {
189 return NULL;
190 }
191 if (vbits > MAX_INT_SIZE / wbits) {
192 return NULL;
193 }
194 }
195
196 return PyNumber_Power(v, w, Py_None);
197}
198
199static PyObject *
200safe_lshift(PyObject *v, PyObject *w)
201{
202 if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) {
203 size_t vbits = _PyLong_NumBits(v);
204 size_t wbits = PyLong_AsSize_t(w);
205 if (vbits == (size_t)-1 || wbits == (size_t)-1) {
206 return NULL;
207 }
208 if (wbits > MAX_INT_SIZE || vbits > MAX_INT_SIZE - wbits) {
209 return NULL;
210 }
211 }
212
213 return PyNumber_Lshift(v, w);
214}
215
216static PyObject *
217safe_mod(PyObject *v, PyObject *w)
218{
219 if (PyUnicode_Check(v) || PyBytes_Check(v)) {
220 return NULL;
221 }
222
223 return PyNumber_Remainder(v, w);
224}
225
INADA Naoki7ea143a2017-12-14 16:47:20 +0900226static int
Pablo Galindod112c602020-03-18 23:02:09 +0000227fold_binop(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900228{
229 expr_ty lhs, rhs;
230 lhs = node->v.BinOp.left;
231 rhs = node->v.BinOp.right;
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300232 if (lhs->kind != Constant_kind || rhs->kind != Constant_kind) {
INADA Naoki7ea143a2017-12-14 16:47:20 +0900233 return 1;
234 }
235
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300236 PyObject *lv = lhs->v.Constant.value;
237 PyObject *rv = rhs->v.Constant.value;
Nick Coghlan8805a4d2020-11-07 22:35:17 +1000238 PyObject *newval = NULL;
INADA Naoki7ea143a2017-12-14 16:47:20 +0900239
240 switch (node->v.BinOp.op) {
241 case Add:
242 newval = PyNumber_Add(lv, rv);
243 break;
244 case Sub:
245 newval = PyNumber_Subtract(lv, rv);
246 break;
247 case Mult:
Serhiy Storchaka2e3f5702017-12-15 14:11:43 +0200248 newval = safe_multiply(lv, rv);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900249 break;
250 case Div:
251 newval = PyNumber_TrueDivide(lv, rv);
252 break;
253 case FloorDiv:
254 newval = PyNumber_FloorDivide(lv, rv);
255 break;
256 case Mod:
Serhiy Storchaka2e3f5702017-12-15 14:11:43 +0200257 newval = safe_mod(lv, rv);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900258 break;
259 case Pow:
Serhiy Storchaka2e3f5702017-12-15 14:11:43 +0200260 newval = safe_power(lv, rv);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900261 break;
262 case LShift:
Serhiy Storchaka2e3f5702017-12-15 14:11:43 +0200263 newval = safe_lshift(lv, rv);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900264 break;
265 case RShift:
266 newval = PyNumber_Rshift(lv, rv);
267 break;
268 case BitOr:
269 newval = PyNumber_Or(lv, rv);
270 break;
271 case BitXor:
272 newval = PyNumber_Xor(lv, rv);
273 break;
274 case BitAnd:
275 newval = PyNumber_And(lv, rv);
276 break;
Nick Coghlan8805a4d2020-11-07 22:35:17 +1000277 // No builtin constants implement the following operators
278 case MatMult:
INADA Naoki7ea143a2017-12-14 16:47:20 +0900279 return 1;
Nick Coghlan8805a4d2020-11-07 22:35:17 +1000280 // No default case, so the compiler will emit a warning if new binary
281 // operators are added without being handled here
INADA Naoki7ea143a2017-12-14 16:47:20 +0900282 }
283
INADA Naoki7ea143a2017-12-14 16:47:20 +0900284 return make_const(node, newval, arena);
285}
286
287static PyObject*
Pablo Galindoa5634c42020-09-16 19:42:00 +0100288make_const_tuple(asdl_expr_seq *elts)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900289{
290 for (int i = 0; i < asdl_seq_LEN(elts); i++) {
291 expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300292 if (e->kind != Constant_kind) {
INADA Naoki7ea143a2017-12-14 16:47:20 +0900293 return NULL;
294 }
295 }
296
297 PyObject *newval = PyTuple_New(asdl_seq_LEN(elts));
298 if (newval == NULL) {
299 return NULL;
300 }
301
302 for (int i = 0; i < asdl_seq_LEN(elts); i++) {
303 expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300304 PyObject *v = e->v.Constant.value;
INADA Naoki7ea143a2017-12-14 16:47:20 +0900305 Py_INCREF(v);
306 PyTuple_SET_ITEM(newval, i, v);
307 }
INADA Naoki7ea143a2017-12-14 16:47:20 +0900308 return newval;
309}
310
311static int
Pablo Galindod112c602020-03-18 23:02:09 +0000312fold_tuple(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900313{
314 PyObject *newval;
315
316 if (node->v.Tuple.ctx != Load)
317 return 1;
318
Serhiy Storchaka15a87282017-12-14 20:24:31 +0200319 newval = make_const_tuple(node->v.Tuple.elts);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900320 return make_const(node, newval, arena);
321}
322
323static int
Pablo Galindod112c602020-03-18 23:02:09 +0000324fold_subscr(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900325{
326 PyObject *newval;
327 expr_ty arg, idx;
INADA Naoki7ea143a2017-12-14 16:47:20 +0900328
329 arg = node->v.Subscript.value;
Serhiy Storchaka13d52c22020-03-10 18:52:34 +0200330 idx = node->v.Subscript.slice;
INADA Naoki7ea143a2017-12-14 16:47:20 +0900331 if (node->v.Subscript.ctx != Load ||
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300332 arg->kind != Constant_kind ||
Serhiy Storchaka13d52c22020-03-10 18:52:34 +0200333 idx->kind != Constant_kind)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900334 {
335 return 1;
336 }
337
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300338 newval = PyObject_GetItem(arg->v.Constant.value, idx->v.Constant.value);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900339 return make_const(node, newval, arena);
340}
341
Serhiy Storchaka15a87282017-12-14 20:24:31 +0200342/* Change literal list or set of constants into constant
Serhiy Storchaka3f7e9aa2018-03-11 10:54:47 +0200343 tuple or frozenset respectively. Change literal list of
344 non-constants into tuple.
Serhiy Storchaka15a87282017-12-14 20:24:31 +0200345 Used for right operand of "in" and "not in" tests and for iterable
346 in "for" loop and comprehensions.
347*/
348static int
Pablo Galindod112c602020-03-18 23:02:09 +0000349fold_iter(expr_ty arg, PyArena *arena, _PyASTOptimizeState *state)
Serhiy Storchaka15a87282017-12-14 20:24:31 +0200350{
351 PyObject *newval;
352 if (arg->kind == List_kind) {
Serhiy Storchaka3f7e9aa2018-03-11 10:54:47 +0200353 /* First change a list into tuple. */
Pablo Galindoa5634c42020-09-16 19:42:00 +0100354 asdl_expr_seq *elts = arg->v.List.elts;
Serhiy Storchaka3f7e9aa2018-03-11 10:54:47 +0200355 Py_ssize_t n = asdl_seq_LEN(elts);
356 for (Py_ssize_t i = 0; i < n; i++) {
357 expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
358 if (e->kind == Starred_kind) {
359 return 1;
360 }
361 }
362 expr_context_ty ctx = arg->v.List.ctx;
363 arg->kind = Tuple_kind;
364 arg->v.Tuple.elts = elts;
365 arg->v.Tuple.ctx = ctx;
366 /* Try to create a constant tuple. */
367 newval = make_const_tuple(elts);
Serhiy Storchaka15a87282017-12-14 20:24:31 +0200368 }
369 else if (arg->kind == Set_kind) {
370 newval = make_const_tuple(arg->v.Set.elts);
371 if (newval) {
372 Py_SETREF(newval, PyFrozenSet_New(newval));
373 }
374 }
375 else {
376 return 1;
377 }
378 return make_const(arg, newval, arena);
379}
380
INADA Naoki7ea143a2017-12-14 16:47:20 +0900381static int
Pablo Galindod112c602020-03-18 23:02:09 +0000382fold_compare(expr_ty node, PyArena *arena, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900383{
384 asdl_int_seq *ops;
Pablo Galindoa5634c42020-09-16 19:42:00 +0100385 asdl_expr_seq *args;
Victor Stinner05d68a82018-01-18 11:15:25 +0100386 Py_ssize_t i;
INADA Naoki7ea143a2017-12-14 16:47:20 +0900387
388 ops = node->v.Compare.ops;
389 args = node->v.Compare.comparators;
390 /* TODO: optimize cases with literal arguments. */
Serhiy Storchaka15a87282017-12-14 20:24:31 +0200391 /* Change literal list or set in 'in' or 'not in' into
392 tuple or frozenset respectively. */
393 i = asdl_seq_LEN(ops) - 1;
394 int op = asdl_seq_GET(ops, i);
395 if (op == In || op == NotIn) {
Pablo Galindod112c602020-03-18 23:02:09 +0000396 if (!fold_iter((expr_ty)asdl_seq_GET(args, i), arena, state)) {
Serhiy Storchaka15a87282017-12-14 20:24:31 +0200397 return 0;
398 }
INADA Naoki7ea143a2017-12-14 16:47:20 +0900399 }
400 return 1;
401}
402
Pablo Galindod112c602020-03-18 23:02:09 +0000403static int astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
404static int astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
405static int astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
406static int astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
407static int astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
408static int astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
Pablo Galindod112c602020-03-18 23:02:09 +0000409static int astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
410static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
Brandt Bucher145bf262021-02-26 14:51:55 -0800411static int astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
412static int astfold_pattern(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
413
INADA Naoki7ea143a2017-12-14 16:47:20 +0900414#define CALL(FUNC, TYPE, ARG) \
Pablo Galindod112c602020-03-18 23:02:09 +0000415 if (!FUNC((ARG), ctx_, state)) \
INADA Naoki7ea143a2017-12-14 16:47:20 +0900416 return 0;
417
418#define CALL_OPT(FUNC, TYPE, ARG) \
Pablo Galindod112c602020-03-18 23:02:09 +0000419 if ((ARG) != NULL && !FUNC((ARG), ctx_, state)) \
INADA Naoki7ea143a2017-12-14 16:47:20 +0900420 return 0;
421
422#define CALL_SEQ(FUNC, TYPE, ARG) { \
423 int i; \
Pablo Galindoa5634c42020-09-16 19:42:00 +0100424 asdl_ ## TYPE ## _seq *seq = (ARG); /* avoid variable capture */ \
INADA Naoki7ea143a2017-12-14 16:47:20 +0900425 for (i = 0; i < asdl_seq_LEN(seq); i++) { \
Pablo Galindoa5634c42020-09-16 19:42:00 +0100426 TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \
Pablo Galindod112c602020-03-18 23:02:09 +0000427 if (elt != NULL && !FUNC(elt, ctx_, state)) \
INADA Naoki7ea143a2017-12-14 16:47:20 +0900428 return 0; \
429 } \
430}
431
432#define CALL_INT_SEQ(FUNC, TYPE, ARG) { \
433 int i; \
434 asdl_int_seq *seq = (ARG); /* avoid variable capture */ \
435 for (i = 0; i < asdl_seq_LEN(seq); i++) { \
436 TYPE elt = (TYPE)asdl_seq_GET(seq, i); \
Pablo Galindod112c602020-03-18 23:02:09 +0000437 if (!FUNC(elt, ctx_, state)) \
INADA Naoki7ea143a2017-12-14 16:47:20 +0900438 return 0; \
439 } \
440}
441
442static int
Pablo Galindoa5634c42020-09-16 19:42:00 +0100443astfold_body(asdl_stmt_seq *stmts, PyArena *ctx_, _PyASTOptimizeState *state)
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300444{
Serhiy Storchaka143ce5c2018-05-30 10:56:16 +0300445 int docstring = _PyAST_GetDocString(stmts) != NULL;
Pablo Galindoa5634c42020-09-16 19:42:00 +0100446 CALL_SEQ(astfold_stmt, stmt, stmts);
Serhiy Storchaka143ce5c2018-05-30 10:56:16 +0300447 if (!docstring && _PyAST_GetDocString(stmts) != NULL) {
448 stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100449 asdl_expr_seq *values = _Py_asdl_expr_seq_new(1, ctx_);
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300450 if (!values) {
451 return 0;
452 }
453 asdl_seq_SET(values, 0, st->v.Expr.value);
Victor Stinnerd27f8d22021-04-07 21:34:22 +0200454 expr_ty expr = _PyAST_JoinedStr(values, st->lineno, st->col_offset,
455 st->end_lineno, st->end_col_offset,
456 ctx_);
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300457 if (!expr) {
458 return 0;
459 }
460 st->v.Expr.value = expr;
461 }
462 return 1;
463}
464
465static int
Pablo Galindod112c602020-03-18 23:02:09 +0000466astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900467{
468 switch (node_->kind) {
469 case Module_kind:
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300470 CALL(astfold_body, asdl_seq, node_->v.Module.body);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900471 break;
472 case Interactive_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100473 CALL_SEQ(astfold_stmt, stmt, node_->v.Interactive.body);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900474 break;
475 case Expression_kind:
476 CALL(astfold_expr, expr_ty, node_->v.Expression.body);
477 break;
Nick Coghlan8805a4d2020-11-07 22:35:17 +1000478 // The following top level nodes don't participate in constant folding
479 case FunctionType_kind:
INADA Naoki7ea143a2017-12-14 16:47:20 +0900480 break;
Nick Coghlan8805a4d2020-11-07 22:35:17 +1000481 // No default case, so the compiler will emit a warning if new top level
482 // compilation nodes are added without being handled here
INADA Naoki7ea143a2017-12-14 16:47:20 +0900483 }
484 return 1;
485}
486
487static int
Pablo Galindod112c602020-03-18 23:02:09 +0000488astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900489{
490 switch (node_->kind) {
491 case BoolOp_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100492 CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900493 break;
494 case BinOp_kind:
495 CALL(astfold_expr, expr_ty, node_->v.BinOp.left);
496 CALL(astfold_expr, expr_ty, node_->v.BinOp.right);
497 CALL(fold_binop, expr_ty, node_);
498 break;
499 case UnaryOp_kind:
500 CALL(astfold_expr, expr_ty, node_->v.UnaryOp.operand);
501 CALL(fold_unaryop, expr_ty, node_);
502 break;
503 case Lambda_kind:
504 CALL(astfold_arguments, arguments_ty, node_->v.Lambda.args);
505 CALL(astfold_expr, expr_ty, node_->v.Lambda.body);
506 break;
507 case IfExp_kind:
508 CALL(astfold_expr, expr_ty, node_->v.IfExp.test);
509 CALL(astfold_expr, expr_ty, node_->v.IfExp.body);
510 CALL(astfold_expr, expr_ty, node_->v.IfExp.orelse);
511 break;
512 case Dict_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100513 CALL_SEQ(astfold_expr, expr, node_->v.Dict.keys);
514 CALL_SEQ(astfold_expr, expr, node_->v.Dict.values);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900515 break;
516 case Set_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100517 CALL_SEQ(astfold_expr, expr, node_->v.Set.elts);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900518 break;
519 case ListComp_kind:
520 CALL(astfold_expr, expr_ty, node_->v.ListComp.elt);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100521 CALL_SEQ(astfold_comprehension, comprehension, node_->v.ListComp.generators);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900522 break;
523 case SetComp_kind:
524 CALL(astfold_expr, expr_ty, node_->v.SetComp.elt);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100525 CALL_SEQ(astfold_comprehension, comprehension, node_->v.SetComp.generators);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900526 break;
527 case DictComp_kind:
528 CALL(astfold_expr, expr_ty, node_->v.DictComp.key);
529 CALL(astfold_expr, expr_ty, node_->v.DictComp.value);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100530 CALL_SEQ(astfold_comprehension, comprehension, node_->v.DictComp.generators);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900531 break;
532 case GeneratorExp_kind:
533 CALL(astfold_expr, expr_ty, node_->v.GeneratorExp.elt);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100534 CALL_SEQ(astfold_comprehension, comprehension, node_->v.GeneratorExp.generators);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900535 break;
536 case Await_kind:
537 CALL(astfold_expr, expr_ty, node_->v.Await.value);
538 break;
539 case Yield_kind:
540 CALL_OPT(astfold_expr, expr_ty, node_->v.Yield.value);
541 break;
542 case YieldFrom_kind:
543 CALL(astfold_expr, expr_ty, node_->v.YieldFrom.value);
544 break;
545 case Compare_kind:
546 CALL(astfold_expr, expr_ty, node_->v.Compare.left);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100547 CALL_SEQ(astfold_expr, expr, node_->v.Compare.comparators);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900548 CALL(fold_compare, expr_ty, node_);
549 break;
550 case Call_kind:
551 CALL(astfold_expr, expr_ty, node_->v.Call.func);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100552 CALL_SEQ(astfold_expr, expr, node_->v.Call.args);
553 CALL_SEQ(astfold_keyword, keyword, node_->v.Call.keywords);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900554 break;
555 case FormattedValue_kind:
556 CALL(astfold_expr, expr_ty, node_->v.FormattedValue.value);
557 CALL_OPT(astfold_expr, expr_ty, node_->v.FormattedValue.format_spec);
558 break;
559 case JoinedStr_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100560 CALL_SEQ(astfold_expr, expr, node_->v.JoinedStr.values);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900561 break;
562 case Attribute_kind:
563 CALL(astfold_expr, expr_ty, node_->v.Attribute.value);
564 break;
565 case Subscript_kind:
566 CALL(astfold_expr, expr_ty, node_->v.Subscript.value);
Serhiy Storchaka13d52c22020-03-10 18:52:34 +0200567 CALL(astfold_expr, expr_ty, node_->v.Subscript.slice);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900568 CALL(fold_subscr, expr_ty, node_);
569 break;
570 case Starred_kind:
571 CALL(astfold_expr, expr_ty, node_->v.Starred.value);
572 break;
Serhiy Storchaka13d52c22020-03-10 18:52:34 +0200573 case Slice_kind:
574 CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.lower);
575 CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.upper);
576 CALL_OPT(astfold_expr, expr_ty, node_->v.Slice.step);
577 break;
INADA Naoki7ea143a2017-12-14 16:47:20 +0900578 case List_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100579 CALL_SEQ(astfold_expr, expr, node_->v.List.elts);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900580 break;
581 case Tuple_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100582 CALL_SEQ(astfold_expr, expr, node_->v.Tuple.elts);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900583 CALL(fold_tuple, expr_ty, node_);
584 break;
Serhiy Storchaka3dfbaf52017-12-25 12:47:50 +0200585 case Name_kind:
Pablo Galindoc5fc1562020-04-22 23:29:27 +0100586 if (node_->v.Name.ctx == Load &&
587 _PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) {
Pablo Galindod112c602020-03-18 23:02:09 +0000588 return make_const(node_, PyBool_FromLong(!state->optimize), ctx_);
Serhiy Storchaka3dfbaf52017-12-25 12:47:50 +0200589 }
590 break;
Nick Coghlan8805a4d2020-11-07 22:35:17 +1000591 case NamedExpr_kind:
592 CALL(astfold_expr, expr_ty, node_->v.NamedExpr.value);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900593 break;
Nick Coghlan8805a4d2020-11-07 22:35:17 +1000594 case Constant_kind:
595 // Already a constant, nothing further to do
596 break;
Brandt Bucher145bf262021-02-26 14:51:55 -0800597 case MatchAs_kind:
598 case MatchOr_kind:
599 // These can't occur outside of patterns.
600 Py_UNREACHABLE();
Nick Coghlan8805a4d2020-11-07 22:35:17 +1000601 // No default case, so the compiler will emit a warning if new expression
602 // kinds are added without being handled here
INADA Naoki7ea143a2017-12-14 16:47:20 +0900603 }
604 return 1;
605}
606
607static int
Pablo Galindod112c602020-03-18 23:02:09 +0000608astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900609{
610 CALL(astfold_expr, expr_ty, node_->value);
611 return 1;
612}
613
614static int
Pablo Galindod112c602020-03-18 23:02:09 +0000615astfold_comprehension(comprehension_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900616{
617 CALL(astfold_expr, expr_ty, node_->target);
618 CALL(astfold_expr, expr_ty, node_->iter);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100619 CALL_SEQ(astfold_expr, expr, node_->ifs);
Serhiy Storchaka15a87282017-12-14 20:24:31 +0200620
621 CALL(fold_iter, expr_ty, node_->iter);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900622 return 1;
623}
624
625static int
Pablo Galindod112c602020-03-18 23:02:09 +0000626astfold_arguments(arguments_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900627{
Pablo Galindoa5634c42020-09-16 19:42:00 +0100628 CALL_SEQ(astfold_expr, expr, node_->kw_defaults);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100629 CALL_SEQ(astfold_expr, expr, node_->defaults);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900630 return 1;
631}
632
633static int
Pablo Galindod112c602020-03-18 23:02:09 +0000634astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900635{
636 switch (node_->kind) {
637 case FunctionDef_kind:
638 CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args);
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300639 CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100640 CALL_SEQ(astfold_expr, expr, node_->v.FunctionDef.decorator_list);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900641 break;
642 case AsyncFunctionDef_kind:
643 CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args);
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300644 CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100645 CALL_SEQ(astfold_expr, expr, node_->v.AsyncFunctionDef.decorator_list);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900646 break;
647 case ClassDef_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100648 CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.bases);
649 CALL_SEQ(astfold_keyword, keyword, node_->v.ClassDef.keywords);
Serhiy Storchaka73cbe7a2018-05-29 12:04:55 +0300650 CALL(astfold_body, asdl_seq, node_->v.ClassDef.body);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100651 CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.decorator_list);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900652 break;
653 case Return_kind:
654 CALL_OPT(astfold_expr, expr_ty, node_->v.Return.value);
655 break;
656 case Delete_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100657 CALL_SEQ(astfold_expr, expr, node_->v.Delete.targets);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900658 break;
659 case Assign_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100660 CALL_SEQ(astfold_expr, expr, node_->v.Assign.targets);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900661 CALL(astfold_expr, expr_ty, node_->v.Assign.value);
662 break;
663 case AugAssign_kind:
664 CALL(astfold_expr, expr_ty, node_->v.AugAssign.target);
665 CALL(astfold_expr, expr_ty, node_->v.AugAssign.value);
666 break;
667 case AnnAssign_kind:
668 CALL(astfold_expr, expr_ty, node_->v.AnnAssign.target);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900669 CALL_OPT(astfold_expr, expr_ty, node_->v.AnnAssign.value);
670 break;
671 case For_kind:
672 CALL(astfold_expr, expr_ty, node_->v.For.target);
673 CALL(astfold_expr, expr_ty, node_->v.For.iter);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100674 CALL_SEQ(astfold_stmt, stmt, node_->v.For.body);
675 CALL_SEQ(astfold_stmt, stmt, node_->v.For.orelse);
Serhiy Storchaka15a87282017-12-14 20:24:31 +0200676
677 CALL(fold_iter, expr_ty, node_->v.For.iter);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900678 break;
679 case AsyncFor_kind:
680 CALL(astfold_expr, expr_ty, node_->v.AsyncFor.target);
681 CALL(astfold_expr, expr_ty, node_->v.AsyncFor.iter);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100682 CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.body);
683 CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncFor.orelse);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900684 break;
685 case While_kind:
686 CALL(astfold_expr, expr_ty, node_->v.While.test);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100687 CALL_SEQ(astfold_stmt, stmt, node_->v.While.body);
688 CALL_SEQ(astfold_stmt, stmt, node_->v.While.orelse);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900689 break;
690 case If_kind:
691 CALL(astfold_expr, expr_ty, node_->v.If.test);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100692 CALL_SEQ(astfold_stmt, stmt, node_->v.If.body);
693 CALL_SEQ(astfold_stmt, stmt, node_->v.If.orelse);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900694 break;
695 case With_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100696 CALL_SEQ(astfold_withitem, withitem, node_->v.With.items);
697 CALL_SEQ(astfold_stmt, stmt, node_->v.With.body);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900698 break;
699 case AsyncWith_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100700 CALL_SEQ(astfold_withitem, withitem, node_->v.AsyncWith.items);
701 CALL_SEQ(astfold_stmt, stmt, node_->v.AsyncWith.body);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900702 break;
703 case Raise_kind:
704 CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.exc);
705 CALL_OPT(astfold_expr, expr_ty, node_->v.Raise.cause);
706 break;
707 case Try_kind:
Pablo Galindoa5634c42020-09-16 19:42:00 +0100708 CALL_SEQ(astfold_stmt, stmt, node_->v.Try.body);
709 CALL_SEQ(astfold_excepthandler, excepthandler, node_->v.Try.handlers);
710 CALL_SEQ(astfold_stmt, stmt, node_->v.Try.orelse);
711 CALL_SEQ(astfold_stmt, stmt, node_->v.Try.finalbody);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900712 break;
713 case Assert_kind:
714 CALL(astfold_expr, expr_ty, node_->v.Assert.test);
715 CALL_OPT(astfold_expr, expr_ty, node_->v.Assert.msg);
716 break;
717 case Expr_kind:
718 CALL(astfold_expr, expr_ty, node_->v.Expr.value);
719 break;
Brandt Bucher145bf262021-02-26 14:51:55 -0800720 case Match_kind:
721 CALL(astfold_expr, expr_ty, node_->v.Match.subject);
722 CALL_SEQ(astfold_match_case, match_case, node_->v.Match.cases);
723 break;
Nick Coghlan8805a4d2020-11-07 22:35:17 +1000724 // The following statements don't contain any subexpressions to be folded
725 case Import_kind:
726 case ImportFrom_kind:
727 case Global_kind:
728 case Nonlocal_kind:
729 case Pass_kind:
730 case Break_kind:
731 case Continue_kind:
INADA Naoki7ea143a2017-12-14 16:47:20 +0900732 break;
Nick Coghlan8805a4d2020-11-07 22:35:17 +1000733 // No default case, so the compiler will emit a warning if new statement
734 // kinds are added without being handled here
INADA Naoki7ea143a2017-12-14 16:47:20 +0900735 }
736 return 1;
737}
738
739static int
Pablo Galindod112c602020-03-18 23:02:09 +0000740astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900741{
742 switch (node_->kind) {
743 case ExceptHandler_kind:
744 CALL_OPT(astfold_expr, expr_ty, node_->v.ExceptHandler.type);
Pablo Galindoa5634c42020-09-16 19:42:00 +0100745 CALL_SEQ(astfold_stmt, stmt, node_->v.ExceptHandler.body);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900746 break;
Nick Coghlan8805a4d2020-11-07 22:35:17 +1000747 // No default case, so the compiler will emit a warning if new handler
748 // kinds are added without being handled here
INADA Naoki7ea143a2017-12-14 16:47:20 +0900749 }
750 return 1;
751}
752
753static int
Pablo Galindod112c602020-03-18 23:02:09 +0000754astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900755{
756 CALL(astfold_expr, expr_ty, node_->context_expr);
757 CALL_OPT(astfold_expr, expr_ty, node_->optional_vars);
758 return 1;
759}
760
Brandt Bucher145bf262021-02-26 14:51:55 -0800761static int
762astfold_pattern_negative(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
763{
764 assert(node_->kind == UnaryOp_kind);
765 assert(node_->v.UnaryOp.op == USub);
766 assert(node_->v.UnaryOp.operand->kind == Constant_kind);
767 PyObject *value = node_->v.UnaryOp.operand->v.Constant.value;
768 assert(PyComplex_CheckExact(value) ||
769 PyFloat_CheckExact(value) ||
770 PyLong_CheckExact(value));
771 PyObject *negated = PyNumber_Negative(value);
772 if (negated == NULL) {
773 return 0;
774 }
775 assert(PyComplex_CheckExact(negated) ||
776 PyFloat_CheckExact(negated) ||
777 PyLong_CheckExact(negated));
778 return make_const(node_, negated, ctx_);
779}
780
781static int
782astfold_pattern_complex(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
783{
784 expr_ty left = node_->v.BinOp.left;
785 expr_ty right = node_->v.BinOp.right;
786 if (left->kind == UnaryOp_kind) {
787 CALL(astfold_pattern_negative, expr_ty, left);
788 }
789 assert(left->kind = Constant_kind);
790 assert(right->kind = Constant_kind);
791 // LHS must be real, RHS must be imaginary:
792 if (!(PyFloat_CheckExact(left->v.Constant.value) ||
793 PyLong_CheckExact(left->v.Constant.value)) ||
794 !PyComplex_CheckExact(right->v.Constant.value))
795 {
796 // Not actually valid, but it's the compiler's job to complain:
797 return 1;
798 }
799 PyObject *new;
800 if (node_->v.BinOp.op == Add) {
801 new = PyNumber_Add(left->v.Constant.value, right->v.Constant.value);
802 }
803 else {
804 assert(node_->v.BinOp.op == Sub);
805 new = PyNumber_Subtract(left->v.Constant.value, right->v.Constant.value);
806 }
807 if (new == NULL) {
808 return 0;
809 }
810 assert(PyComplex_CheckExact(new));
811 return make_const(node_, new, ctx_);
812}
813
814static int
815astfold_pattern_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
816{
817 CALL(astfold_pattern, expr_ty, node_->value);
818 return 1;
819}
820
821static int
822astfold_pattern(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
823{
824 // Don't blindly optimize the pattern as an expr; it plays by its own rules!
825 // Currently, this is only used to form complex/negative numeric constants.
826 switch (node_->kind) {
827 case Attribute_kind:
828 break;
829 case BinOp_kind:
830 CALL(astfold_pattern_complex, expr_ty, node_);
831 break;
832 case Call_kind:
833 CALL_SEQ(astfold_pattern, expr, node_->v.Call.args);
834 CALL_SEQ(astfold_pattern_keyword, keyword, node_->v.Call.keywords);
835 break;
836 case Constant_kind:
837 break;
838 case Dict_kind:
839 CALL_SEQ(astfold_pattern, expr, node_->v.Dict.keys);
840 CALL_SEQ(astfold_pattern, expr, node_->v.Dict.values);
841 break;
842 // Not actually valid, but it's the compiler's job to complain:
843 case JoinedStr_kind:
844 break;
845 case List_kind:
846 CALL_SEQ(astfold_pattern, expr, node_->v.List.elts);
847 break;
848 case MatchAs_kind:
849 CALL(astfold_pattern, expr_ty, node_->v.MatchAs.pattern);
850 break;
851 case MatchOr_kind:
852 CALL_SEQ(astfold_pattern, expr, node_->v.MatchOr.patterns);
853 break;
854 case Name_kind:
855 break;
856 case Starred_kind:
857 CALL(astfold_pattern, expr_ty, node_->v.Starred.value);
858 break;
859 case Tuple_kind:
860 CALL_SEQ(astfold_pattern, expr, node_->v.Tuple.elts);
861 break;
862 case UnaryOp_kind:
863 CALL(astfold_pattern_negative, expr_ty, node_);
864 break;
865 default:
866 Py_UNREACHABLE();
867 }
868 return 1;
869}
870
871static int
872astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
873{
874 CALL(astfold_pattern, expr_ty, node_->pattern);
875 CALL_OPT(astfold_expr, expr_ty, node_->guard);
876 CALL_SEQ(astfold_stmt, stmt, node_->body);
877 return 1;
878}
879
INADA Naoki7ea143a2017-12-14 16:47:20 +0900880#undef CALL
881#undef CALL_OPT
882#undef CALL_SEQ
883#undef CALL_INT_SEQ
884
885int
Pablo Galindod112c602020-03-18 23:02:09 +0000886_PyAST_Optimize(mod_ty mod, PyArena *arena, _PyASTOptimizeState *state)
INADA Naoki7ea143a2017-12-14 16:47:20 +0900887{
Pablo Galindod112c602020-03-18 23:02:09 +0000888 int ret = astfold_mod(mod, arena, state);
INADA Naoki7ea143a2017-12-14 16:47:20 +0900889 assert(ret || PyErr_Occurred());
890 return ret;
891}