-
-
Notifications
You must be signed in to change notification settings - Fork 32.8k
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
Changes from 1 commit
fe8d76c
095f066
6fc2efc
b56cc8e
35a3a3d
06c2747
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 != '<string>': | ||
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: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Last question: instead of copy/paste |
||
code = os.linesep.join(code.splitlines()[2:]) | ||
lineno -= 2 | ||
with self.assertRaises(SyntaxError) as cm: | ||
exec(code) | ||
self.check_syntax_error(cm.exception, "<string>", 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) | ||
vstinner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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''' | ||
sobolevn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
from __future__ import nested_scopes | ||
from __future__ import rested_snopes # error here | ||
sobolevn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
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): | ||
vstinner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
code = """ | ||
'''Docstring''' | ||
from __future__ import * | ||
""" | ||
self.assertSyntaxError(code, 3) | ||
|
||
def test_future_import_braces(self): | ||
vstinner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test name is not clear. The expected error is:
|
||
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 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like code first line is always empty. I suggest using:
And adapt
lineno -= 2
and other references to lineno below.For example, for me, test_unknown_future_flag() code has only 3 lines and expect an error on the 4th line, it's strange.