Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 17c8060

Browse files
committed
Better error messages for illegal bounds/constraints
1 parent f580583 commit 17c8060

3 files changed

Lines changed: 106 additions & 5 deletions

File tree

Grammar/python.gram

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,17 @@ type_param_seq[asdl_typeparam_seq*]: a[asdl_typeparam_seq*]=','.type_param+ [','
646646

647647
type_param[typeparam_ty] (memo):
648648
| a=NAME b=[type_param_bound] { _PyAST_TypeVar(a->v.Name.id, b, EXTRA) }
649+
| '*' a=NAME colon=":" e=expression {
650+
RAISE_SYNTAX_ERROR_STARTING_FROM(colon, e->kind == Tuple_kind
651+
? "cannot use constraints with TypeVarTuple"
652+
: "cannot use bound with TypeVarTuple")
653+
}
649654
| '*' a=NAME { _PyAST_TypeVarTuple(a->v.Name.id, EXTRA) }
655+
| '**' a=NAME colon=":" e=expression {
656+
RAISE_SYNTAX_ERROR_STARTING_FROM(colon, e->kind == Tuple_kind
657+
? "cannot use constraints with ParamSpec"
658+
: "cannot use bound with ParamSpec")
659+
}
650660
| '**' a=NAME { _PyAST_ParamSpec(a->v.Name.id, EXTRA) }
651661

652662
type_param_bound[expr_ty]: ":" e=expression { e }

Lib/test/test_type_params.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,18 @@ async def coroutine[B]():
452452

453453
class TypeParamsTypeVarTupleTest(unittest.TestCase):
454454
def test_typevartuple_01(self):
455-
code = """def func1[*A: str](): return (A, B, C)"""
456-
check_syntax_error(self, code, r"expected '\('")
455+
code = """def func1[*A: str](): pass"""
456+
check_syntax_error(self, code, "cannot use bound with TypeVarTuple")
457+
code = """def func1[*A: (int, str)](): pass"""
458+
check_syntax_error(self, code, "cannot use constraints with TypeVarTuple")
459+
code = """class X[*A: str]: pass"""
460+
check_syntax_error(self, code, "cannot use bound with TypeVarTuple")
461+
code = """class X[*A: (int, str)]: pass"""
462+
check_syntax_error(self, code, "cannot use constraints with TypeVarTuple")
463+
code = """type X[*A: str] = int"""
464+
check_syntax_error(self, code, "cannot use bound with TypeVarTuple")
465+
code = """type X[*A: (int, str)] = int"""
466+
check_syntax_error(self, code, "cannot use constraints with TypeVarTuple")
457467

458468
def test_typevartuple_02(self):
459469
def func1[*A]():
@@ -465,8 +475,18 @@ def func1[*A]():
465475

466476
class TypeParamsTypeVarParamSpec(unittest.TestCase):
467477
def test_paramspec_01(self):
468-
code = """def func1[**A: str](): return (A, B, C)"""
469-
check_syntax_error(self, code, r"expected '\('")
478+
code = """def func1[**A: str](): pass"""
479+
check_syntax_error(self, code, "cannot use bound with ParamSpec")
480+
code = """def func1[**A: (int, str)](): pass"""
481+
check_syntax_error(self, code, "cannot use constraints with ParamSpec")
482+
code = """class X[**A: str]: pass"""
483+
check_syntax_error(self, code, "cannot use bound with ParamSpec")
484+
code = """class X[**A: (int, str)]: pass"""
485+
check_syntax_error(self, code, "cannot use constraints with ParamSpec")
486+
code = """type X[**A: str] = int"""
487+
check_syntax_error(self, code, "cannot use bound with ParamSpec")
488+
code = """type X[**A: (int, str)] = int"""
489+
check_syntax_error(self, code, "cannot use constraints with ParamSpec")
470490

471491
def test_paramspec_02(self):
472492
def func1[**A]():

Parser/parser.c

Lines changed: 72 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)