diff options
author | Pablo Galindo <Pablogsal@gmail.com> | 2021-04-12 15:59:30 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-12 15:59:30 (GMT) |
commit | b86ed8e3bb41ede77eeab4a8bb4e2b91a8065283 (patch) | |
tree | 250e32e95a6bead87006d2e1e1a06d9058fc3b91 /Lib | |
parent | 2459b92a4db69d9b14d0a86a9b81cc075894e910 (diff) | |
download | cpython-b86ed8e3bb41ede77eeab4a8bb4e2b91a8065283.zip cpython-b86ed8e3bb41ede77eeab4a8bb4e2b91a8065283.tar.gz cpython-b86ed8e3bb41ede77eeab4a8bb4e2b91a8065283.tar.bz2 |
bpo-43797: Improve syntax error for invalid comparisons (#25317)
* bpo-43797: Improve syntax error for invalid comparisons
* Update Lib/test/test_fstring.py
Co-authored-by: Guido van Rossum <gvanrossum@gmail.com>
* Apply review comments
* can't -> cannot
Co-authored-by: Guido van Rossum <gvanrossum@gmail.com>
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_cmd_line_script.py | 8 | ||||
-rw-r--r-- | Lib/test/test_codeop.py | 1 | ||||
-rw-r--r-- | Lib/test/test_exceptions.py | 2 | ||||
-rw-r--r-- | Lib/test/test_fstring.py | 6 | ||||
-rw-r--r-- | Lib/test/test_generators.py | 2 | ||||
-rw-r--r-- | Lib/test/test_genexps.py | 2 | ||||
-rw-r--r-- | Lib/test/test_syntax.py | 116 | ||||
-rw-r--r-- | Lib/test/test_unpack_ex.py | 10 |
8 files changed, 83 insertions, 64 deletions
diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 8f12b1e..2e0b5f7 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -600,8 +600,8 @@ class CmdLineTest(unittest.TestCase): script_name = _make_test_script(script_dir, 'script', script) exitcode, stdout, stderr = assert_python_failure(script_name) text = io.TextIOWrapper(io.BytesIO(stderr), 'ascii').read() - # Confirm that the caret is located under the first 1 character - self.assertIn("\n 1 + 1 = 2\n ^", text) + # Confirm that the caret is located under the '=' sign + self.assertIn("\n 1 + 1 = 2\n ^\n", text) def test_syntaxerror_indented_caret_position(self): script = textwrap.dedent("""\ @@ -613,7 +613,7 @@ class CmdLineTest(unittest.TestCase): exitcode, stdout, stderr = assert_python_failure(script_name) text = io.TextIOWrapper(io.BytesIO(stderr), 'ascii').read() # Confirm that the caret is located under the first 1 character - self.assertIn("\n 1 + 1 = 2\n ^", text) + self.assertIn("\n 1 + 1 = 2\n ^\n", text) # Try the same with a form feed at the start of the indented line script = ( @@ -624,7 +624,7 @@ class CmdLineTest(unittest.TestCase): exitcode, stdout, stderr = assert_python_failure(script_name) text = io.TextIOWrapper(io.BytesIO(stderr), "ascii").read() self.assertNotIn("\f", text) - self.assertIn("\n 1 + 1 = 2\n ^", text) + self.assertIn("\n 1 + 1 = 2\n ^\n", text) def test_syntaxerror_multi_line_fstring(self): script = 'foo = f"""{}\nfoo"""\n' diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index ecc46af..07b46af 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -275,7 +275,6 @@ class CodeopTests(unittest.TestCase): ai("a = 'a\\\n") ai("a = 1","eval") - ai("a = (","eval") ai("]","eval") ai("())","eval") ai("[}","eval") diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 1e6f525..9dc3a81 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -260,7 +260,7 @@ class ExceptionTests(unittest.TestCase): check('[*x for x in xs]', 1, 2) check('foo(x for x in range(10), 100)', 1, 5) check('for 1 in []: pass', 1, 5) - check('(yield i) = 2', 1, 2) + check('(yield i) = 2', 1, 11) check('def f(*):\n pass', 1, 8) @cpython_only diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 296cb05..caae1b7 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -990,7 +990,7 @@ x = ( ]) def test_assignment(self): - self.assertAllRaise(SyntaxError, 'invalid syntax', + self.assertAllRaise(SyntaxError, r'invalid syntax', ["f'' = 3", "f'{0}' = x", "f'{x}' = x", @@ -1276,11 +1276,11 @@ x = ( f'{1:_,}' def test_syntax_error_for_starred_expressions(self): - error_msg = re.escape("can't use starred expression here") + error_msg = re.escape("cannot use starred expression here") with self.assertRaisesRegex(SyntaxError, error_msg): compile("f'{*a}'", "?", "exec") - error_msg = re.escape("can't use double starred expression here") + error_msg = re.escape("cannot use double starred expression here") with self.assertRaisesRegex(SyntaxError, error_msg): compile("f'{**a}'", "?", "exec") diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index a634ccd..ebf8bb7 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -2013,7 +2013,7 @@ SyntaxError: 'yield' outside function >>> def f(): (yield bar) = y Traceback (most recent call last): ... -SyntaxError: cannot assign to yield expression +SyntaxError: cannot assign to yield expression here. Maybe you meant '==' instead of '='? >>> def f(): (yield bar) += y Traceback (most recent call last): diff --git a/Lib/test/test_genexps.py b/Lib/test/test_genexps.py index 5c1a209..70fe2bb 100644 --- a/Lib/test/test_genexps.py +++ b/Lib/test/test_genexps.py @@ -103,7 +103,7 @@ Verify that parenthesis are required when used as a keyword argument value >>> dict(a = i for i in range(10)) Traceback (most recent call last): ... - SyntaxError: invalid syntax + SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='? Verify that parenthesis are required when used as a keyword argument value diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 730c297..78b11c9 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -61,7 +61,7 @@ SyntaxError: cannot assign to __debug__ >>> f() = 1 Traceback (most recent call last): -SyntaxError: cannot assign to function call +SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='? >>> yield = 1 Traceback (most recent call last): @@ -73,7 +73,7 @@ SyntaxError: cannot delete function call >>> a + 1 = 2 Traceback (most recent call last): -SyntaxError: cannot assign to operator +SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='? >>> (x for x in x) = 1 Traceback (most recent call last): @@ -81,19 +81,19 @@ SyntaxError: cannot assign to generator expression >>> 1 = 1 Traceback (most recent call last): -SyntaxError: cannot assign to literal +SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='? >>> "abc" = 1 Traceback (most recent call last): -SyntaxError: cannot assign to literal +SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='? >>> b"" = 1 Traceback (most recent call last): -SyntaxError: cannot assign to literal +SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='? >>> ... = 1 Traceback (most recent call last): -SyntaxError: cannot assign to Ellipsis +SyntaxError: cannot assign to Ellipsis here. Maybe you meant '==' instead of '='? >>> `1` = 1 Traceback (most recent call last): @@ -126,15 +126,15 @@ SyntaxError: cannot assign to __debug__ >>> [a, b, c + 1] = [1, 2, 3] Traceback (most recent call last): -SyntaxError: cannot assign to operator +SyntaxError: cannot assign to expression >>> [a, b[1], c + 1] = [1, 2, 3] Traceback (most recent call last): -SyntaxError: cannot assign to operator +SyntaxError: cannot assign to expression >>> [a, b.c.d, c + 1] = [1, 2, 3] Traceback (most recent call last): -SyntaxError: cannot assign to operator +SyntaxError: cannot assign to expression >>> a if 1 else b = 1 Traceback (most recent call last): @@ -181,7 +181,7 @@ SyntaxError: cannot assign to function call >>> for (*a, b, c+1) in b: pass Traceback (most recent call last): -SyntaxError: cannot assign to operator +SyntaxError: cannot assign to expression >>> for (x, *(y, z.d())) in b: pass Traceback (most recent call last): @@ -193,7 +193,7 @@ SyntaxError: cannot assign to function call >>> for a, b, (c + 1, d()): pass Traceback (most recent call last): -SyntaxError: cannot assign to operator +SyntaxError: cannot assign to expression >>> for i < (): pass Traceback (most recent call last): @@ -217,7 +217,7 @@ SyntaxError: cannot assign to function call >>> with a as (*b, c, d+1): pass Traceback (most recent call last): -SyntaxError: cannot assign to operator +SyntaxError: cannot assign to expression >>> with a as (x, *(y, z.d())): pass Traceback (most recent call last): @@ -465,7 +465,7 @@ keyword slot of a call site. Test a few different options. # SyntaxError: expression cannot contain assignment, perhaps you meant "=="? # >>> f(True=2) # Traceback (most recent call last): -# SyntaxError: cannot assign to True +# SyntaxError: cannot assign to True here. Maybe you meant '==' instead of '='? >>> f(__debug__=1) Traceback (most recent call last): SyntaxError: cannot assign to __debug__ @@ -684,7 +684,7 @@ leading to spurious errors. ... pass Traceback (most recent call last): ... - SyntaxError: cannot assign to function call + SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='? >>> if 1: ... pass @@ -692,7 +692,7 @@ leading to spurious errors. ... x() = 1 Traceback (most recent call last): ... - SyntaxError: cannot assign to function call + SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='? >>> if 1: ... x() = 1 @@ -702,7 +702,7 @@ leading to spurious errors. ... pass Traceback (most recent call last): ... - SyntaxError: cannot assign to function call + SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='? >>> if 1: ... pass @@ -712,7 +712,7 @@ leading to spurious errors. ... pass Traceback (most recent call last): ... - SyntaxError: cannot assign to function call + SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='? >>> if 1: ... pass @@ -722,7 +722,7 @@ leading to spurious errors. ... x() = 1 Traceback (most recent call last): ... - SyntaxError: cannot assign to function call + SyntaxError: cannot assign to function call here. Maybe you meant '==' instead of '='? Missing ':' before suites: @@ -843,6 +843,26 @@ leading to spurious errors. Traceback (most recent call last): SyntaxError: expected ':' + >>> if x = 3: + ... pass + Traceback (most recent call last): + SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='? + + >>> while x = 3: + ... pass + Traceback (most recent call last): + SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='? + + >>> if x.a = 3: + ... pass + Traceback (most recent call last): + SyntaxError: cannot assign to attribute here. Maybe you meant '==' instead of '='? + + >>> while x.a = 3: + ... pass + Traceback (most recent call last): + SyntaxError: cannot assign to attribute here. Maybe you meant '==' instead of '='? + Make sure that the old "raise X, Y[, Z]" form is gone: >>> raise X, Y Traceback (most recent call last): @@ -894,19 +914,19 @@ SyntaxError: keyword argument repeated: a >>> {1, 2, 3} = 42 Traceback (most recent call last): -SyntaxError: cannot assign to set display +SyntaxError: cannot assign to set display here. Maybe you meant '==' instead of '='? >>> {1: 2, 3: 4} = 42 Traceback (most recent call last): -SyntaxError: cannot assign to dict display +SyntaxError: cannot assign to dict literal here. Maybe you meant '==' instead of '='? >>> f'{x}' = 42 Traceback (most recent call last): -SyntaxError: cannot assign to f-string expression +SyntaxError: cannot assign to f-string expression here. Maybe you meant '==' instead of '='? >>> f'{x}-{y}' = 42 Traceback (most recent call last): -SyntaxError: cannot assign to f-string expression +SyntaxError: cannot assign to f-string expression here. Maybe you meant '==' instead of '='? >>> from t import x, Traceback (most recent call last): @@ -988,7 +1008,7 @@ class SyntaxTestCase(unittest.TestCase): def test_expression_with_assignment(self): self._check_error( "print(end1 + end2 = ' ')", - 'expression cannot contain assignment, perhaps you meant "=="?', + "cannot assign to expression here. Maybe you meant '==' instead of '='?", offset=19 ) @@ -1000,31 +1020,31 @@ class SyntaxTestCase(unittest.TestCase): def test_assign_del(self): self._check_error("del (,)", "invalid syntax") - self._check_error("del 1", "delete literal") - self._check_error("del (1, 2)", "delete literal") - self._check_error("del None", "delete None") - self._check_error("del *x", "delete starred") - self._check_error("del (*x)", "use starred expression") - self._check_error("del (*x,)", "delete starred") - self._check_error("del [*x,]", "delete starred") - self._check_error("del f()", "delete function call") - self._check_error("del f(a, b)", "delete function call") - self._check_error("del o.f()", "delete function call") - self._check_error("del a[0]()", "delete function call") - self._check_error("del x, f()", "delete function call") - self._check_error("del f(), x", "delete function call") - self._check_error("del [a, b, ((c), (d,), e.f())]", "delete function call") - self._check_error("del (a if True else b)", "delete conditional") - self._check_error("del +a", "delete operator") - self._check_error("del a, +b", "delete operator") - self._check_error("del a + b", "delete operator") - self._check_error("del (a + b, c)", "delete operator") - self._check_error("del (c[0], a + b)", "delete operator") - self._check_error("del a.b.c + 2", "delete operator") - self._check_error("del a.b.c[0] + 2", "delete operator") - self._check_error("del (a, b, (c, d.e.f + 2))", "delete operator") - self._check_error("del [a, b, (c, d.e.f[0] + 2)]", "delete operator") - self._check_error("del (a := 5)", "delete named expression") + self._check_error("del 1", "cannot delete literal") + self._check_error("del (1, 2)", "cannot delete literal") + self._check_error("del None", "cannot delete None") + self._check_error("del *x", "cannot delete starred") + self._check_error("del (*x)", "cannot use starred expression") + self._check_error("del (*x,)", "cannot delete starred") + self._check_error("del [*x,]", "cannot delete starred") + self._check_error("del f()", "cannot delete function call") + self._check_error("del f(a, b)", "cannot delete function call") + self._check_error("del o.f()", "cannot delete function call") + self._check_error("del a[0]()", "cannot delete function call") + self._check_error("del x, f()", "cannot delete function call") + self._check_error("del f(), x", "cannot delete function call") + self._check_error("del [a, b, ((c), (d,), e.f())]", "cannot delete function call") + self._check_error("del (a if True else b)", "cannot delete conditional") + self._check_error("del +a", "cannot delete expression") + self._check_error("del a, +b", "cannot delete expression") + self._check_error("del a + b", "cannot delete expression") + self._check_error("del (a + b, c)", "cannot delete expression") + self._check_error("del (c[0], a + b)", "cannot delete expression") + self._check_error("del a.b.c + 2", "cannot delete expression") + self._check_error("del a.b.c[0] + 2", "cannot delete expression") + self._check_error("del (a, b, (c, d.e.f + 2))", "cannot delete expression") + self._check_error("del [a, b, (c, d.e.f[0] + 2)]", "cannot delete expression") + self._check_error("del (a := 5)", "cannot delete named expression") # We don't have a special message for this, but make sure we don't # report "cannot delete name" self._check_error("del a += b", "invalid syntax") diff --git a/Lib/test/test_unpack_ex.py b/Lib/test/test_unpack_ex.py index 049e48b..bd79421 100644 --- a/Lib/test/test_unpack_ex.py +++ b/Lib/test/test_unpack_ex.py @@ -349,27 +349,27 @@ Now some general starred expressions (all fail). >>> (*x),y = 1, 2 # doctest:+ELLIPSIS Traceback (most recent call last): ... - SyntaxError: can't use starred expression here + SyntaxError: cannot use starred expression here >>> (((*x))),y = 1, 2 # doctest:+ELLIPSIS Traceback (most recent call last): ... - SyntaxError: can't use starred expression here + SyntaxError: cannot use starred expression here >>> z,(*x),y = 1, 2, 4 # doctest:+ELLIPSIS Traceback (most recent call last): ... - SyntaxError: can't use starred expression here + SyntaxError: cannot use starred expression here >>> z,(*x) = 1, 2 # doctest:+ELLIPSIS Traceback (most recent call last): ... - SyntaxError: can't use starred expression here + SyntaxError: cannot use starred expression here >>> ((*x),y) = 1, 2 # doctest:+ELLIPSIS Traceback (most recent call last): ... - SyntaxError: can't use starred expression here + SyntaxError: cannot use starred expression here Some size constraints (all fail.) |