| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,4 @@ | |||
| 1 | - :mod:`!ast` --- Abstract Syntax Trees | ||
| 1 | + :mod:`!ast` --- Abstract syntax trees | ||
| 2 | 2 | ===================================== | |
| 3 | 3 | ||
| 4 | 4 | .. module:: ast | |
@@ -29,7 +29,7 @@ compiled into a Python code object using the built-in :func:`compile` function. | |||
| 29 | 29 | ||
| 30 | 30 | .. _abstract-grammar: | |
| 31 | 31 | ||
| 32 | - Abstract Grammar | ||
| 32 | + Abstract grammar | ||
| 33 | 33 | ---------------- | |
| 34 | 34 | ||
| 35 | 35 | The abstract grammar is currently defined as follows: | |
@@ -2156,10 +2156,10 @@ Async and await | |||
| 2156 | 2156 | of :class:`ast.operator`, :class:`ast.unaryop`, :class:`ast.cmpop`, | |
| 2157 | 2157 | :class:`ast.boolop` and :class:`ast.expr_context`) on the returned tree | |
| 2158 | 2158 | will be singletons. Changes to one will be reflected in all other | |
| 2159 | - occurrences of the same value (e.g. :class:`ast.Add`). | ||
| 2159 | + occurrences of the same value (for example, :class:`ast.Add`). | ||
| 2160 | 2160 | ||
| 2161 | 2161 | ||
| 2162 | - :mod:`ast` Helpers | ||
| 2162 | + :mod:`ast` helpers | ||
| 2163 | 2163 | ------------------ | |
| 2164 | 2164 | ||
| 2165 | 2165 | Apart from the node classes, the :mod:`ast` module defines these utility functions | |
@@ -2484,7 +2484,7 @@ and classes for traversing abstract syntax trees: | |||
| 2484 | 2484 | ||
| 2485 | 2485 | .. _ast-compiler-flags: | |
| 2486 | 2486 | ||
| 2487 | - Compiler Flags | ||
| 2487 | + Compiler flags | ||
| 2488 | 2488 | -------------- | |
| 2489 | 2489 | ||
| 2490 | 2490 | The following flags may be passed to :func:`compile` in order to change | |
@@ -2533,7 +2533,7 @@ effects on the compilation of a program: | |||
| 2533 | 2533 | ||
| 2534 | 2534 | .. _ast-cli: | |
| 2535 | 2535 | ||
| 2536 | - Command-Line Usage | ||
| 2536 | + Command-line usage | ||
| 2537 | 2537 | ------------------ | |
| 2538 | 2538 | ||
| 2539 | 2539 | .. versionadded:: 3.9 | |
@@ -2572,6 +2572,28 @@ The following options are accepted: | |||
| 2572 | 2572 | ||
| 2573 | 2573 | Indentation of nodes in AST (number of spaces). | |
| 2574 | 2574 | ||
| 2575 | + .. option:: --feature-version <version> | ||
| 2576 | + | ||
| 2577 | + Python version in the format 3.x (for example, 3.10). Defaults to the | ||
| 2578 | + current version of the interpreter. | ||
| 2579 | + | ||
| 2580 | + .. versionadded:: next | ||
| 2581 | + | ||
| 2582 | + .. option:: -O <level> | ||
| 2583 | + --optimize <level> | ||
| 2584 | + | ||
| 2585 | + Optimization level for parser. Defaults to no optimization. | ||
| 2586 | + | ||
| 2587 | + .. versionadded:: next | ||
| 2588 | + | ||
| 2589 | + .. option:: --show-empty | ||
| 2590 | + | ||
| 2591 | + Show empty lists and fields that are ``None``. Defaults to not showing empty | ||
| 2592 | + objects. | ||
| 2593 | + | ||
| 2594 | + .. versionadded:: next | ||
| 2595 | + | ||
| 2596 | + | ||
| 2575 | 2597 | If :file:`infile` is specified its contents are parsed to AST and dumped | |
| 2576 | 2598 | to stdout. Otherwise, the content is read from stdin. | |
| 2577 | 2599 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -875,6 +875,11 @@ ast | |||
| 875 | 875 | that the root node type is appropriate. | |
| 876 | 876 | (Contributed by Irit Katriel in :gh:`130139`.) | |
| 877 | 877 | ||
| 878 | + * Add new ``--feature-version``, ``--optimize``, ``--show-empty`` options to | ||
| 879 | + command-line interface. | ||
| 880 | + (Contributed by Semyon Moroz in :gh:`133367`.) | ||
| 881 | + | ||
| 882 | + | ||
| 878 | 883 | bdb | |
| 879 | 884 | --- | |
| 880 | 885 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -643,6 +643,15 @@ def main(args=None): | |||
| 643 | 643 | 'column offsets') | |
| 644 | 644 | parser.add_argument('-i', '--indent', type=int, default=3, | |
| 645 | 645 | help='indentation of nodes (number of spaces)') | |
| 646 | + parser.add_argument('--feature-version', | ||
| 647 | + type=str, default=None, metavar='VERSION', | ||
| 648 | + help='Python version in the format 3.x ' | ||
| 649 | + '(for example, 3.10)') | ||
| 650 | + parser.add_argument('-O', '--optimize', | ||
| 651 | + type=int, default=-1, metavar='LEVEL', | ||
| 652 | + help='optimization level for parser (default -1)') | ||
| 653 | + parser.add_argument('--show-empty', default=False, action='store_true', | ||
| 654 | + help='show empty lists and fields in dump output') | ||
| 646 | 655 | args = parser.parse_args(args) | |
| 647 | 656 | ||
| 648 | 657 | if args.infile == '-': | |
@@ -652,8 +661,22 @@ def main(args=None): | |||
| 652 | 661 | name = args.infile | |
| 653 | 662 | with open(args.infile, 'rb') as infile: | |
| 654 | 663 | source = infile.read() | |
| 655 | - tree = parse(source, name, args.mode, type_comments=args.no_type_comments) | ||
| 656 | - print(dump(tree, include_attributes=args.include_attributes, indent=args.indent)) | ||
| 664 | + | ||
| 665 | + # Process feature_version | ||
| 666 | + feature_version = None | ||
| 667 | + if args.feature_version: | ||
| 668 | + try: | ||
| 669 | + major, minor = map(int, args.feature_version.split('.', 1)) | ||
| 670 | + except ValueError: | ||
| 671 | + parser.error('Invalid format for --feature-version; ' | ||
| 672 | + 'expected format 3.x (for example, 3.10)') | ||
| 673 | + | ||
| 674 | + feature_version = (major, minor) | ||
| 675 | + | ||
| 676 | + tree = parse(source, name, args.mode, type_comments=args.no_type_comments, | ||
| 677 | + feature_version=feature_version, optimize=args.optimize) | ||
| 678 | + print(dump(tree, include_attributes=args.include_attributes, | ||
| 679 | + indent=args.indent, show_empty=args.show_empty)) | ||
| 657 | 680 | ||
| 658 | 681 | if __name__ == '__main__': | |
| 659 | 682 | main() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3272,6 +3272,9 @@ def test_invocation(self): | |||
| 3272 | 3272 | ('--no-type-comments', '--no-type-comments'), | |
| 3273 | 3273 | ('-a', '--include-attributes'), | |
| 3274 | 3274 | ('-i=4', '--indent=4'), | |
| 3275 | + ('--feature-version=3.13', '--feature-version=3.13'), | ||
| 3276 | + ('-O=-1', '--optimize=-1'), | ||
| 3277 | + ('--show-empty', '--show-empty'), | ||
| 3275 | 3278 | ) | |
| 3276 | 3279 | self.set_source(''' | |
| 3277 | 3280 | print(1, 2, 3) | |
@@ -3389,7 +3392,7 @@ def test_include_attributes_flag(self): | |||
| 3389 | 3392 | self.check_output(source, expect, flag) | |
| 3390 | 3393 | ||
| 3391 | 3394 | def test_indent_flag(self): | |
| 3392 | - # test 'python -m ast -i/--indent' | ||
| 3395 | + # test 'python -m ast -i/--indent 0' | ||
| 3393 | 3396 | source = 'pass' | |
| 3394 | 3397 | expect = ''' | |
| 3395 | 3398 | Module( | |
@@ -3400,6 +3403,96 @@ def test_indent_flag(self): | |||
| 3400 | 3403 | with self.subTest(flag=flag): | |
| 3401 | 3404 | self.check_output(source, expect, flag) | |
| 3402 | 3405 | ||
| 3406 | + def test_feature_version_flag(self): | ||
| 3407 | + # test 'python -m ast --feature-version 3.9/3.10' | ||
| 3408 | + source = ''' | ||
| 3409 | + match x: | ||
| 3410 | + case 1: | ||
| 3411 | + pass | ||
| 3412 | + ''' | ||
| 3413 | + expect = ''' | ||
| 3414 | + Module( | ||
| 3415 | + body=[ | ||
| 3416 | + Match( | ||
| 3417 | + subject=Name(id='x', ctx=Load()), | ||
| 3418 | + cases=[ | ||
| 3419 | + match_case( | ||
| 3420 | + pattern=MatchValue( | ||
| 3421 | + value=Constant(value=1)), | ||
| 3422 | + body=[ | ||
| 3423 | + Pass()])])]) | ||
| 3424 | + ''' | ||
| 3425 | + self.check_output(source, expect, '--feature-version=3.10') | ||
| 3426 | + with self.assertRaises(SyntaxError): | ||
| 3427 | + self.invoke_ast('--feature-version=3.9') | ||
| 3428 | + | ||
| 3429 | + def test_no_optimize_flag(self): | ||
| 3430 | + # test 'python -m ast -O/--optimize -1/0' | ||
| 3431 | + source = ''' | ||
| 3432 | + match a: | ||
| 3433 | + case 1+2j: | ||
| 3434 | + pass | ||
| 3435 | + ''' | ||
| 3436 | + expect = ''' | ||
| 3437 | + Module( | ||
| 3438 | + body=[ | ||
| 3439 | + Match( | ||
| 3440 | + subject=Name(id='a', ctx=Load()), | ||
| 3441 | + cases=[ | ||
| 3442 | + match_case( | ||
| 3443 | + pattern=MatchValue( | ||
| 3444 | + value=BinOp( | ||
| 3445 | + left=Constant(value=1), | ||
| 3446 | + op=Add(), | ||
| 3447 | + right=Constant(value=2j))), | ||
| 3448 | + body=[ | ||
| 3449 | + Pass()])])]) | ||
| 3450 | + ''' | ||
| 3451 | + for flag in ('-O=-1', '--optimize=-1', '-O=0', '--optimize=0'): | ||
| 3452 | + with self.subTest(flag=flag): | ||
| 3453 | + self.check_output(source, expect, flag) | ||
| 3454 | + | ||
| 3455 | + def test_optimize_flag(self): | ||
| 3456 | + # test 'python -m ast -O/--optimize 1/2' | ||
| 3457 | + source = ''' | ||
| 3458 | + match a: | ||
| 3459 | + case 1+2j: | ||
| 3460 | + pass | ||
| 3461 | + ''' | ||
| 3462 | + expect = ''' | ||
| 3463 | + Module( | ||
| 3464 | + body=[ | ||
| 3465 | + Match( | ||
| 3466 | + subject=Name(id='a', ctx=Load()), | ||
| 3467 | + cases=[ | ||
| 3468 | + match_case( | ||
| 3469 | + pattern=MatchValue( | ||
| 3470 | + value=Constant(value=(1+2j))), | ||
| 3471 | + body=[ | ||
| 3472 | + Pass()])])]) | ||
| 3473 | + ''' | ||
| 3474 | + for flag in ('-O=1', '--optimize=1', '-O=2', '--optimize=2'): | ||
| 3475 | + with self.subTest(flag=flag): | ||
| 3476 | + self.check_output(source, expect, flag) | ||
| 3477 | + | ||
| 3478 | + def test_show_empty_flag(self): | ||
| 3479 | + # test 'python -m ast --show-empty' | ||
| 3480 | + source = 'print(1, 2, 3)' | ||
| 3481 | + expect = ''' | ||
| 3482 | + Module( | ||
| 3483 | + body=[ | ||
| 3484 | + Expr( | ||
| 3485 | + value=Call( | ||
| 3486 | + func=Name(id='print', ctx=Load()), | ||
| 3487 | + args=[ | ||
| 3488 | + Constant(value=1), | ||
| 3489 | + Constant(value=2), | ||
| 3490 | + Constant(value=3)], | ||
| 3491 | + keywords=[]))], | ||
| 3492 | + type_ignores=[]) | ||
| 3493 | + ''' | ||
| 3494 | + self.check_output(source, expect, '--show-empty') | ||
| 3495 | + | ||
| 3403 | 3496 | ||
| 3404 | 3497 | class ASTOptimiziationTests(unittest.TestCase): | |
| 3405 | 3498 | def wrap_expr(self, expr): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Add the ``--feature-version``, ``--optimize``, and ``--show-empty`` options | ||
| 2 | + to the :mod:`ast` command-line interface. Patch by Semyon Moroz. | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments