| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,6 +19,14 @@ PyAPI_FUNC(PyCodeObject*) _PyAST_Compile( | |||
| 19 | 19 | int optimize, | |
| 20 | 20 | struct _arena *arena); | |
| 21 | 21 | ||
| 22 | + /* AST optimizations */ | ||
| 23 | + PyAPI_FUNC(int) _PyCompile_AstOptimize( | ||
| 24 | + struct _mod *mod, | ||
| 25 | + PyObject *filename, | ||
| 26 | + PyCompilerFlags *flags, | ||
| 27 | + int optimize, | ||
| 28 | + struct _arena *arena); | ||
| 29 | + | ||
| 22 | 30 | static const _PyCompilerSrcLocation NO_LOCATION = {-1, -1, -1, -1}; | |
| 23 | 31 | ||
| 24 | 32 | extern int _PyAST_Optimize( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -361,14 +361,16 @@ def test_optimization_levels__debug__(self): | |||
| 361 | 361 | cases = [(-1, '__debug__'), (0, '__debug__'), (1, False), (2, False)] | |
| 362 | 362 | for (optval, expected) in cases: | |
| 363 | 363 | with self.subTest(optval=optval, expected=expected): | |
| 364 | - res = ast.parse("__debug__", optimize=optval) | ||
| 365 | - self.assertIsInstance(res.body[0], ast.Expr) | ||
| 366 | - if isinstance(expected, bool): | ||
| 367 | - self.assertIsInstance(res.body[0].value, ast.Constant) | ||
| 368 | - self.assertEqual(res.body[0].value.value, expected) | ||
| 369 | - else: | ||
| 370 | - self.assertIsInstance(res.body[0].value, ast.Name) | ||
| 371 | - self.assertEqual(res.body[0].value.id, expected) | ||
| 364 | + res1 = ast.parse("__debug__", optimize=optval) | ||
| 365 | + res2 = ast.parse(ast.parse("__debug__"), optimize=optval) | ||
| 366 | + for res in [res1, res2]: | ||
| 367 | + self.assertIsInstance(res.body[0], ast.Expr) | ||
| 368 | + if isinstance(expected, bool): | ||
| 369 | + self.assertIsInstance(res.body[0].value, ast.Constant) | ||
| 370 | + self.assertEqual(res.body[0].value.value, expected) | ||
| 371 | + else: | ||
| 372 | + self.assertIsInstance(res.body[0].value, ast.Name) | ||
| 373 | + self.assertEqual(res.body[0].value.id, expected) | ||
| 372 | 374 | ||
| 373 | 375 | def test_optimization_levels_const_folding(self): | |
| 374 | 376 | folded = ('Expr', (1, 0, 1, 5), ('Constant', (1, 0, 1, 5), 3, None)) | |
@@ -381,9 +383,11 @@ def test_optimization_levels_const_folding(self): | |||
| 381 | 383 | cases = [(-1, not_folded), (0, not_folded), (1, folded), (2, folded)] | |
| 382 | 384 | for (optval, expected) in cases: | |
| 383 | 385 | with self.subTest(optval=optval): | |
| 384 | - tree = ast.parse("1 + 2", optimize=optval) | ||
| 385 | - res = to_tuple(tree.body[0]) | ||
| 386 | - self.assertEqual(res, expected) | ||
| 386 | + tree1 = ast.parse("1 + 2", optimize=optval) | ||
| 387 | + tree2 = ast.parse(ast.parse("1 + 2"), optimize=optval) | ||
| 388 | + for tree in [tree1, tree2]: | ||
| 389 | + res = to_tuple(tree.body[0]) | ||
| 390 | + self.assertEqual(res, expected) | ||
| 387 | 391 | ||
| 388 | 392 | def test_invalid_position_information(self): | |
| 389 | 393 | invalid_linenos = [ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -521,9 +521,10 @@ def test_compile_async_generator(self): | |||
| 521 | 521 | def test_compile_ast(self): | |
| 522 | 522 | args = ("a*(1+2)", "f.py", "exec") | |
| 523 | 523 | raw = compile(*args, flags = ast.PyCF_ONLY_AST).body[0] | |
| 524 | - opt = compile(*args, flags = ast.PyCF_OPTIMIZED_AST).body[0] | ||
| 524 | + opt1 = compile(*args, flags = ast.PyCF_OPTIMIZED_AST).body[0] | ||
| 525 | + opt2 = compile(ast.parse(args[0]), *args[1:], flags = ast.PyCF_OPTIMIZED_AST).body[0] | ||
| 525 | 526 | ||
| 526 | - for tree in (raw, opt): | ||
| 527 | + for tree in (raw, opt1, opt2): | ||
| 527 | 528 | self.assertIsInstance(tree.value, ast.BinOp) | |
| 528 | 529 | self.assertIsInstance(tree.value.op, ast.Mult) | |
| 529 | 530 | self.assertIsInstance(tree.value.left, ast.Name) | |
@@ -536,9 +537,10 @@ def test_compile_ast(self): | |||
| 536 | 537 | self.assertIsInstance(raw_right.right, ast.Constant) | |
| 537 | 538 | self.assertEqual(raw_right.right.value, 2) | |
| 538 | 539 | ||
| 539 | - opt_right = opt.value.right # expect Constant(3) | ||
| 540 | - self.assertIsInstance(opt_right, ast.Constant) | ||
| 541 | - self.assertEqual(opt_right.value, 3) | ||
| 540 | + for opt in [opt1, opt2]: | ||
| 541 | + opt_right = opt.value.right # expect Constant(3) | ||
| 542 | + self.assertIsInstance(opt_right, ast.Constant) | ||
| 543 | + self.assertEqual(opt_right.value, 3) | ||
| 542 | 544 | ||
| 543 | 545 | def test_delattr(self): | |
| 544 | 546 | sys.spam = 1 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -804,23 +804,40 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, | |||
| 804 | 804 | if (is_ast == -1) | |
| 805 | 805 | goto error; | |
| 806 | 806 | if (is_ast) { | |
| 807 | - if (flags & PyCF_ONLY_AST) { | ||
| 807 | + if ((flags & PyCF_OPTIMIZED_AST) == PyCF_ONLY_AST) { | ||
| 808 | + // return an un-optimized AST | ||
| 808 | 809 | result = Py_NewRef(source); | |
| 809 | 810 | } | |
| 810 | 811 | else { | |
| 811 | - PyArena *arena; | ||
| 812 | - mod_ty mod; | ||
| 812 | + // Return an optimized AST or code object | ||
| 813 | 813 | ||
| 814 | - arena = _PyArena_New(); | ||
| 815 | - if (arena == NULL) | ||
| 816 | - goto error; | ||
| 817 | - mod = PyAST_obj2mod(source, arena, compile_mode); | ||
| 818 | - if (mod == NULL || !_PyAST_Validate(mod)) { | ||
| 819 | - _PyArena_Free(arena); | ||
| 814 | + PyArena *arena = _PyArena_New(); | ||
| 815 | + if (arena == NULL) { | ||
| 820 | 816 | goto error; | |
| 821 | 817 | } | |
| 822 | - result = (PyObject*)_PyAST_Compile(mod, filename, | ||
| 823 | - &cf, optimize, arena); | ||
| 818 | + | ||
| 819 | + if (flags & PyCF_ONLY_AST) { | ||
| 820 | + mod_ty mod = PyAST_obj2mod(source, arena, compile_mode); | ||
| 821 | + if (mod == NULL || !_PyAST_Validate(mod)) { | ||
| 822 | + _PyArena_Free(arena); | ||
| 823 | + goto error; | ||
| 824 | + } | ||
| 825 | + if (_PyCompile_AstOptimize(mod, filename, &cf, optimize, | ||
| 826 | + arena) < 0) { | ||
| 827 | + _PyArena_Free(arena); | ||
| 828 | + goto error; | ||
| 829 | + } | ||
| 830 | + result = PyAST_mod2obj(mod); | ||
| 831 | + } | ||
| 832 | + else { | ||
| 833 | + mod_ty mod = PyAST_obj2mod(source, arena, compile_mode); | ||
| 834 | + if (mod == NULL || !_PyAST_Validate(mod)) { | ||
| 835 | + _PyArena_Free(arena); | ||
| 836 | + goto error; | ||
| 837 | + } | ||
| 838 | + result = (PyObject*)_PyAST_Compile(mod, filename, | ||
| 839 | + &cf, optimize, arena); | ||
| 840 | + } | ||
| 824 | 841 | _PyArena_Free(arena); | |
| 825 | 842 | } | |
| 826 | 843 | goto finally; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -557,6 +557,24 @@ _PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags, | |||
| 557 | 557 | return co; | |
| 558 | 558 | } | |
| 559 | 559 | ||
| 560 | + int | ||
| 561 | + _PyCompile_AstOptimize(mod_ty mod, PyObject *filename, PyCompilerFlags *cf, | ||
| 562 | + int optimize, PyArena *arena) | ||
| 563 | + { | ||
| 564 | + PyFutureFeatures future; | ||
| 565 | + if (!_PyFuture_FromAST(mod, filename, &future)) { | ||
| 566 | + return -1; | ||
| 567 | + } | ||
| 568 | + int flags = future.ff_features | cf->cf_flags; | ||
| 569 | + if (optimize == -1) { | ||
| 570 | + optimize = _Py_GetConfig()->optimization_level; | ||
| 571 | + } | ||
| 572 | + if (!_PyAST_Optimize(mod, arena, optimize, flags)) { | ||
| 573 | + return -1; | ||
| 574 | + } | ||
| 575 | + return 0; | ||
| 576 | + } | ||
| 577 | + | ||
| 560 | 578 | static void | |
| 561 | 579 | compiler_free(struct compiler *c) | |
| 562 | 580 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,7 +22,6 @@ | |||
| 22 | 22 | #include "pycore_pyerrors.h" // _PyErr_GetRaisedException, _Py_Offer_Suggestions | |
| 23 | 23 | #include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt | |
| 24 | 24 | #include "pycore_pystate.h" // _PyInterpreterState_GET() | |
| 25 | - #include "pycore_symtable.h" // _PyFuture_FromAST() | ||
| 26 | 25 | #include "pycore_sysmodule.h" // _PySys_Audit() | |
| 27 | 26 | #include "pycore_traceback.h" // _PyTraceBack_Print_Indented() | |
| 28 | 27 | ||
@@ -1792,24 +1791,6 @@ run_pyc_file(FILE *fp, PyObject *globals, PyObject *locals, | |||
| 1792 | 1791 | return NULL; | |
| 1793 | 1792 | } | |
| 1794 | 1793 | ||
| 1795 | - static int | ||
| 1796 | - ast_optimize(mod_ty mod, PyObject *filename, PyCompilerFlags *cf, | ||
| 1797 | - int optimize, PyArena *arena) | ||
| 1798 | - { | ||
| 1799 | - PyFutureFeatures future; | ||
| 1800 | - if (!_PyFuture_FromAST(mod, filename, &future)) { | ||
| 1801 | - return -1; | ||
| 1802 | - } | ||
| 1803 | - int flags = future.ff_features | cf->cf_flags; | ||
| 1804 | - if (optimize == -1) { | ||
| 1805 | - optimize = _Py_GetConfig()->optimization_level; | ||
| 1806 | - } | ||
| 1807 | - if (!_PyAST_Optimize(mod, arena, optimize, flags)) { | ||
| 1808 | - return -1; | ||
| 1809 | - } | ||
| 1810 | - return 0; | ||
| 1811 | - } | ||
| 1812 | - | ||
| 1813 | 1794 | PyObject * | |
| 1814 | 1795 | Py_CompileStringObject(const char *str, PyObject *filename, int start, | |
| 1815 | 1796 | PyCompilerFlags *flags, int optimize) | |
@@ -1827,8 +1808,7 @@ Py_CompileStringObject(const char *str, PyObject *filename, int start, | |||
| 1827 | 1808 | } | |
| 1828 | 1809 | if (flags && (flags->cf_flags & PyCF_ONLY_AST)) { | |
| 1829 | 1810 | if ((flags->cf_flags & PyCF_OPTIMIZED_AST) == PyCF_OPTIMIZED_AST) { | |
| 1830 | - if (ast_optimize(mod, filename, flags, optimize, arena) < 0) { | ||
| 1831 | - _PyArena_Free(arena); | ||
| 1811 | + if (_PyCompile_AstOptimize(mod, filename, flags, optimize, arena) < 0) { | ||
| 1832 | 1812 | return NULL; | |
| 1833 | 1813 | } | |
| 1834 | 1814 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments