summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2019-02-16 06:12:19 (GMT)
committerGitHub <noreply@github.com>2019-02-16 06:12:19 (GMT)
commit62e4481238b82f111ffb1104a4b97099dd83ae2b (patch)
treef679c8f683e8e01118273163c2cec077a4530777 /Lib
parenta16ab00c0b8e126ab82e7cb5098af3ea32d315ff (diff)
downloadcpython-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.py87
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