Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-45727: Make the syntax error for missing comma more consistent #29427

Merged
merged 1 commit into from
Nov 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Grammar/python.gram
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ expressions[expr_ty]:

expression[expr_ty] (memo):
| invalid_expression
| invalid_legacy_expression
| a=disjunction 'if' b=disjunction 'else' c=expression { _PyAST_IfExp(b, a, c, EXTRA) }
| disjunction
| lambdef
Expand Down Expand Up @@ -1078,11 +1079,10 @@ invalid_legacy_expression:
"Missing parentheses in call to '%U'. Did you mean %U(...)?", a->v.Name.id, a->v.Name.id) : NULL}

invalid_expression:
| invalid_legacy_expression
# !(NAME STRING) is not matched so we don't show this error with some invalid string prefixes like: kf"dsfsdf"
# Soft keywords need to also be ignored because they can be parsed as NAME NAME
| !(NAME STRING | SOFT_KEYWORD) a=disjunction b=expression_without_invalid {
RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Perhaps you forgot a comma?") }
_PyPegen_check_legacy_stmt(p, a) ? NULL : RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Perhaps you forgot a comma?") }
| a=disjunction 'if' b=disjunction !('else'|':') { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected 'else' after 'if' expression") }

invalid_named_expression:
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ def testSyntaxErrorOffset(self):
check('[file for\n str(file) in []]', 2, 2)
check("ages = {'Alice'=22, 'Bob'=23}", 1, 16)
check('match ...:\n case {**rest, "key": value}:\n ...', 2, 19)
check("a b c d e f", 1, 1)

# Errors thrown by compile.c
check('class foo:return 1', 1, 11)
Expand Down
42 changes: 21 additions & 21 deletions Parser/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -9717,6 +9717,7 @@ expressions_rule(Parser *p)

// expression:
// | invalid_expression
// | invalid_legacy_expression
// | disjunction 'if' disjunction 'else' expression
// | disjunction
// | lambdef
Expand Down Expand Up @@ -9762,6 +9763,25 @@ expression_rule(Parser *p)
D(fprintf(stderr, "%*c%s expression[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_expression"));
}
if (p->call_invalid_rules) { // invalid_legacy_expression
if (p->error_indicator) {
D(p->level--);
return NULL;
}
D(fprintf(stderr, "%*c> expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_legacy_expression"));
void *invalid_legacy_expression_var;
if (
(invalid_legacy_expression_var = invalid_legacy_expression_rule(p)) // invalid_legacy_expression
)
{
D(fprintf(stderr, "%*c+ expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_legacy_expression"));
_res = invalid_legacy_expression_var;
goto done;
}
p->mark = _mark;
D(fprintf(stderr, "%*c%s expression[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_legacy_expression"));
}
{ // disjunction 'if' disjunction 'else' expression
if (p->error_indicator) {
D(p->level--);
Expand Down Expand Up @@ -18207,7 +18227,6 @@ invalid_legacy_expression_rule(Parser *p)
}

// invalid_expression:
// | invalid_legacy_expression
// | !(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid
// | disjunction 'if' disjunction !('else' | ':')
static void *
Expand All @@ -18220,25 +18239,6 @@ invalid_expression_rule(Parser *p)
}
void * _res = NULL;
int _mark = p->mark;
if (p->call_invalid_rules) { // invalid_legacy_expression
if (p->error_indicator) {
D(p->level--);
return NULL;
}
D(fprintf(stderr, "%*c> invalid_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_legacy_expression"));
void *invalid_legacy_expression_var;
if (
(invalid_legacy_expression_var = invalid_legacy_expression_rule(p)) // invalid_legacy_expression
)
{
D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_legacy_expression"));
_res = invalid_legacy_expression_var;
goto done;
}
p->mark = _mark;
D(fprintf(stderr, "%*c%s invalid_expression[%d-%d]: %s failed!\n", p->level, ' ',
p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_legacy_expression"));
}
{ // !(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid
if (p->error_indicator) {
D(p->level--);
Expand All @@ -18256,7 +18256,7 @@ invalid_expression_rule(Parser *p)
)
{
D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid"));
_res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Perhaps you forgot a comma?" );
_res = _PyPegen_check_legacy_stmt ( p , a ) ? NULL : RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "invalid syntax. Perhaps you forgot a comma?" );
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
D(p->level--);
Expand Down
4 changes: 3 additions & 1 deletion Parser/pegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ _PyPegen_check_barry_as_flufl(Parser *p, Token* t) {

int
_PyPegen_check_legacy_stmt(Parser *p, expr_ty name) {
assert(name->kind == Name_kind);
if (name->kind != Name_kind) {
return 0;
}
const char* candidates[2] = {"print", "exec"};
for (int i=0; i<2; i++) {
if (PyUnicode_CompareWithASCIIString(name->v.Name.id, candidates[i]) == 0) {
Expand Down