mirror of
https://github.com/python/cpython.git
synced 2025-09-16 13:47:31 +00:00
bpo-44456: Improve the syntax error when mixing keyword and positional patterns (GH-26793)
(cherry picked from commit 0acc258fe6
)
Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
This commit is contained in:
parent
b3fac2926b
commit
11f1a30cdb
6 changed files with 843 additions and 635 deletions
|
@ -380,6 +380,7 @@ class_pattern[pattern_ty]:
|
||||||
CHECK(asdl_expr_seq*, _PyPegen_get_pattern_keys(p, keywords)))),
|
CHECK(asdl_expr_seq*, _PyPegen_get_pattern_keys(p, keywords)))),
|
||||||
CHECK(asdl_pattern_seq*, _PyPegen_get_patterns(p, keywords)),
|
CHECK(asdl_pattern_seq*, _PyPegen_get_patterns(p, keywords)),
|
||||||
EXTRA) }
|
EXTRA) }
|
||||||
|
| invalid_class_pattern
|
||||||
positional_patterns[asdl_pattern_seq*]:
|
positional_patterns[asdl_pattern_seq*]:
|
||||||
| args[asdl_pattern_seq*]=','.pattern+ { args }
|
| args[asdl_pattern_seq*]=','.pattern+ { args }
|
||||||
keyword_patterns[asdl_seq*]:
|
keyword_patterns[asdl_seq*]:
|
||||||
|
@ -978,6 +979,13 @@ invalid_case_block:
|
||||||
invalid_as_pattern:
|
invalid_as_pattern:
|
||||||
| or_pattern 'as' a="_" { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use '_' as a target") }
|
| 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") }
|
| 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:
|
invalid_if_stmt:
|
||||||
| 'if' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
|
| 'if' named_expression NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
|
||||||
| a='if' a=named_expression ':' NEWLINE !INDENT {
|
| a='if' a=named_expression ':' NEWLINE !INDENT {
|
||||||
|
|
|
@ -1240,6 +1240,30 @@ Corner-cases that used to crash:
|
||||||
... ...
|
... ...
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
SyntaxError: invalid pattern target
|
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
|
import re
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Improve the syntax error when mixing positional and keyword patterns. Patch
|
||||||
|
by Pablo Galindo.
|
1434
Parser/parser.c
1434
Parser/parser.c
File diff suppressed because it is too large
Load diff
|
@ -1557,6 +1557,13 @@ _PyPegen_seq_last_item(asdl_seq *seq)
|
||||||
return asdl_seq_GET_UNTYPED(seq, len - 1);
|
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> */
|
/* Creates a new name of the form <first_name>.<second_name> */
|
||||||
expr_ty
|
expr_ty
|
||||||
_PyPegen_join_names_with_dot(Parser *p, expr_ty first_name, expr_ty second_name)
|
_PyPegen_join_names_with_dot(Parser *p, expr_ty first_name, expr_ty second_name)
|
||||||
|
|
|
@ -149,6 +149,9 @@ void *_PyPegen_dummy_name(Parser *p, ...);
|
||||||
void * _PyPegen_seq_last_item(asdl_seq *seq);
|
void * _PyPegen_seq_last_item(asdl_seq *seq);
|
||||||
#define PyPegen_last_item(seq, type) ((type)_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)
|
#define CURRENT_POS (-5)
|
||||||
|
|
||||||
Py_LOCAL_INLINE(void *)
|
Py_LOCAL_INLINE(void *)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue