Skip to content

Commit 75b863a

Browse files
authored
bpo-40334: Reproduce error message for type comments on bare '*' in the new parser (GH-20151)
1 parent d71a649 commit 75b863a

File tree

5 files changed

+55
-23
lines changed

5 files changed

+55
-23
lines changed

Grammar/python.gram

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,7 @@ invalid_parameters:
661661
RAISE_SYNTAX_ERROR("non-default argument follows default argument") }
662662
invalid_star_etc:
663663
| '*' (')' | ',' (')' | '**')) { RAISE_SYNTAX_ERROR("named arguments must follow bare *") }
664+
| '*' ',' TYPE_COMMENT { RAISE_SYNTAX_ERROR("bare * has associated type comment") }
664665
invalid_lambda_star_etc:
665666
| '*' (':' | ',' (':' | '**')) { RAISE_SYNTAX_ERROR("named arguments must follow bare *") }
666667
invalid_double_type_comments:

Lib/test/test_syntax.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,16 @@
178178
Traceback (most recent call last):
179179
SyntaxError: invalid syntax
180180
181+
>>> import ast; ast.parse('''
182+
... def f(
183+
... *, # type: int
184+
... a, # type: int
185+
... ):
186+
... pass
187+
... ''', type_comments=True)
188+
Traceback (most recent call last):
189+
SyntaxError: bare * has associated type comment
190+
181191
182192
From ast_for_funcdef():
183193

Parser/pegen/parse.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12041,7 +12041,7 @@ invalid_parameters_rule(Parser *p)
1204112041
return _res;
1204212042
}
1204312043

12044-
// invalid_star_etc: '*' (')' | ',' (')' | '**'))
12044+
// invalid_star_etc: '*' (')' | ',' (')' | '**')) | '*' ',' TYPE_COMMENT
1204512045
static void *
1204612046
invalid_star_etc_rule(Parser *p)
1204712047
{
@@ -12071,6 +12071,27 @@ invalid_star_etc_rule(Parser *p)
1207112071
}
1207212072
p->mark = _mark;
1207312073
}
12074+
{ // '*' ',' TYPE_COMMENT
12075+
Token * _literal;
12076+
Token * _literal_1;
12077+
Token * type_comment_var;
12078+
if (
12079+
(_literal = _PyPegen_expect_token(p, 16)) // token='*'
12080+
&&
12081+
(_literal_1 = _PyPegen_expect_token(p, 12)) // token=','
12082+
&&
12083+
(type_comment_var = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT'
12084+
)
12085+
{
12086+
_res = RAISE_SYNTAX_ERROR ( "bare * has associated type comment" );
12087+
if (_res == NULL && PyErr_Occurred()) {
12088+
p->error_indicator = 1;
12089+
return NULL;
12090+
}
12091+
goto done;
12092+
}
12093+
p->mark = _mark;
12094+
}
1207412095
_res = NULL;
1207512096
done:
1207612097
return _res;

Parser/pegen/pegen.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -431,25 +431,6 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype,
431431
return NULL;
432432
}
433433

434-
void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) {
435-
int kwarg_unpacking = 0;
436-
for (Py_ssize_t i = 0, l = asdl_seq_LEN(e->v.Call.keywords); i < l; i++) {
437-
keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i);
438-
if (!keyword->arg) {
439-
kwarg_unpacking = 1;
440-
}
441-
}
442-
443-
const char *msg = NULL;
444-
if (kwarg_unpacking) {
445-
msg = "positional argument follows keyword argument unpacking";
446-
} else {
447-
msg = "positional argument follows keyword argument";
448-
}
449-
450-
return RAISE_SYNTAX_ERROR(msg);
451-
}
452-
453434
#if 0
454435
static const char *
455436
token_name(int type)
@@ -2099,4 +2080,23 @@ _PyPegen_get_invalid_target(expr_ty e)
20992080
default:
21002081
return e;
21012082
}
2102-
}
2083+
}
2084+
2085+
void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) {
2086+
int kwarg_unpacking = 0;
2087+
for (Py_ssize_t i = 0, l = asdl_seq_LEN(e->v.Call.keywords); i < l; i++) {
2088+
keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i);
2089+
if (!keyword->arg) {
2090+
kwarg_unpacking = 1;
2091+
}
2092+
}
2093+
2094+
const char *msg = NULL;
2095+
if (kwarg_unpacking) {
2096+
msg = "positional argument follows keyword argument unpacking";
2097+
} else {
2098+
msg = "positional argument follows keyword argument";
2099+
}
2100+
2101+
return RAISE_SYNTAX_ERROR(msg);
2102+
}

Parser/pegen/pegen.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,13 +256,13 @@ asdl_seq *_PyPegen_seq_extract_starred_exprs(Parser *, asdl_seq *);
256256
asdl_seq *_PyPegen_seq_delete_starred_exprs(Parser *, asdl_seq *);
257257
expr_ty _PyPegen_concatenate_strings(Parser *p, asdl_seq *);
258258
asdl_seq *_PyPegen_join_sequences(Parser *, asdl_seq *, asdl_seq *);
259-
void *_PyPegen_arguments_parsing_error(Parser *, expr_ty);
260259
int _PyPegen_check_barry_as_flufl(Parser *);
261260
mod_ty _PyPegen_make_module(Parser *, asdl_seq *);
262261

263262
// Error reporting helpers
264-
265263
expr_ty _PyPegen_get_invalid_target(expr_ty e);
264+
void *_PyPegen_arguments_parsing_error(Parser *, expr_ty);
265+
266266

267267
void *_PyPegen_parse(Parser *);
268268

0 commit comments

Comments
 (0)