bpo-40334: Reproduce error message for type comments on bare '*' in the new parser (GH-20151)
diff --git a/Grammar/python.gram b/Grammar/python.gram
index cca9209..40e7818 100644
--- a/Grammar/python.gram
+++ b/Grammar/python.gram
@@ -661,6 +661,7 @@
RAISE_SYNTAX_ERROR("non-default argument follows default argument") }
invalid_star_etc:
| '*' (')' | ',' (')' | '**')) { RAISE_SYNTAX_ERROR("named arguments must follow bare *") }
+ | '*' ',' TYPE_COMMENT { RAISE_SYNTAX_ERROR("bare * has associated type comment") }
invalid_lambda_star_etc:
| '*' (':' | ',' (':' | '**')) { RAISE_SYNTAX_ERROR("named arguments must follow bare *") }
invalid_double_type_comments:
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index 87ceced..a82b444 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -178,6 +178,16 @@
Traceback (most recent call last):
SyntaxError: invalid syntax
+>>> import ast; ast.parse('''
+... def f(
+... *, # type: int
+... a, # type: int
+... ):
+... pass
+... ''', type_comments=True)
+Traceback (most recent call last):
+SyntaxError: bare * has associated type comment
+
From ast_for_funcdef():
diff --git a/Parser/pegen/parse.c b/Parser/pegen/parse.c
index e9c2032..fe95d27 100644
--- a/Parser/pegen/parse.c
+++ b/Parser/pegen/parse.c
@@ -12041,7 +12041,7 @@
return _res;
}
-// invalid_star_etc: '*' (')' | ',' (')' | '**'))
+// invalid_star_etc: '*' (')' | ',' (')' | '**')) | '*' ',' TYPE_COMMENT
static void *
invalid_star_etc_rule(Parser *p)
{
@@ -12071,6 +12071,27 @@
}
p->mark = _mark;
}
+ { // '*' ',' TYPE_COMMENT
+ Token * _literal;
+ Token * _literal_1;
+ Token * type_comment_var;
+ if (
+ (_literal = _PyPegen_expect_token(p, 16)) // token='*'
+ &&
+ (_literal_1 = _PyPegen_expect_token(p, 12)) // token=','
+ &&
+ (type_comment_var = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT'
+ )
+ {
+ _res = RAISE_SYNTAX_ERROR ( "bare * has associated type comment" );
+ if (_res == NULL && PyErr_Occurred()) {
+ p->error_indicator = 1;
+ return NULL;
+ }
+ goto done;
+ }
+ p->mark = _mark;
+ }
_res = NULL;
done:
return _res;
diff --git a/Parser/pegen/pegen.c b/Parser/pegen/pegen.c
index 7f3e456..ca4ea82 100644
--- a/Parser/pegen/pegen.c
+++ b/Parser/pegen/pegen.c
@@ -431,25 +431,6 @@
return NULL;
}
-void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) {
- int kwarg_unpacking = 0;
- for (Py_ssize_t i = 0, l = asdl_seq_LEN(e->v.Call.keywords); i < l; i++) {
- keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i);
- if (!keyword->arg) {
- kwarg_unpacking = 1;
- }
- }
-
- const char *msg = NULL;
- if (kwarg_unpacking) {
- msg = "positional argument follows keyword argument unpacking";
- } else {
- msg = "positional argument follows keyword argument";
- }
-
- return RAISE_SYNTAX_ERROR(msg);
-}
-
#if 0
static const char *
token_name(int type)
@@ -2099,4 +2080,23 @@
default:
return e;
}
-}
\ No newline at end of file
+}
+
+void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) {
+ int kwarg_unpacking = 0;
+ for (Py_ssize_t i = 0, l = asdl_seq_LEN(e->v.Call.keywords); i < l; i++) {
+ keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i);
+ if (!keyword->arg) {
+ kwarg_unpacking = 1;
+ }
+ }
+
+ const char *msg = NULL;
+ if (kwarg_unpacking) {
+ msg = "positional argument follows keyword argument unpacking";
+ } else {
+ msg = "positional argument follows keyword argument";
+ }
+
+ return RAISE_SYNTAX_ERROR(msg);
+}
diff --git a/Parser/pegen/pegen.h b/Parser/pegen/pegen.h
index b9d4c04..146804a 100644
--- a/Parser/pegen/pegen.h
+++ b/Parser/pegen/pegen.h
@@ -256,13 +256,13 @@
asdl_seq *_PyPegen_seq_delete_starred_exprs(Parser *, asdl_seq *);
expr_ty _PyPegen_concatenate_strings(Parser *p, asdl_seq *);
asdl_seq *_PyPegen_join_sequences(Parser *, asdl_seq *, asdl_seq *);
-void *_PyPegen_arguments_parsing_error(Parser *, expr_ty);
int _PyPegen_check_barry_as_flufl(Parser *);
mod_ty _PyPegen_make_module(Parser *, asdl_seq *);
// Error reporting helpers
-
expr_ty _PyPegen_get_invalid_target(expr_ty e);
+void *_PyPegen_arguments_parsing_error(Parser *, expr_ty);
+
void *_PyPegen_parse(Parser *);