mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-138857: Improve error message for case outside of match (#138858)
* gh-138857: Improve error message for `case` outside of `match` --------- Co-authored-by: Bartosz Sławecki <bartosz@ilikepython.com>
This commit is contained in:
parent
161b3064ef
commit
92c0c45563
4 changed files with 80 additions and 0 deletions
|
|
@ -1477,6 +1477,10 @@ invalid_match_stmt:
|
||||||
| "match" subject_expr NEWLINE { CHECK_VERSION(void*, 10, "Pattern matching is", RAISE_SYNTAX_ERROR("expected ':'") ) }
|
| "match" subject_expr NEWLINE { CHECK_VERSION(void*, 10, "Pattern matching is", RAISE_SYNTAX_ERROR("expected ':'") ) }
|
||||||
| a="match" subject=subject_expr ':' NEWLINE !INDENT {
|
| a="match" subject=subject_expr ':' NEWLINE !INDENT {
|
||||||
RAISE_INDENTATION_ERROR("expected an indented block after 'match' statement on line %d", a->lineno) }
|
RAISE_INDENTATION_ERROR("expected an indented block after 'match' statement on line %d", a->lineno) }
|
||||||
|
| a="case" patterns guard? b=':' block {
|
||||||
|
RAISE_SYNTAX_ERROR_KNOWN_RANGE(
|
||||||
|
a, b,
|
||||||
|
"case statement must be inside match statement") }
|
||||||
invalid_case_block:
|
invalid_case_block:
|
||||||
| "case" patterns guard? NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
|
| "case" patterns guard? NEWLINE { RAISE_SYNTAX_ERROR("expected ':'") }
|
||||||
| a="case" patterns guard? ':' NEWLINE !INDENT {
|
| a="case" patterns guard? ':' NEWLINE !INDENT {
|
||||||
|
|
|
||||||
|
|
@ -376,6 +376,42 @@
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
SyntaxError: invalid syntax
|
SyntaxError: invalid syntax
|
||||||
|
|
||||||
|
# Check incorrect "case" placement with specialized error messages
|
||||||
|
|
||||||
|
>>> case "pattern": ...
|
||||||
|
Traceback (most recent call last):
|
||||||
|
SyntaxError: case statement must be inside match statement
|
||||||
|
|
||||||
|
>>> case 1 | 2: ...
|
||||||
|
Traceback (most recent call last):
|
||||||
|
SyntaxError: case statement must be inside match statement
|
||||||
|
|
||||||
|
>>> case klass(attr=1) | {}: ...
|
||||||
|
Traceback (most recent call last):
|
||||||
|
SyntaxError: case statement must be inside match statement
|
||||||
|
|
||||||
|
>>> case [] if x > 1: ...
|
||||||
|
Traceback (most recent call last):
|
||||||
|
SyntaxError: case statement must be inside match statement
|
||||||
|
|
||||||
|
>>> case match: ...
|
||||||
|
Traceback (most recent call last):
|
||||||
|
SyntaxError: case statement must be inside match statement
|
||||||
|
|
||||||
|
>>> case case: ...
|
||||||
|
Traceback (most recent call last):
|
||||||
|
SyntaxError: case statement must be inside match statement
|
||||||
|
|
||||||
|
>>> if some:
|
||||||
|
... case 1: ...
|
||||||
|
Traceback (most recent call last):
|
||||||
|
SyntaxError: case statement must be inside match statement
|
||||||
|
|
||||||
|
>>> case some:
|
||||||
|
... case 1: ...
|
||||||
|
Traceback (most recent call last):
|
||||||
|
SyntaxError: case statement must be inside match statement
|
||||||
|
|
||||||
# But prefixes of soft keywords should
|
# But prefixes of soft keywords should
|
||||||
# still raise specialized errors
|
# still raise specialized errors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
Improve :exc:`SyntaxError` message for ``case`` keyword placed outside
|
||||||
|
:keyword:`match` body.
|
||||||
38
Parser/parser.c
generated
38
Parser/parser.c
generated
|
|
@ -25154,6 +25154,7 @@ invalid_except_star_stmt_indent_rule(Parser *p)
|
||||||
// invalid_match_stmt:
|
// invalid_match_stmt:
|
||||||
// | "match" subject_expr NEWLINE
|
// | "match" subject_expr NEWLINE
|
||||||
// | "match" subject_expr ':' NEWLINE !INDENT
|
// | "match" subject_expr ':' NEWLINE !INDENT
|
||||||
|
// | "case" patterns guard? ':' block
|
||||||
static void *
|
static void *
|
||||||
invalid_match_stmt_rule(Parser *p)
|
invalid_match_stmt_rule(Parser *p)
|
||||||
{
|
{
|
||||||
|
|
@ -25231,6 +25232,43 @@ invalid_match_stmt_rule(Parser *p)
|
||||||
D(fprintf(stderr, "%*c%s invalid_match_stmt[%d-%d]: %s failed!\n", p->level, ' ',
|
D(fprintf(stderr, "%*c%s invalid_match_stmt[%d-%d]: %s failed!\n", p->level, ' ',
|
||||||
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"match\" subject_expr ':' NEWLINE !INDENT"));
|
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"match\" subject_expr ':' NEWLINE !INDENT"));
|
||||||
}
|
}
|
||||||
|
{ // "case" patterns guard? ':' block
|
||||||
|
if (p->error_indicator) {
|
||||||
|
p->level--;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
D(fprintf(stderr, "%*c> invalid_match_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? ':' block"));
|
||||||
|
void *_opt_var;
|
||||||
|
UNUSED(_opt_var); // Silence compiler warnings
|
||||||
|
expr_ty a;
|
||||||
|
Token * b;
|
||||||
|
asdl_stmt_seq* block_var;
|
||||||
|
pattern_ty patterns_var;
|
||||||
|
if (
|
||||||
|
(a = _PyPegen_expect_soft_keyword(p, "case")) // soft_keyword='"case"'
|
||||||
|
&&
|
||||||
|
(patterns_var = patterns_rule(p)) // patterns
|
||||||
|
&&
|
||||||
|
(_opt_var = guard_rule(p), !p->error_indicator) // guard?
|
||||||
|
&&
|
||||||
|
(b = _PyPegen_expect_token(p, 11)) // token=':'
|
||||||
|
&&
|
||||||
|
(block_var = block_rule(p)) // block
|
||||||
|
)
|
||||||
|
{
|
||||||
|
D(fprintf(stderr, "%*c+ invalid_match_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"case\" patterns guard? ':' block"));
|
||||||
|
_res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "case statement must be inside match statement" );
|
||||||
|
if (_res == NULL && PyErr_Occurred()) {
|
||||||
|
p->error_indicator = 1;
|
||||||
|
p->level--;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
p->mark = _mark;
|
||||||
|
D(fprintf(stderr, "%*c%s invalid_match_stmt[%d-%d]: %s failed!\n", p->level, ' ',
|
||||||
|
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"case\" patterns guard? ':' block"));
|
||||||
|
}
|
||||||
_res = NULL;
|
_res = NULL;
|
||||||
done:
|
done:
|
||||||
p->level--;
|
p->level--;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue