From fe8d76c63482f8185e05f4b33b905ff8c6d190b3 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sat, 16 Sep 2023 13:28:43 +0300 Subject: [PATCH 1/6] gh-109485: Further improve `test_future_stmt` tests --- ...syntax_future10.py => badsyntax_future.py} | 0 .../test_future_stmt/badsyntax_future3.py | 10 -- .../test_future_stmt/badsyntax_future4.py | 10 -- .../test_future_stmt/badsyntax_future5.py | 12 -- .../test_future_stmt/badsyntax_future6.py | 10 -- .../test_future_stmt/badsyntax_future7.py | 11 -- .../test_future_stmt/badsyntax_future8.py | 10 -- .../test_future_stmt/badsyntax_future9.py | 10 -- ..._test1.py => import_nested_scope_twice.py} | 0 .../{future_test2.py => nested_scope.py} | 0 Lib/test/test_future_stmt/test_future.py | 139 ++++++++++++------ 11 files changed, 98 insertions(+), 114 deletions(-) rename Lib/test/test_future_stmt/{badsyntax_future10.py => badsyntax_future.py} (100%) delete mode 100644 Lib/test/test_future_stmt/badsyntax_future3.py delete mode 100644 Lib/test/test_future_stmt/badsyntax_future4.py delete mode 100644 Lib/test/test_future_stmt/badsyntax_future5.py delete mode 100644 Lib/test/test_future_stmt/badsyntax_future6.py delete mode 100644 Lib/test/test_future_stmt/badsyntax_future7.py delete mode 100644 Lib/test/test_future_stmt/badsyntax_future8.py delete mode 100644 Lib/test/test_future_stmt/badsyntax_future9.py rename Lib/test/test_future_stmt/{future_test1.py => import_nested_scope_twice.py} (100%) rename Lib/test/test_future_stmt/{future_test2.py => nested_scope.py} (100%) diff --git a/Lib/test/test_future_stmt/badsyntax_future10.py b/Lib/test/test_future_stmt/badsyntax_future.py similarity index 100% rename from Lib/test/test_future_stmt/badsyntax_future10.py rename to Lib/test/test_future_stmt/badsyntax_future.py diff --git a/Lib/test/test_future_stmt/badsyntax_future3.py b/Lib/test/test_future_stmt/badsyntax_future3.py deleted file mode 100644 index f1c8417edaa297..00000000000000 --- a/Lib/test/test_future_stmt/badsyntax_future3.py +++ /dev/null @@ -1,10 +0,0 @@ -"""This is a test""" -from __future__ import nested_scopes -from __future__ import rested_snopes - -def f(x): - def g(y): - return x + y - return g - -result = f(2)(4) diff --git a/Lib/test/test_future_stmt/badsyntax_future4.py b/Lib/test/test_future_stmt/badsyntax_future4.py deleted file mode 100644 index b5f4c98e922ac2..00000000000000 --- a/Lib/test/test_future_stmt/badsyntax_future4.py +++ /dev/null @@ -1,10 +0,0 @@ -"""This is a test""" -import __future__ -from __future__ import nested_scopes - -def f(x): - def g(y): - return x + y - return g - -result = f(2)(4) diff --git a/Lib/test/test_future_stmt/badsyntax_future5.py b/Lib/test/test_future_stmt/badsyntax_future5.py deleted file mode 100644 index 8a7e5fcb70ff2e..00000000000000 --- a/Lib/test/test_future_stmt/badsyntax_future5.py +++ /dev/null @@ -1,12 +0,0 @@ -"""This is a test""" -from __future__ import nested_scopes -import foo -from __future__ import nested_scopes - - -def f(x): - def g(y): - return x + y - return g - -result = f(2)(4) diff --git a/Lib/test/test_future_stmt/badsyntax_future6.py b/Lib/test/test_future_stmt/badsyntax_future6.py deleted file mode 100644 index 5a8b55a02c41bf..00000000000000 --- a/Lib/test/test_future_stmt/badsyntax_future6.py +++ /dev/null @@ -1,10 +0,0 @@ -"""This is a test""" -"this isn't a doc string" -from __future__ import nested_scopes - -def f(x): - def g(y): - return x + y - return g - -result = f(2)(4) diff --git a/Lib/test/test_future_stmt/badsyntax_future7.py b/Lib/test/test_future_stmt/badsyntax_future7.py deleted file mode 100644 index 131db2c2164cf2..00000000000000 --- a/Lib/test/test_future_stmt/badsyntax_future7.py +++ /dev/null @@ -1,11 +0,0 @@ -"""This is a test""" - -from __future__ import nested_scopes; import string; from __future__ import \ - nested_scopes - -def f(x): - def g(y): - return x + y - return g - -result = f(2)(4) diff --git a/Lib/test/test_future_stmt/badsyntax_future8.py b/Lib/test/test_future_stmt/badsyntax_future8.py deleted file mode 100644 index ca45289e2e5a4f..00000000000000 --- a/Lib/test/test_future_stmt/badsyntax_future8.py +++ /dev/null @@ -1,10 +0,0 @@ -"""This is a test""" - -from __future__ import * - -def f(x): - def g(y): - return x + y - return g - -print(f(2)(4)) diff --git a/Lib/test/test_future_stmt/badsyntax_future9.py b/Lib/test/test_future_stmt/badsyntax_future9.py deleted file mode 100644 index 916de06ab71e97..00000000000000 --- a/Lib/test/test_future_stmt/badsyntax_future9.py +++ /dev/null @@ -1,10 +0,0 @@ -"""This is a test""" - -from __future__ import nested_scopes, braces - -def f(x): - def g(y): - return x + y - return g - -print(f(2)(4)) diff --git a/Lib/test/test_future_stmt/future_test1.py b/Lib/test/test_future_stmt/import_nested_scope_twice.py similarity index 100% rename from Lib/test/test_future_stmt/future_test1.py rename to Lib/test/test_future_stmt/import_nested_scope_twice.py diff --git a/Lib/test/test_future_stmt/future_test2.py b/Lib/test/test_future_stmt/nested_scope.py similarity index 100% rename from Lib/test/test_future_stmt/future_test2.py rename to Lib/test/test_future_stmt/nested_scope.py diff --git a/Lib/test/test_future_stmt/test_future.py b/Lib/test/test_future_stmt/test_future.py index 8e67bcd72c91c5..7220abe1ba63ad 100644 --- a/Lib/test/test_future_stmt/test_future.py +++ b/Lib/test/test_future_stmt/test_future.py @@ -19,20 +19,37 @@ def get_error_location(msg): class FutureTest(unittest.TestCase): def check_syntax_error(self, err, basename, lineno, offset=1): - self.assertIn('%s.py, line %d' % (basename, lineno), str(err)) - self.assertEqual(os.path.basename(err.filename), basename + '.py') + if basename != '': + basename += '.py' + + self.assertIn(f'{basename}, line {lineno}', str(err)) + self.assertEqual(os.path.basename(err.filename), basename) self.assertEqual(err.lineno, lineno) self.assertEqual(err.offset, offset) - def test_future1(self): - with import_helper.CleanImport('test.test_future_stmt.future_test1'): - from test.test_future_stmt import future_test1 - self.assertEqual(future_test1.result, 6) + def assertSyntaxError(self, code, lineno, offset=1, *, parametrize_docstring=True): + code = dedent(code) + for trim_docstring in ([False, True] if parametrize_docstring else [False]): + with self.subTest(trim_docstring=trim_docstring): + if trim_docstring: + code = os.linesep.join(code.splitlines()[2:]) + lineno -= 2 + with self.assertRaises(SyntaxError) as cm: + exec(code) + self.check_syntax_error(cm.exception, "", lineno, offset=offset) + + def test_import_nested_scope_twice(self): + # Import the name nested_scopes twice to trigger SF bug #407394 + with import_helper.CleanImport( + 'test.test_future_stmt.import_nested_scope_twice', + ): + from test.test_future_stmt import import_nested_scope_twice + self.assertEqual(import_nested_scope_twice.result, 6) - def test_future2(self): - with import_helper.CleanImport('test.test_future_stmt.future_test2'): - from test.test_future_stmt import future_test2 - self.assertEqual(future_test2.result, 6) + def test_nested_scope(self): + with import_helper.CleanImport('test.test_future_stmt.nested_scope'): + from test.test_future_stmt import nested_scope + self.assertEqual(nested_scope.result, 6) def test_future_single_import(self): with import_helper.CleanImport( @@ -52,45 +69,85 @@ def test_future_multiple_features(self): ): from test.test_future_stmt import test_future_multiple_features - def test_badfuture3(self): - with self.assertRaises(SyntaxError) as cm: - from test.test_future_stmt import badsyntax_future3 - self.check_syntax_error(cm.exception, "badsyntax_future3", 3) + def test_unknown_future_flag(self): + code = """ + '''Docstring''' + from __future__ import nested_scopes + from __future__ import rested_snopes # error here + """ + self.assertSyntaxError(code, 4) - def test_badfuture4(self): - with self.assertRaises(SyntaxError) as cm: - from test.test_future_stmt import badsyntax_future4 - self.check_syntax_error(cm.exception, "badsyntax_future4", 3) + def test_future_import_not_on_top(self): + code = """ + '''Docstring''' + import some_module + from __future__ import annotations + """ + self.assertSyntaxError(code, 4) - def test_badfuture5(self): - with self.assertRaises(SyntaxError) as cm: - from test.test_future_stmt import badsyntax_future5 - self.check_syntax_error(cm.exception, "badsyntax_future5", 4) + code = """ + '''Docstring''' + import __future__ + from __future__ import annotations + """ + self.assertSyntaxError(code, 4) - def test_badfuture6(self): - with self.assertRaises(SyntaxError) as cm: - from test.test_future_stmt import badsyntax_future6 - self.check_syntax_error(cm.exception, "badsyntax_future6", 3) + code = """ + '''Docstring''' + from __future__ import absolute_import + "spam, bar, blah" + from __future__ import print_function + """ + self.assertSyntaxError(code, 5) - def test_badfuture7(self): - with self.assertRaises(SyntaxError) as cm: - from test.test_future_stmt import badsyntax_future7 - self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 54) + def test_future_import_with_extra_string(self): + code = """ + '''Docstring''' + "this isn't a doc string" + from __future__ import nested_scopes + """ + self.assertSyntaxError(code, 4, parametrize_docstring=False) + + def test_multiple_import_statements_on_same_line(self): + # With `\`: + code = """ + '''Docstring''' + from __future__ import nested_scopes; import string; from __future__ import \ + nested_scopes + """ + self.assertSyntaxError(code, 3, offset=54) - def test_badfuture8(self): - with self.assertRaises(SyntaxError) as cm: - from test.test_future_stmt import badsyntax_future8 - self.check_syntax_error(cm.exception, "badsyntax_future8", 3) + # Without `\`: + code = """ + '''Docstring''' + from __future__ import nested_scopes; import string; from __future__ import nested_scopes + """ + self.assertSyntaxError(code, 3, offset=54) - def test_badfuture9(self): - with self.assertRaises(SyntaxError) as cm: - from test.test_future_stmt import badsyntax_future9 - self.check_syntax_error(cm.exception, "badsyntax_future9", 3) + def test_future_import_star(self): + code = """ + '''Docstring''' + from __future__ import * + """ + self.assertSyntaxError(code, 3) + + def test_future_import_braces(self): + code = """ + '''Docstring''' + from __future__ import braces + """ + self.assertSyntaxError(code, 3) + + code = """ + '''Docstring''' + from __future__ import nested_scopes, braces + """ + self.assertSyntaxError(code, 3) - def test_badfuture10(self): + def test_bad_future_as_module(self): with self.assertRaises(SyntaxError) as cm: - from test.test_future_stmt import badsyntax_future10 - self.check_syntax_error(cm.exception, "badsyntax_future10", 3) + from test.test_future_stmt import badsyntax_future + self.check_syntax_error(cm.exception, "badsyntax_future", 3) def test_ensure_flags_dont_clash(self): # bpo-39562: test that future flags and compiler flags doesn't clash From 095f0669d4f6e6b8bbdc7daf32134f11c6bb516c Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sun, 17 Sep 2023 09:53:21 +0300 Subject: [PATCH 2/6] Address review --- Lib/test/test_future_stmt/test_future.py | 54 ++++++++++++------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Lib/test/test_future_stmt/test_future.py b/Lib/test/test_future_stmt/test_future.py index 7220abe1ba63ad..ddcc7cef55830a 100644 --- a/Lib/test/test_future_stmt/test_future.py +++ b/Lib/test/test_future_stmt/test_future.py @@ -71,76 +71,76 @@ def test_future_multiple_features(self): def test_unknown_future_flag(self): code = """ - '''Docstring''' - from __future__ import nested_scopes - from __future__ import rested_snopes # error here + '''Docstring''' + from __future__ import nested_scopes + from __future__ import rested_snopes # typo error here: nested => rested """ self.assertSyntaxError(code, 4) def test_future_import_not_on_top(self): code = """ - '''Docstring''' - import some_module - from __future__ import annotations + '''Docstring''' + import some_module + from __future__ import annotations """ self.assertSyntaxError(code, 4) code = """ - '''Docstring''' - import __future__ - from __future__ import annotations + '''Docstring''' + import __future__ + from __future__ import annotations """ self.assertSyntaxError(code, 4) code = """ - '''Docstring''' - from __future__ import absolute_import - "spam, bar, blah" - from __future__ import print_function + '''Docstring''' + from __future__ import absolute_import + "spam, bar, blah" + from __future__ import print_function """ self.assertSyntaxError(code, 5) def test_future_import_with_extra_string(self): code = """ - '''Docstring''' - "this isn't a doc string" - from __future__ import nested_scopes + '''Docstring''' + "this isn't a doc string" + from __future__ import nested_scopes """ self.assertSyntaxError(code, 4, parametrize_docstring=False) def test_multiple_import_statements_on_same_line(self): # With `\`: code = """ - '''Docstring''' - from __future__ import nested_scopes; import string; from __future__ import \ - nested_scopes + '''Docstring''' + from __future__ import nested_scopes; import string; from __future__ import \ + nested_scopes """ self.assertSyntaxError(code, 3, offset=54) # Without `\`: code = """ - '''Docstring''' - from __future__ import nested_scopes; import string; from __future__ import nested_scopes + '''Docstring''' + from __future__ import nested_scopes; import string; from __future__ import nested_scopes """ self.assertSyntaxError(code, 3, offset=54) def test_future_import_star(self): code = """ - '''Docstring''' - from __future__ import * + '''Docstring''' + from __future__ import * """ self.assertSyntaxError(code, 3) def test_future_import_braces(self): code = """ - '''Docstring''' - from __future__ import braces + '''Docstring''' + from __future__ import braces """ self.assertSyntaxError(code, 3) code = """ - '''Docstring''' - from __future__ import nested_scopes, braces + '''Docstring''' + from __future__ import nested_scopes, braces """ self.assertSyntaxError(code, 3) From 6fc2efcca929da79a38546d20a501a2d9598fb36 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 18 Sep 2023 18:47:48 +0300 Subject: [PATCH 3/6] Address review --- Lib/test/test_future_stmt/test_future.py | 31 ++++++++++++++++-------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_future_stmt/test_future.py b/Lib/test/test_future_stmt/test_future.py index ddcc7cef55830a..56f58e819f04d2 100644 --- a/Lib/test/test_future_stmt/test_future.py +++ b/Lib/test/test_future_stmt/test_future.py @@ -10,6 +10,8 @@ import re import sys +TOP_LEVEL_MSG = 'from __future__ imports must occur at the beginning of the file' + rx = re.compile(r'\((\S+).py, line (\d+)') def get_error_location(msg): @@ -18,25 +20,30 @@ def get_error_location(msg): class FutureTest(unittest.TestCase): - def check_syntax_error(self, err, basename, lineno, offset=1): + def check_syntax_error(self, err, basename, lineno, + message=TOP_LEVEL_MSG, offset=1): if basename != '': basename += '.py' - self.assertIn(f'{basename}, line {lineno}', str(err)) + self.assertEqual(f'{message} ({basename}, line {lineno})', str(err)) self.assertEqual(os.path.basename(err.filename), basename) self.assertEqual(err.lineno, lineno) self.assertEqual(err.offset, offset) - def assertSyntaxError(self, code, lineno, offset=1, *, parametrize_docstring=True): + def assertSyntaxError(self, code, lineno, + message=TOP_LEVEL_MSG, offset=1, + *, + parametrize_docstring=True): code = dedent(code) for trim_docstring in ([False, True] if parametrize_docstring else [False]): - with self.subTest(trim_docstring=trim_docstring): + with self.subTest(code=code, trim_docstring=trim_docstring): if trim_docstring: code = os.linesep.join(code.splitlines()[2:]) lineno -= 2 with self.assertRaises(SyntaxError) as cm: exec(code) - self.check_syntax_error(cm.exception, "", lineno, offset=offset) + self.check_syntax_error(cm.exception, "", lineno, + message, offset=offset) def test_import_nested_scope_twice(self): # Import the name nested_scopes twice to trigger SF bug #407394 @@ -75,7 +82,10 @@ def test_unknown_future_flag(self): from __future__ import nested_scopes from __future__ import rested_snopes # typo error here: nested => rested """ - self.assertSyntaxError(code, 4) + self.assertSyntaxError( + code, 4, + message='future feature rested_snopes is not defined', + ) def test_future_import_not_on_top(self): code = """ @@ -129,22 +139,23 @@ def test_future_import_star(self): '''Docstring''' from __future__ import * """ - self.assertSyntaxError(code, 3) + self.assertSyntaxError(code, 3, message='future feature * is not defined') def test_future_import_braces(self): code = """ '''Docstring''' from __future__ import braces """ - self.assertSyntaxError(code, 3) + # Congrats, you found an easter egg! + self.assertSyntaxError(code, 3, message='not a chance') code = """ '''Docstring''' from __future__ import nested_scopes, braces """ - self.assertSyntaxError(code, 3) + self.assertSyntaxError(code, 3, message='not a chance') - def test_bad_future_as_module(self): + def test_module_with_future_import_not_on_top(self): with self.assertRaises(SyntaxError) as cm: from test.test_future_stmt import badsyntax_future self.check_syntax_error(cm.exception, "badsyntax_future", 3) From b56cc8e975df252e348b110d35ce8111ad68eeb2 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 18 Sep 2023 19:49:14 +0300 Subject: [PATCH 4/6] Kw `lineno` --- Lib/test/test_future_stmt/test_future.py | 40 ++++++++++++++---------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/Lib/test/test_future_stmt/test_future.py b/Lib/test/test_future_stmt/test_future.py index 56f58e819f04d2..2140b0d7c2a09e 100644 --- a/Lib/test/test_future_stmt/test_future.py +++ b/Lib/test/test_future_stmt/test_future.py @@ -20,7 +20,9 @@ def get_error_location(msg): class FutureTest(unittest.TestCase): - def check_syntax_error(self, err, basename, lineno, + def check_syntax_error(self, err, basename, + *, + lineno, message=TOP_LEVEL_MSG, offset=1): if basename != '': basename += '.py' @@ -30,9 +32,10 @@ def check_syntax_error(self, err, basename, lineno, self.assertEqual(err.lineno, lineno) self.assertEqual(err.offset, offset) - def assertSyntaxError(self, code, lineno, - message=TOP_LEVEL_MSG, offset=1, + def assertSyntaxError(self, code, *, + lineno, + message=TOP_LEVEL_MSG, offset=1, parametrize_docstring=True): code = dedent(code) for trim_docstring in ([False, True] if parametrize_docstring else [False]): @@ -42,8 +45,10 @@ def assertSyntaxError(self, code, lineno, lineno -= 2 with self.assertRaises(SyntaxError) as cm: exec(code) - self.check_syntax_error(cm.exception, "", lineno, - message, offset=offset) + self.check_syntax_error(cm.exception, "", + lineno=lineno, + message=message, + offset=offset) def test_import_nested_scope_twice(self): # Import the name nested_scopes twice to trigger SF bug #407394 @@ -83,7 +88,7 @@ def test_unknown_future_flag(self): from __future__ import rested_snopes # typo error here: nested => rested """ self.assertSyntaxError( - code, 4, + code, lineno=4, message='future feature rested_snopes is not defined', ) @@ -93,14 +98,14 @@ def test_future_import_not_on_top(self): import some_module from __future__ import annotations """ - self.assertSyntaxError(code, 4) + self.assertSyntaxError(code, lineno=4) code = """ '''Docstring''' import __future__ from __future__ import annotations """ - self.assertSyntaxError(code, 4) + self.assertSyntaxError(code, lineno=4) code = """ '''Docstring''' @@ -108,7 +113,7 @@ def test_future_import_not_on_top(self): "spam, bar, blah" from __future__ import print_function """ - self.assertSyntaxError(code, 5) + self.assertSyntaxError(code, lineno=5) def test_future_import_with_extra_string(self): code = """ @@ -116,7 +121,7 @@ def test_future_import_with_extra_string(self): "this isn't a doc string" from __future__ import nested_scopes """ - self.assertSyntaxError(code, 4, parametrize_docstring=False) + self.assertSyntaxError(code, lineno=4, parametrize_docstring=False) def test_multiple_import_statements_on_same_line(self): # With `\`: @@ -125,21 +130,24 @@ def test_multiple_import_statements_on_same_line(self): from __future__ import nested_scopes; import string; from __future__ import \ nested_scopes """ - self.assertSyntaxError(code, 3, offset=54) + self.assertSyntaxError(code, lineno=3, offset=54) # Without `\`: code = """ '''Docstring''' from __future__ import nested_scopes; import string; from __future__ import nested_scopes """ - self.assertSyntaxError(code, 3, offset=54) + self.assertSyntaxError(code, lineno=3, offset=54) def test_future_import_star(self): code = """ '''Docstring''' from __future__ import * """ - self.assertSyntaxError(code, 3, message='future feature * is not defined') + self.assertSyntaxError( + code, lineno=3, + message='future feature * is not defined', + ) def test_future_import_braces(self): code = """ @@ -147,18 +155,18 @@ def test_future_import_braces(self): from __future__ import braces """ # Congrats, you found an easter egg! - self.assertSyntaxError(code, 3, message='not a chance') + self.assertSyntaxError(code, lineno=3, message='not a chance') code = """ '''Docstring''' from __future__ import nested_scopes, braces """ - self.assertSyntaxError(code, 3, message='not a chance') + self.assertSyntaxError(code, lineno=3, message='not a chance') def test_module_with_future_import_not_on_top(self): with self.assertRaises(SyntaxError) as cm: from test.test_future_stmt import badsyntax_future - self.check_syntax_error(cm.exception, "badsyntax_future", 3) + self.check_syntax_error(cm.exception, "badsyntax_future", lineno=3) def test_ensure_flags_dont_clash(self): # bpo-39562: test that future flags and compiler flags doesn't clash From 35a3a3de02f824b1e6069013cf2cd54752638fba Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 18 Sep 2023 19:58:30 +0300 Subject: [PATCH 5/6] Adjust lineno --- Lib/test/test_future_stmt/test_future.py | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_future_stmt/test_future.py b/Lib/test/test_future_stmt/test_future.py index 2140b0d7c2a09e..40e13dd643aed9 100644 --- a/Lib/test/test_future_stmt/test_future.py +++ b/Lib/test/test_future_stmt/test_future.py @@ -37,12 +37,12 @@ def assertSyntaxError(self, code, lineno, message=TOP_LEVEL_MSG, offset=1, parametrize_docstring=True): - code = dedent(code) + code = dedent(code.lstrip('\n')) for trim_docstring in ([False, True] if parametrize_docstring else [False]): with self.subTest(code=code, trim_docstring=trim_docstring): if trim_docstring: - code = os.linesep.join(code.splitlines()[2:]) - lineno -= 2 + code = os.linesep.join(code.splitlines()[1:]) + lineno -= 1 with self.assertRaises(SyntaxError) as cm: exec(code) self.check_syntax_error(cm.exception, "", @@ -88,7 +88,7 @@ def test_unknown_future_flag(self): from __future__ import rested_snopes # typo error here: nested => rested """ self.assertSyntaxError( - code, lineno=4, + code, lineno=3, message='future feature rested_snopes is not defined', ) @@ -98,14 +98,14 @@ def test_future_import_not_on_top(self): import some_module from __future__ import annotations """ - self.assertSyntaxError(code, lineno=4) + self.assertSyntaxError(code, lineno=3) code = """ '''Docstring''' import __future__ from __future__ import annotations """ - self.assertSyntaxError(code, lineno=4) + self.assertSyntaxError(code, lineno=3) code = """ '''Docstring''' @@ -113,7 +113,7 @@ def test_future_import_not_on_top(self): "spam, bar, blah" from __future__ import print_function """ - self.assertSyntaxError(code, lineno=5) + self.assertSyntaxError(code, lineno=4) def test_future_import_with_extra_string(self): code = """ @@ -121,7 +121,7 @@ def test_future_import_with_extra_string(self): "this isn't a doc string" from __future__ import nested_scopes """ - self.assertSyntaxError(code, lineno=4, parametrize_docstring=False) + self.assertSyntaxError(code, lineno=3, parametrize_docstring=False) def test_multiple_import_statements_on_same_line(self): # With `\`: @@ -130,14 +130,14 @@ def test_multiple_import_statements_on_same_line(self): from __future__ import nested_scopes; import string; from __future__ import \ nested_scopes """ - self.assertSyntaxError(code, lineno=3, offset=54) + self.assertSyntaxError(code, lineno=2, offset=54) # Without `\`: code = """ '''Docstring''' from __future__ import nested_scopes; import string; from __future__ import nested_scopes """ - self.assertSyntaxError(code, lineno=3, offset=54) + self.assertSyntaxError(code, lineno=2, offset=54) def test_future_import_star(self): code = """ @@ -145,7 +145,7 @@ def test_future_import_star(self): from __future__ import * """ self.assertSyntaxError( - code, lineno=3, + code, lineno=2, message='future feature * is not defined', ) @@ -155,13 +155,13 @@ def test_future_import_braces(self): from __future__ import braces """ # Congrats, you found an easter egg! - self.assertSyntaxError(code, lineno=3, message='not a chance') + self.assertSyntaxError(code, lineno=2, message='not a chance') code = """ '''Docstring''' from __future__ import nested_scopes, braces """ - self.assertSyntaxError(code, lineno=3, message='not a chance') + self.assertSyntaxError(code, lineno=2, message='not a chance') def test_module_with_future_import_not_on_top(self): with self.assertRaises(SyntaxError) as cm: From 06c2747b1e7331f7065d1579dfc756059d54f6d0 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 18 Sep 2023 21:42:00 +0300 Subject: [PATCH 6/6] Add docstring in parametrization --- Lib/test/test_future_stmt/test_future.py | 42 +++++++++--------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/Lib/test/test_future_stmt/test_future.py b/Lib/test/test_future_stmt/test_future.py index 40e13dd643aed9..2c8ceb664cb362 100644 --- a/Lib/test/test_future_stmt/test_future.py +++ b/Lib/test/test_future_stmt/test_future.py @@ -34,15 +34,15 @@ def check_syntax_error(self, err, basename, def assertSyntaxError(self, code, *, - lineno, + lineno=1, message=TOP_LEVEL_MSG, offset=1, parametrize_docstring=True): code = dedent(code.lstrip('\n')) - for trim_docstring in ([False, True] if parametrize_docstring else [False]): - with self.subTest(code=code, trim_docstring=trim_docstring): - if trim_docstring: - code = os.linesep.join(code.splitlines()[1:]) - lineno -= 1 + for add_docstring in ([False, True] if parametrize_docstring else [False]): + with self.subTest(code=code, add_docstring=add_docstring): + if add_docstring: + code = '"""Docstring"""\n' + code + lineno += 1 with self.assertRaises(SyntaxError) as cm: exec(code) self.check_syntax_error(cm.exception, "", @@ -83,37 +83,33 @@ def test_future_multiple_features(self): def test_unknown_future_flag(self): code = """ - '''Docstring''' from __future__ import nested_scopes from __future__ import rested_snopes # typo error here: nested => rested """ self.assertSyntaxError( - code, lineno=3, + code, lineno=2, message='future feature rested_snopes is not defined', ) def test_future_import_not_on_top(self): code = """ - '''Docstring''' import some_module from __future__ import annotations """ - self.assertSyntaxError(code, lineno=3) + self.assertSyntaxError(code, lineno=2) code = """ - '''Docstring''' import __future__ from __future__ import annotations """ - self.assertSyntaxError(code, lineno=3) + self.assertSyntaxError(code, lineno=2) code = """ - '''Docstring''' from __future__ import absolute_import "spam, bar, blah" from __future__ import print_function """ - self.assertSyntaxError(code, lineno=4) + self.assertSyntaxError(code, lineno=3) def test_future_import_with_extra_string(self): code = """ @@ -126,42 +122,34 @@ def test_future_import_with_extra_string(self): def test_multiple_import_statements_on_same_line(self): # With `\`: code = """ - '''Docstring''' from __future__ import nested_scopes; import string; from __future__ import \ nested_scopes """ - self.assertSyntaxError(code, lineno=2, offset=54) + self.assertSyntaxError(code, offset=54) # Without `\`: code = """ - '''Docstring''' from __future__ import nested_scopes; import string; from __future__ import nested_scopes """ - self.assertSyntaxError(code, lineno=2, offset=54) + self.assertSyntaxError(code, offset=54) def test_future_import_star(self): code = """ - '''Docstring''' from __future__ import * """ - self.assertSyntaxError( - code, lineno=2, - message='future feature * is not defined', - ) + self.assertSyntaxError(code, message='future feature * is not defined') def test_future_import_braces(self): code = """ - '''Docstring''' from __future__ import braces """ # Congrats, you found an easter egg! - self.assertSyntaxError(code, lineno=2, message='not a chance') + self.assertSyntaxError(code, message='not a chance') code = """ - '''Docstring''' from __future__ import nested_scopes, braces """ - self.assertSyntaxError(code, lineno=2, message='not a chance') + self.assertSyntaxError(code, message='not a chance') def test_module_with_future_import_not_on_top(self): with self.assertRaises(SyntaxError) as cm: