diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2019-02-16 06:12:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-16 06:12:19 (GMT) |
commit | 62e4481238b82f111ffb1104a4b97099dd83ae2b (patch) | |
tree | f679c8f683e8e01118273163c2cec077a4530777 /Lib | |
parent | a16ab00c0b8e126ab82e7cb5098af3ea32d315ff (diff) | |
download | cpython-62e4481238b82f111ffb1104a4b97099dd83ae2b.zip cpython-62e4481238b82f111ffb1104a4b97099dd83ae2b.tar.gz cpython-62e4481238b82f111ffb1104a4b97099dd83ae2b.tar.bz2 |
bpo-15248: Emit a compiler warning when missed a comma before tuple or list. (GH-11757)
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_grammar.py | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 74590eb..2ee38f0 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -1263,6 +1263,93 @@ class GrammarTests(unittest.TestCase): compile('x is True', '<testcase>', 'exec') compile('x is ...', '<testcase>', 'exec') + def test_warn_missed_comma(self): + def check(test): + with self.assertWarnsRegex(SyntaxWarning, msg): + compile(test, '<testcase>', 'exec') + with warnings.catch_warnings(): + warnings.filterwarnings('error', category=SyntaxWarning) + with self.assertRaisesRegex(SyntaxError, msg): + compile(test, '<testcase>', 'exec') + + msg=r'is not callable; perhaps you missed a comma\?' + check('[(1, 2) (3, 4)]') + check('[(x, y) (3, 4)]') + check('[[1, 2] (3, 4)]') + check('[{1, 2} (3, 4)]') + check('[{1: 2} (3, 4)]') + check('[[i for i in range(5)] (3, 4)]') + check('[{i for i in range(5)} (3, 4)]') + check('[(i for i in range(5)) (3, 4)]') + check('[{i: i for i in range(5)} (3, 4)]') + check('[f"{x}" (3, 4)]') + check('[f"x={x}" (3, 4)]') + check('["abc" (3, 4)]') + check('[b"abc" (3, 4)]') + check('[123 (3, 4)]') + check('[12.3 (3, 4)]') + check('[12.3j (3, 4)]') + check('[None (3, 4)]') + check('[True (3, 4)]') + check('[... (3, 4)]') + + msg=r'is not subscriptable; perhaps you missed a comma\?' + check('[{1, 2} [i, j]]') + check('[{i for i in range(5)} [i, j]]') + check('[(i for i in range(5)) [i, j]]') + check('[(lambda x, y: x) [i, j]]') + check('[123 [i, j]]') + check('[12.3 [i, j]]') + check('[12.3j [i, j]]') + check('[None [i, j]]') + check('[True [i, j]]') + check('[... [i, j]]') + + msg=r'indices must be integers or slices, not tuple; perhaps you missed a comma\?' + check('[(1, 2) [i, j]]') + check('[(x, y) [i, j]]') + check('[[1, 2] [i, j]]') + check('[[i for i in range(5)] [i, j]]') + check('[f"{x}" [i, j]]') + check('[f"x={x}" [i, j]]') + check('["abc" [i, j]]') + check('[b"abc" [i, j]]') + + msg=r'indices must be integers or slices, not tuple;' + check('[[1, 2] [3, 4]]') + msg=r'indices must be integers or slices, not list;' + check('[[1, 2] [[3, 4]]]') + check('[[1, 2] [[i for i in range(5)]]]') + msg=r'indices must be integers or slices, not set;' + check('[[1, 2] [{3, 4}]]') + check('[[1, 2] [{i for i in range(5)}]]') + msg=r'indices must be integers or slices, not dict;' + check('[[1, 2] [{3: 4}]]') + check('[[1, 2] [{i: i for i in range(5)}]]') + msg=r'indices must be integers or slices, not generator;' + check('[[1, 2] [(i for i in range(5))]]') + msg=r'indices must be integers or slices, not function;' + check('[[1, 2] [(lambda x, y: x)]]') + msg=r'indices must be integers or slices, not str;' + check('[[1, 2] [f"{x}"]]') + check('[[1, 2] [f"x={x}"]]') + check('[[1, 2] ["abc"]]') + msg=r'indices must be integers or slices, not' + check('[[1, 2] [b"abc"]]') + check('[[1, 2] [12.3]]') + check('[[1, 2] [12.3j]]') + check('[[1, 2] [None]]') + check('[[1, 2] [...]]') + + with warnings.catch_warnings(): + warnings.filterwarnings('error', category=SyntaxWarning) + compile('[(lambda x, y: x) (3, 4)]', '<testcase>', 'exec') + compile('[[1, 2] [i]]', '<testcase>', 'exec') + compile('[[1, 2] [0]]', '<testcase>', 'exec') + compile('[[1, 2] [True]]', '<testcase>', 'exec') + compile('[[1, 2] [1:2]]', '<testcase>', 'exec') + compile('[{(1, 2): 3} [i, j]]', '<testcase>', 'exec') + def test_binary_mask_ops(self): x = 1 & 1 x = 1 ^ 1 |