Browse Source

bpo-44456: Improve the syntax error when mixing keyword and positional patterns (GH-26793)

pull/26905/head
Pablo Galindo 4 years ago
committed by GitHub
parent
commit
0acc258fe6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      Grammar/python.gram
  2. 24
      Lib/test/test_syntax.py
  3. 2
      Misc/NEWS.d/next/Core and Builtins/2021-06-18-22-08-25.bpo-44456.L0Rhko.rst
  4. 1092
      Parser/parser.c
  5. 7
      Parser/pegen.c
  6. 3
      Parser/pegen.h

8
Grammar/python.gram

@ -380,6 +380,7 @@ class_pattern[pattern_ty]:
CHECK(asdl_expr_seq*, _PyPegen_get_pattern_keys(p, keywords)))),
CHECK(asdl_pattern_seq*, _PyPegen_get_patterns(p, keywords)),
EXTRA) }
| invalid_class_pattern
positional_patterns[asdl_pattern_seq*]:
| args[asdl_pattern_seq*]=','.pattern+ { args }
keyword_patterns[asdl_seq*]:
@ -978,6 +979,13 @@ invalid_case_block:
invalid_as_pattern:
| or_pattern 'as' a="_" { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use '_' as a target") }
| or_pattern 'as' !NAME a=expression { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "invalid pattern target") }
invalid_class_pattern:
| name_or_attr '(' a=invalid_class_argument_pattern { RAISE_SYNTAX_ERROR_KNOWN_RANGE(
PyPegen_first_item(a, pattern_ty),
PyPegen_last_item(a, pattern_ty),
"positional patterns follow keyword patterns") }
invalid_class_argument_pattern[asdl_pattern_seq*]:
| [positional_patterns ','] keyword_patterns ',' a=positional_patterns { a }
invalid_if_stmt:
| 'if' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
| a='if' a=named_expression ':' NEWLINE !INDENT {

24
Lib/test/test_syntax.py

@ -1240,6 +1240,30 @@ Corner-cases that used to crash:
... ...
Traceback (most recent call last):
SyntaxError: invalid pattern target
>>> match ...:
... case Foo(z=1, y=2, x):
... ...
Traceback (most recent call last):
SyntaxError: positional patterns follow keyword patterns
>>> match ...:
... case Foo(a, z=1, y=2, x):
... ...
Traceback (most recent call last):
SyntaxError: positional patterns follow keyword patterns
>>> match ...:
... case Foo(z=1, x, y=2):
... ...
Traceback (most recent call last):
SyntaxError: positional patterns follow keyword patterns
>>> match ...:
... case C(a=b, c, d=e, f, g=h, i, j=k, ...):
... ...
Traceback (most recent call last):
SyntaxError: positional patterns follow keyword patterns
"""
import re

2
Misc/NEWS.d/next/Core and Builtins/2021-06-18-22-08-25.bpo-44456.L0Rhko.rst

@ -0,0 +1,2 @@
Improve the syntax error when mixing positional and keyword patterns. Patch
by Pablo Galindo.

1092
Parser/parser.c
File diff suppressed because it is too large
View File

7
Parser/pegen.c

@ -1557,6 +1557,13 @@ _PyPegen_seq_last_item(asdl_seq *seq)
return asdl_seq_GET_UNTYPED(seq, len - 1);
}
void *
_PyPegen_seq_first_item(asdl_seq *seq)
{
return asdl_seq_GET_UNTYPED(seq, 0);
}
/* Creates a new name of the form <first_name>.<second_name> */
expr_ty
_PyPegen_join_names_with_dot(Parser *p, expr_ty first_name, expr_ty second_name)

3
Parser/pegen.h

@ -149,6 +149,9 @@ void *_PyPegen_dummy_name(Parser *p, ...);
void * _PyPegen_seq_last_item(asdl_seq *seq);
#define PyPegen_last_item(seq, type) ((type)_PyPegen_seq_last_item((asdl_seq*)seq))
void * _PyPegen_seq_first_item(asdl_seq *seq);
#define PyPegen_first_item(seq, type) ((type)_PyPegen_seq_first_item((asdl_seq*)seq))
#define CURRENT_POS (-5)
Py_LOCAL_INLINE(void *)

Loading…
Cancel
Save