Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
gh-109485: Further improve test_future_stmt tests#109486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
fe8d76c095f0666fc2efcb56cc8e35a3a3d06c2747File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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,21 +20,48 @@ 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') | ||
| def check_syntax_error(self, err, basename, | ||
| *, | ||
| lineno, | ||
| message=TOP_LEVEL_MSG, offset=1): | ||
| if basename != '<string>': | ||
| basename += '.py' | ||
| 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 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=1, | ||
| message=TOP_LEVEL_MSG, offset=1, | ||
| parametrize_docstring=True): | ||
| code = dedent(code.lstrip('\n')) | ||
| 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, "<string>", | ||
| lineno=lineno, | ||
| message=message, | ||
| 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 +81,80 @@ 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 = """ | ||
| from __future__ import nested_scopes | ||
| from __future__ import rested_snopes # typo error here: nested => rested | ||
| """ | ||
| self.assertSyntaxError( | ||
| code, lineno=2, | ||
| message='future feature rested_snopes is not defined', | ||
| ) | ||
| 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 = """ | ||
| import some_module | ||
| from __future__ import annotations | ||
| """ | ||
| self.assertSyntaxError(code, lineno=2) | ||
| 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 = """ | ||
| import __future__ | ||
| from __future__ import annotations | ||
| """ | ||
| self.assertSyntaxError(code, lineno=2) | ||
| 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 = """ | ||
| from __future__ import absolute_import | ||
| "spam, bar, blah" | ||
| from __future__ import print_function | ||
| """ | ||
| self.assertSyntaxError(code, lineno=3) | ||
| 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, lineno=3, parametrize_docstring=False) | ||
| 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) | ||
| def test_multiple_import_statements_on_same_line(self): | ||
| # With `\`: | ||
| code = """ | ||
| from __future__ import nested_scopes; import string; from __future__ import \ | ||
| nested_scopes | ||
| """ | ||
| self.assertSyntaxError(code, 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) | ||
| # Without `\`: | ||
| code = """ | ||
| from __future__ import nested_scopes; import string; from __future__ import nested_scopes | ||
| """ | ||
| self.assertSyntaxError(code, offset=54) | ||
| def test_future_import_star(self): | ||
vstinner marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| code = """ | ||
| from __future__ import * | ||
| """ | ||
| self.assertSyntaxError(code, message='future feature * is not defined') | ||
| def test_future_import_braces(self): | ||
vstinner marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| code = """ | ||
| from __future__ import braces | ||
| """ | ||
| # Congrats, you found an easter egg! | ||
| self.assertSyntaxError(code, message='not a chance') | ||
| code = """ | ||
| from __future__ import nested_scopes, braces | ||
| """ | ||
| self.assertSyntaxError(code, message='not a chance') | ||
| def test_badfuture10(self): | ||
| def test_module_with_future_import_not_on_top(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", lineno=3) | ||
| def test_ensure_flags_dont_clash(self): | ||
| # bpo-39562: test that future flags and compiler flags doesn't clash | ||
Uh oh!
There was an error while loading. Please reload this page.