Raise specialised syntax error for invalid lambda parameters (GH-20776)

(cherry picked from commit c6483c9896)

Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
This commit is contained in:
Miss Islington (bot) 2020-06-10 06:24:41 -07:00 committed by GitHub
parent 73b728a779
commit d55ed7b107
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 902 additions and 596 deletions

View File

@ -329,7 +329,11 @@ expression[expr_ty] (memo):
| lambdef
lambdef[expr_ty]:
| 'lambda' a=[lambda_parameters] ':' b=expression { _Py_Lambda((a) ? a : CHECK(_PyPegen_empty_arguments(p)), b, EXTRA) }
| 'lambda' a=[lambda_params] ':' b=expression { _Py_Lambda((a) ? a : CHECK(_PyPegen_empty_arguments(p)), b, EXTRA) }
lambda_params[arguments_ty]:
| invalid_lambda_parameters
| lambda_parameters
# lambda_parameters etc. duplicates parameters but without annotations
# or type comments, and if there's no comma after a parameter, we expect
@ -669,6 +673,9 @@ invalid_dict_comprehension:
invalid_parameters:
| param_no_default* (slash_with_default | param_with_default+) param_no_default {
RAISE_SYNTAX_ERROR("non-default argument follows default argument") }
invalid_lambda_parameters:
| lambda_param_no_default* (lambda_slash_with_default | lambda_param_with_default+) lambda_param_no_default {
RAISE_SYNTAX_ERROR("non-default argument follows default argument") }
invalid_star_etc:
| '*' (')' | ',' (')' | '**')) { RAISE_SYNTAX_ERROR("named arguments must follow bare *") }
| '*' ',' TYPE_COMMENT { RAISE_SYNTAX_ERROR("bare * has associated type comment") }

View File

@ -4,7 +4,7 @@ import dis
import pickle
import unittest
from test.support import check_syntax_error, use_old_parser
from test.support import check_syntax_error
def global_pos_only_f(a, b, /):
@ -23,12 +23,10 @@ class PositionalOnlyTestCase(unittest.TestCase):
compile(codestr + "\n", "<test>", "single")
def test_invalid_syntax_errors(self):
if use_old_parser():
check_syntax_error(self, "def f(a, b = 5, /, c): pass", "non-default argument follows default argument")
check_syntax_error(self, "def f(a = 5, b, /, c): pass", "non-default argument follows default argument")
check_syntax_error(self, "def f(a = 5, b=1, /, c, *, d=2): pass", "non-default argument follows default argument")
check_syntax_error(self, "def f(a = 5, b, /): pass", "non-default argument follows default argument")
check_syntax_error(self, "def f(a, b = 5, /, c): pass", "non-default argument follows default argument")
check_syntax_error(self, "def f(a = 5, b, /, c): pass", "non-default argument follows default argument")
check_syntax_error(self, "def f(a = 5, b=1, /, c, *, d=2): pass", "non-default argument follows default argument")
check_syntax_error(self, "def f(a = 5, b, /): pass", "non-default argument follows default argument")
check_syntax_error(self, "def f(*args, /): pass")
check_syntax_error(self, "def f(*args, a, /): pass")
check_syntax_error(self, "def f(**kwargs, /): pass")
@ -46,12 +44,10 @@ class PositionalOnlyTestCase(unittest.TestCase):
check_syntax_error(self, "def f(a, *, c, /, d, e): pass")
def test_invalid_syntax_errors_async(self):
if use_old_parser():
check_syntax_error(self, "async def f(a, b = 5, /, c): pass", "non-default argument follows default argument")
check_syntax_error(self, "async def f(a = 5, b, /, c): pass", "non-default argument follows default argument")
check_syntax_error(self, "async def f(a = 5, b=1, /, c, d=2): pass", "non-default argument follows default argument")
check_syntax_error(self, "async def f(a = 5, b, /): pass", "non-default argument follows default argument")
check_syntax_error(self, "async def f(a, b = 5, /, c): pass", "non-default argument follows default argument")
check_syntax_error(self, "async def f(a = 5, b, /, c): pass", "non-default argument follows default argument")
check_syntax_error(self, "async def f(a = 5, b=1, /, c, d=2): pass", "non-default argument follows default argument")
check_syntax_error(self, "async def f(a = 5, b, /): pass", "non-default argument follows default argument")
check_syntax_error(self, "async def f(*args, /): pass")
check_syntax_error(self, "async def f(*args, a, /): pass")
check_syntax_error(self, "async def f(**kwargs, /): pass")
@ -235,11 +231,9 @@ class PositionalOnlyTestCase(unittest.TestCase):
self.assertEqual(x(1, 2), 3)
def test_invalid_syntax_lambda(self):
if use_old_parser():
check_syntax_error(self, "lambda a, b = 5, /, c: None", "non-default argument follows default argument")
check_syntax_error(self, "lambda a = 5, b, /, c: None", "non-default argument follows default argument")
check_syntax_error(self, "lambda a = 5, b, /: None", "non-default argument follows default argument")
check_syntax_error(self, "lambda a, b = 5, /, c: None", "non-default argument follows default argument")
check_syntax_error(self, "lambda a = 5, b, /, c: None", "non-default argument follows default argument")
check_syntax_error(self, "lambda a = 5, b, /: None", "non-default argument follows default argument")
check_syntax_error(self, "lambda *args, /: None")
check_syntax_error(self, "lambda *args, a, /: None")
check_syntax_error(self, "lambda **kwargs, /: None")

File diff suppressed because it is too large Load Diff