From 198c87a625ecb0aeac723fda539290698bfce428 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sat, 3 May 2025 09:00:03 +0400 Subject: [PATCH 01/11] Add tests for `ast` command-line interface --- Lib/ast.py | 6 +- Lib/test/test_ast/test_ast.py | 162 ++++++++++++++++++++++++++++++---- 2 files changed, 150 insertions(+), 18 deletions(-) diff --git a/Lib/ast.py b/Lib/ast.py index aa788e6eb62c4f..4940c6381a7a15 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -626,7 +626,7 @@ def unparse(ast_obj): return unparser.visit(ast_obj) -def main(): +def _main(args=None): import argparse import sys @@ -643,7 +643,7 @@ def main(): 'column offsets') parser.add_argument('-i', '--indent', type=int, default=3, help='indentation of nodes (number of spaces)') - args = parser.parse_args() + args = parser.parse_args(args) if args.infile == '-': name = '' @@ -656,4 +656,4 @@ def main(): print(dump(tree, include_attributes=args.include_attributes, indent=args.indent)) if __name__ == '__main__': - main() + _main() diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 7d64b1c0e3a0c3..b7f06537fb0d4f 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -1,12 +1,16 @@ import _ast_unparse import ast import builtins +import contextlib import copy import dis import enum +import io +import itertools import os import re import sys +import tempfile import textwrap import types import unittest @@ -3175,23 +3179,151 @@ def test_subinterpreter(self): self.assertEqual(res, 0) -class ASTMainTests(unittest.TestCase): - # Tests `ast.main()` function. +class CommandLineTests(unittest.TestCase): + def setUp(self): + self.filename = tempfile.mktemp() + self.addCleanup(os_helper.unlink, self.filename) - def test_cli_file_input(self): - code = "print(1, 2, 3)" - expected = ast.dump(ast.parse(code), indent=3) - - with os_helper.temp_dir() as tmp_dir: - filename = os.path.join(tmp_dir, "test_module.py") - with open(filename, 'w', encoding='utf-8') as f: - f.write(code) - res, _ = script_helper.run_python_until_end("-m", "ast", filename) + @staticmethod + def text_normalize(string): + """Dedent *string* and strip it from its surrounding whitespaces. + This method is used by the other utility functions so that any + string to write or to match against can be freely indented. + """ + return textwrap.dedent(string).strip() + + def set_source(self, content): + with open(self.filename, 'w') as f: + f.write(self.text_normalize(content)) + + def invoke_ast(self, *flags): + output = io.StringIO() + with contextlib.redirect_stdout(output): + ast._main(args=[*flags, self.filename]) + return self.text_normalize(output.getvalue()) + + def check_output(self, source, expect, *flags): + with self.subTest(source=source, flags=flags): + self.set_source(source) + res = self.invoke_ast(*flags) + expect = self.text_normalize(expect) + self.assertListEqual(res.splitlines(), expect.splitlines()) + + def test_invocation(self): + # test various combinations of parameters + base_flags = [ + ('-m=exec', '--mode=exec'), + ('--no-type-comments', '--no-type-comments'), + ('-a', '--include-attributes'), + ('-i=4', '--indent=4'), + ] + self.set_source(''' + print(1, 2, 3) + def f(x): + x -= 1 + return x + ''') - self.assertEqual(res.err, b"") - self.assertEqual(expected.splitlines(), - res.out.decode("utf8").splitlines()) - self.assertEqual(res.rc, 0) + for r in range(1, len(base_flags) + 1): + for choices in itertools.combinations(base_flags, r=r): + for args in itertools.product(*choices): + with self.subTest(args=args[1:]): + _ = self.invoke_ast(*args) + + with self.assertRaises(SystemExit): + # suppress argparse error message + with contextlib.redirect_stderr(io.StringIO()): + _ = self.invoke_ast('--unknown') + + def test_mode_flag(self): + # test 'python -m ast -m/--mode' + source = 'print(1, 2, 3)' + expect = ''' + Module( + body=[ + Expr( + value=Call( + func=Name(id='print', ctx=Load()), + args=[ + Constant(value=1), + Constant(value=2), + Constant(value=3)]))]) + ''' + for flag in ['-m=exec', '--mode=exec']: + self.check_output(source, expect, flag) + source = 'pass' + expect = ''' + Interactive( + body=[ + Pass()]) + ''' + for flag in ['-m=single', '--mode=single']: + self.check_output(source, expect, flag) + source = 'print(1, 2, 3)' + expect = ''' + Expression( + body=Call( + func=Name(id='print', ctx=Load()), + args=[ + Constant(value=1), + Constant(value=2), + Constant(value=3)])) + ''' + for flag in ['-m=eval', '--mode=eval']: + self.check_output(source, expect, flag) + source = '(int, str) -> list[int]' + expect = ''' + FunctionType( + argtypes=[ + Name(id='int', ctx=Load()), + Name(id='str', ctx=Load())], + returns=Subscript( + value=Name(id='list', ctx=Load()), + slice=Name(id='int', ctx=Load()), + ctx=Load())) + ''' + for flag in ['-m=func_type', '--mode=func_type']: + self.check_output(source, expect, flag) + + def test_no_type_comments_flag(self): + # test 'python -m ast --no-type-comments' + source = 'x: bool = 1 # type: ignore[assignment]' + expect = ''' + Module( + body=[ + AnnAssign( + target=Name(id='x', ctx=Store()), + annotation=Name(id='bool', ctx=Load()), + value=Constant(value=1), + simple=1)]) + ''' + self.check_output(source, expect, '--no-type-comments') + + def test_include_attributes_flag(self): + # test 'python -m ast -a/--include-attributes' + source = 'pass' + expect = ''' + Module( + body=[ + Pass( + lineno=1, + col_offset=0, + end_lineno=1, + end_col_offset=4)]) + ''' + for flag in ['-a', '--include-attributes']: + self.check_output(source, expect, flag) + + def test_indent_flag(self): + # test 'python -m ast -i/--indent' + source = 'pass' + expect = ''' + Module( + body=[ + Pass()]) + ''' + for flag in ['-i=0', '--indent=0']: + self.check_output(source, expect, flag) class ASTOptimiziationTests(unittest.TestCase): From bc12715b56572dc77eedb03df3bd0d2206df5a0a Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sat, 3 May 2025 09:14:56 +0400 Subject: [PATCH 02/11] check unknown flag output --- Lib/test/test_ast/test_ast.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index b7f06537fb0d4f..7a77b94a49604e 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -5,7 +5,6 @@ import copy import dis import enum -import io import itertools import os import re @@ -15,6 +14,7 @@ import types import unittest import weakref +from io import StringIO from pathlib import Path from textwrap import dedent try: @@ -3197,7 +3197,7 @@ def set_source(self, content): f.write(self.text_normalize(content)) def invoke_ast(self, *flags): - output = io.StringIO() + output = StringIO() with contextlib.redirect_stdout(output): ast._main(args=[*flags, self.filename]) return self.text_normalize(output.getvalue()) @@ -3232,8 +3232,9 @@ def f(x): with self.assertRaises(SystemExit): # suppress argparse error message - with contextlib.redirect_stderr(io.StringIO()): - _ = self.invoke_ast('--unknown') + with contextlib.redirect_stderr(StringIO()): + output = self.invoke_ast('--unknown') + self.assertStartsWith(output, 'usage: ') def test_mode_flag(self): # test 'python -m ast -m/--mode' From 75d3cb71e1c9e50ad8f9d12f84ad02bcaf4792c3 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sat, 3 May 2025 09:56:26 +0400 Subject: [PATCH 03/11] remove unused import --- Lib/test/test_ast/test_ast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 7a77b94a49604e..17190f24256c82 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -23,7 +23,7 @@ _testinternalcapi = None from test import support -from test.support import os_helper, script_helper +from test.support import os_helper from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow from test.support.ast_helper import ASTTestMixin from test.test_ast.utils import to_tuple From de328afc20b10ef45b8cd85488c91d0419c4d49a Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sun, 4 May 2025 00:42:37 +0400 Subject: [PATCH 04/11] Accept suggestions --- Lib/test/test_ast/test_ast.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 17190f24256c82..045dca3db3a5be 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -3193,8 +3193,7 @@ def text_normalize(string): return textwrap.dedent(string).strip() def set_source(self, content): - with open(self.filename, 'w') as f: - f.write(self.text_normalize(content)) + Path(self.filename).write_text(self.text_normalize(content)) def invoke_ast(self, *flags): output = StringIO() @@ -3207,16 +3206,16 @@ def check_output(self, source, expect, *flags): self.set_source(source) res = self.invoke_ast(*flags) expect = self.text_normalize(expect) - self.assertListEqual(res.splitlines(), expect.splitlines()) + self.assertEqual(res, expect) def test_invocation(self): # test various combinations of parameters - base_flags = [ + base_flags = ( ('-m=exec', '--mode=exec'), ('--no-type-comments', '--no-type-comments'), ('-a', '--include-attributes'), ('-i=4', '--indent=4'), - ] + ) self.set_source(''' print(1, 2, 3) def f(x): @@ -3250,7 +3249,7 @@ def test_mode_flag(self): Constant(value=2), Constant(value=3)]))]) ''' - for flag in ['-m=exec', '--mode=exec']: + for flag in ('-m=exec', '--mode=exec'): self.check_output(source, expect, flag) source = 'pass' expect = ''' @@ -3258,7 +3257,7 @@ def test_mode_flag(self): body=[ Pass()]) ''' - for flag in ['-m=single', '--mode=single']: + for flag in ('-m=single', '--mode=single'): self.check_output(source, expect, flag) source = 'print(1, 2, 3)' expect = ''' @@ -3270,7 +3269,7 @@ def test_mode_flag(self): Constant(value=2), Constant(value=3)])) ''' - for flag in ['-m=eval', '--mode=eval']: + for flag in ('-m=eval', '--mode=eval'): self.check_output(source, expect, flag) source = '(int, str) -> list[int]' expect = ''' @@ -3283,7 +3282,7 @@ def test_mode_flag(self): slice=Name(id='int', ctx=Load()), ctx=Load())) ''' - for flag in ['-m=func_type', '--mode=func_type']: + for flag in ('-m=func_type', '--mode=func_type'): self.check_output(source, expect, flag) def test_no_type_comments_flag(self): @@ -3312,7 +3311,7 @@ def test_include_attributes_flag(self): end_lineno=1, end_col_offset=4)]) ''' - for flag in ['-a', '--include-attributes']: + for flag in ('-a', '--include-attributes'): self.check_output(source, expect, flag) def test_indent_flag(self): @@ -3323,7 +3322,7 @@ def test_indent_flag(self): body=[ Pass()]) ''' - for flag in ['-i=0', '--indent=0']: + for flag in ('-i=0', '--indent=0'): self.check_output(source, expect, flag) From 6aa5cd7ec4d9148dcd45a3ede7054bb88e4547c5 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sun, 4 May 2025 12:29:34 +0400 Subject: [PATCH 05/11] Accept suggestions --- Lib/ast.py | 4 +-- Lib/test/test_ast/test_ast.py | 67 ++++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/Lib/ast.py b/Lib/ast.py index 4940c6381a7a15..af4fe8ff5a8e95 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -626,7 +626,7 @@ def unparse(ast_obj): return unparser.visit(ast_obj) -def _main(args=None): +def main(args=None): import argparse import sys @@ -656,4 +656,4 @@ def _main(args=None): print(dump(tree, include_attributes=args.include_attributes, indent=args.indent)) if __name__ == '__main__': - _main() + main() diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 045dca3db3a5be..4cb4d73ce445d0 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -3186,20 +3186,21 @@ def setUp(self): @staticmethod def text_normalize(string): - """Dedent *string* and strip it from its surrounding whitespaces. - This method is used by the other utility functions so that any - string to write or to match against can be freely indented. - """ return textwrap.dedent(string).strip() def set_source(self, content): Path(self.filename).write_text(self.text_normalize(content)) def invoke_ast(self, *flags): - output = StringIO() - with contextlib.redirect_stdout(output): - ast._main(args=[*flags, self.filename]) - return self.text_normalize(output.getvalue()) + stderr = StringIO() + stdout = StringIO() + with ( + contextlib.redirect_stdout(stdout), + contextlib.redirect_stderr(stderr), + ): + ast.main(args=[*flags, self.filename]) + self.assertEqual(stderr.getvalue(), '') + return self.text_normalize(stdout.getvalue()) def check_output(self, source, expect, *flags): with self.subTest(source=source, flags=flags): @@ -3218,7 +3219,7 @@ def test_invocation(self): ) self.set_source(''' print(1, 2, 3) - def f(x): + def f(x: int) -> int: x -= 1 return x ''') @@ -3226,31 +3227,41 @@ def f(x): for r in range(1, len(base_flags) + 1): for choices in itertools.combinations(base_flags, r=r): for args in itertools.product(*choices): - with self.subTest(args=args[1:]): + with self.subTest(flags=args[1:]): _ = self.invoke_ast(*args) + def test_unknown_flag(self): with self.assertRaises(SystemExit): - # suppress argparse error message - with contextlib.redirect_stderr(StringIO()): - output = self.invoke_ast('--unknown') - self.assertStartsWith(output, 'usage: ') - - def test_mode_flag(self): - # test 'python -m ast -m/--mode' - source = 'print(1, 2, 3)' + output = self.invoke_ast('--unknown') + self.assertStartsWith(output, 'usage: ') + + def test_help_flag(self): + # test 'python -m ast -h/--help' + for flag in ('-h', '--help'): + with self.subTest(flags=flag): + with self.assertRaises(SystemExit): + output = self.invoke_ast(flag) + self.assertStartsWith(output, 'usage: ') + + def test_exec_mode_flag(self): + # test 'python -m ast -m/--mode exec' + source = 'x: bool = 1 # type: ignore[assignment]' expect = ''' Module( body=[ - Expr( - value=Call( - func=Name(id='print', ctx=Load()), - args=[ - Constant(value=1), - Constant(value=2), - Constant(value=3)]))]) + AnnAssign( + target=Name(id='x', ctx=Store()), + annotation=Name(id='bool', ctx=Load()), + value=Constant(value=1), + simple=1)], + type_ignores=[ + TypeIgnore(lineno=1, tag='[assignment]')]) ''' for flag in ('-m=exec', '--mode=exec'): self.check_output(source, expect, flag) + + def test_single_mode_flag(self): + # test 'python -m ast -m/--mode single' source = 'pass' expect = ''' Interactive( @@ -3259,6 +3270,9 @@ def test_mode_flag(self): ''' for flag in ('-m=single', '--mode=single'): self.check_output(source, expect, flag) + + def test_eval_mode_flag(self): + # test 'python -m ast -m/--mode eval' source = 'print(1, 2, 3)' expect = ''' Expression( @@ -3271,6 +3285,9 @@ def test_mode_flag(self): ''' for flag in ('-m=eval', '--mode=eval'): self.check_output(source, expect, flag) + + def test_func_type_mode_flag(self): + # test 'python -m ast -m/--mode func_type' source = '(int, str) -> list[int]' expect = ''' FunctionType( From b804f6152fcb03a022d9a629a2e658a617ed9c46 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sun, 4 May 2025 15:35:23 +0400 Subject: [PATCH 06/11] accept again --- Lib/test/test_ast/test_ast.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 4cb4d73ce445d0..37116f7b644fd4 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -3227,8 +3227,8 @@ def f(x: int) -> int: for r in range(1, len(base_flags) + 1): for choices in itertools.combinations(base_flags, r=r): for args in itertools.product(*choices): - with self.subTest(flags=args[1:]): - _ = self.invoke_ast(*args) + with self.subTest(flags=args): + self.invoke_ast(*args) def test_unknown_flag(self): with self.assertRaises(SystemExit): @@ -3258,7 +3258,8 @@ def test_exec_mode_flag(self): TypeIgnore(lineno=1, tag='[assignment]')]) ''' for flag in ('-m=exec', '--mode=exec'): - self.check_output(source, expect, flag) + with self.subTest(flags=flag): + self.check_output(source, expect, flag) def test_single_mode_flag(self): # test 'python -m ast -m/--mode single' @@ -3269,7 +3270,8 @@ def test_single_mode_flag(self): Pass()]) ''' for flag in ('-m=single', '--mode=single'): - self.check_output(source, expect, flag) + with self.subTest(flags=flag): + self.check_output(source, expect, flag) def test_eval_mode_flag(self): # test 'python -m ast -m/--mode eval' @@ -3284,7 +3286,8 @@ def test_eval_mode_flag(self): Constant(value=3)])) ''' for flag in ('-m=eval', '--mode=eval'): - self.check_output(source, expect, flag) + with self.subTest(flags=flag): + self.check_output(source, expect, flag) def test_func_type_mode_flag(self): # test 'python -m ast -m/--mode func_type' @@ -3300,7 +3303,8 @@ def test_func_type_mode_flag(self): ctx=Load())) ''' for flag in ('-m=func_type', '--mode=func_type'): - self.check_output(source, expect, flag) + with self.subTest(flags=flag): + self.check_output(source, expect, flag) def test_no_type_comments_flag(self): # test 'python -m ast --no-type-comments' @@ -3329,7 +3333,8 @@ def test_include_attributes_flag(self): end_col_offset=4)]) ''' for flag in ('-a', '--include-attributes'): - self.check_output(source, expect, flag) + with self.subTest(flags=flag): + self.check_output(source, expect, flag) def test_indent_flag(self): # test 'python -m ast -i/--indent' @@ -3340,7 +3345,8 @@ def test_indent_flag(self): Pass()]) ''' for flag in ('-i=0', '--indent=0'): - self.check_output(source, expect, flag) + with self.subTest(flags=flag): + self.check_output(source, expect, flag) class ASTOptimiziationTests(unittest.TestCase): From 21097ebfa5f23bcf295094f200744c090864dd29 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sun, 4 May 2025 15:36:29 +0400 Subject: [PATCH 07/11] Rename from flags to flag --- Lib/test/test_ast/test_ast.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 37116f7b644fd4..3f29981c102ad1 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -3238,7 +3238,7 @@ def test_unknown_flag(self): def test_help_flag(self): # test 'python -m ast -h/--help' for flag in ('-h', '--help'): - with self.subTest(flags=flag): + with self.subTest(flag=flag): with self.assertRaises(SystemExit): output = self.invoke_ast(flag) self.assertStartsWith(output, 'usage: ') @@ -3258,7 +3258,7 @@ def test_exec_mode_flag(self): TypeIgnore(lineno=1, tag='[assignment]')]) ''' for flag in ('-m=exec', '--mode=exec'): - with self.subTest(flags=flag): + with self.subTest(flag=flag): self.check_output(source, expect, flag) def test_single_mode_flag(self): @@ -3270,7 +3270,7 @@ def test_single_mode_flag(self): Pass()]) ''' for flag in ('-m=single', '--mode=single'): - with self.subTest(flags=flag): + with self.subTest(flag=flag): self.check_output(source, expect, flag) def test_eval_mode_flag(self): @@ -3286,7 +3286,7 @@ def test_eval_mode_flag(self): Constant(value=3)])) ''' for flag in ('-m=eval', '--mode=eval'): - with self.subTest(flags=flag): + with self.subTest(flag=flag): self.check_output(source, expect, flag) def test_func_type_mode_flag(self): @@ -3303,7 +3303,7 @@ def test_func_type_mode_flag(self): ctx=Load())) ''' for flag in ('-m=func_type', '--mode=func_type'): - with self.subTest(flags=flag): + with self.subTest(flag=flag): self.check_output(source, expect, flag) def test_no_type_comments_flag(self): @@ -3333,7 +3333,7 @@ def test_include_attributes_flag(self): end_col_offset=4)]) ''' for flag in ('-a', '--include-attributes'): - with self.subTest(flags=flag): + with self.subTest(flag=flag): self.check_output(source, expect, flag) def test_indent_flag(self): @@ -3345,7 +3345,7 @@ def test_indent_flag(self): Pass()]) ''' for flag in ('-i=0', '--indent=0'): - with self.subTest(flags=flag): + with self.subTest(flag=flag): self.check_output(source, expect, flag) From 42ff309fbeeee688efa5776e71a9602c1a72cd1b Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sun, 4 May 2025 16:40:04 +0400 Subject: [PATCH 08/11] Rewrite tests with help messages --- Lib/test/test_ast/test_ast.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 3f29981c102ad1..c6d19d3c254f54 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -3230,18 +3230,14 @@ def f(x: int) -> int: with self.subTest(flags=args): self.invoke_ast(*args) - def test_unknown_flag(self): - with self.assertRaises(SystemExit): - output = self.invoke_ast('--unknown') - self.assertStartsWith(output, 'usage: ') - - def test_help_flag(self): - # test 'python -m ast -h/--help' - for flag in ('-h', '--help'): + def test_help_message(self): + for flag in ('-h', '--help', '--unknown'): with self.subTest(flag=flag): + output = StringIO() with self.assertRaises(SystemExit): - output = self.invoke_ast(flag) - self.assertStartsWith(output, 'usage: ') + with contextlib.redirect_stderr(output): + ast.main(args=(flag)) + self.assertStartsWith(output.getvalue(), 'usage: ') def test_exec_mode_flag(self): # test 'python -m ast -m/--mode exec' From ac71310df3b3486b1b8a70bfb817aeb15b5b85bb Mon Sep 17 00:00:00 2001 From: donBarbos Date: Sun, 4 May 2025 23:31:15 +0400 Subject: [PATCH 09/11] Remove normalize for result --- Lib/test/test_ast/test_ast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index c6d19d3c254f54..ec7e6cf767d8ab 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -3200,7 +3200,7 @@ def invoke_ast(self, *flags): ): ast.main(args=[*flags, self.filename]) self.assertEqual(stderr.getvalue(), '') - return self.text_normalize(stdout.getvalue()) + return stdout.getvalue().strip() def check_output(self, source, expect, *flags): with self.subTest(source=source, flags=flags): From 9f6f5b2907dc173f67709b8166949b5ce58978c2 Mon Sep 17 00:00:00 2001 From: Semyon Moroz Date: Mon, 5 May 2025 00:45:32 +0400 Subject: [PATCH 10/11] Update test_ast.py --- Lib/test/test_ast/test_ast.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index ec7e6cf767d8ab..5b81ee629260b4 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -3203,11 +3203,10 @@ def invoke_ast(self, *flags): return stdout.getvalue().strip() def check_output(self, source, expect, *flags): - with self.subTest(source=source, flags=flags): - self.set_source(source) - res = self.invoke_ast(*flags) - expect = self.text_normalize(expect) - self.assertEqual(res, expect) + self.set_source(source) + res = self.invoke_ast(*flags) + expect = self.text_normalize(expect) + self.assertEqual(res, expect) def test_invocation(self): # test various combinations of parameters From 361706a92dfabeb33833b6c1283ee0247ebb8b25 Mon Sep 17 00:00:00 2001 From: Semyon Moroz Date: Mon, 5 May 2025 00:45:59 +0400 Subject: [PATCH 11/11] Update test_ast.py Co-authored-by: sobolevn --- Lib/test/test_ast/test_ast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 5b81ee629260b4..a6fc35585b13b2 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -3235,7 +3235,7 @@ def test_help_message(self): output = StringIO() with self.assertRaises(SystemExit): with contextlib.redirect_stderr(output): - ast.main(args=(flag)) + ast.main(args=flag) self.assertStartsWith(output.getvalue(), 'usage: ') def test_exec_mode_flag(self): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy