Skip to content

Commit 9423712

Browse files
committed
Allow type variable tuple for *args
1 parent 5018b1a commit 9423712

File tree

3 files changed

+214
-7
lines changed

3 files changed

+214
-7
lines changed

compiler/parser/python.lalrpop

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,7 +1180,7 @@ FuncDef: ast::Stmt = {
11801180
};
11811181

11821182
Parameters: ast::Arguments = {
1183-
"(" <a: (ParameterList<TypedParameter>)?> ")" =>? {
1183+
"(" <a: (ParameterList<TypedParameter, StarTypedParameter>)?> ")" =>? {
11841184
let args = validate_arguments(
11851185
a.unwrap_or_else(|| ast::Arguments {
11861186
posonlyargs: vec![],
@@ -1199,8 +1199,8 @@ Parameters: ast::Arguments = {
11991199

12001200
// Note that this is a macro which is used once for function defs, and
12011201
// once for lambda defs.
1202-
ParameterList<ArgType>: ast::Arguments = {
1203-
<param1:ParameterDefs<ArgType>> <args2:("," ParameterListStarArgs<ArgType>)?> ","? =>? {
1202+
ParameterList<ArgType, StarArgType>: ast::Arguments = {
1203+
<param1:ParameterDefs<ArgType>> <args2:("," ParameterListStarArgs<ArgType, StarArgType>)?> ","? =>? {
12041204
let (posonlyargs, args, defaults) = parse_params(param1)?;
12051205

12061206
// Now gather rest of parameters:
@@ -1235,7 +1235,7 @@ ParameterList<ArgType>: ast::Arguments = {
12351235
kw_defaults,
12361236
})
12371237
},
1238-
<params:ParameterListStarArgs<ArgType>> ","? => {
1238+
<params:ParameterListStarArgs<ArgType, StarArgType>> ","? => {
12391239
let (vararg, kwonlyargs, kw_defaults, kwarg) = params;
12401240
ast::Arguments {
12411241
posonlyargs: vec![],
@@ -1291,11 +1291,18 @@ TypedParameter: ast::Arg = {
12911291
},
12921292
};
12931293

1294+
StarTypedParameter: ast::Arg = {
1295+
<location:@L> <arg:Identifier> <a:(":" TestOrStarExpr)?> <end_location:@R> => {
1296+
let annotation = a.map(|x| Box::new(x.1));
1297+
ast::Arg::new(location, end_location, ast::ArgData { arg, annotation, type_comment: None })
1298+
},
1299+
};
1300+
12941301
// Use inline here to make sure the "," is not creating an ambiguity.
12951302
// TODO: figure out another grammar that makes this inline no longer required.
12961303
#[inline]
1297-
ParameterListStarArgs<ArgType>: (Option<Box<ast::Arg>>, Vec<ast::Arg>, Vec<ast::Expr>, Option<Box<ast::Arg>>) = {
1298-
<location:@L> "*" <va:ArgType?> <kw:("," ParameterDef<ArgType>)*> <kwarg:("," KwargParameter<ArgType>)?> =>? {
1304+
ParameterListStarArgs<ArgType, StarArgType>: (Option<Box<ast::Arg>>, Vec<ast::Arg>, Vec<ast::Expr>, Option<Box<ast::Arg>>) = {
1305+
<location:@L> "*" <va:StarArgType?> <kw:("," ParameterDef<ArgType>)*> <kwarg:("," KwargParameter<ArgType>)?> =>? {
12991306
// Extract keyword arguments:
13001307
let mut kwonlyargs = Vec::new();
13011308
let mut kw_defaults = Vec::new();
@@ -1413,7 +1420,7 @@ NamedExpression: ast::Expr = {
14131420
};
14141421

14151422
LambdaDef: ast::Expr = {
1416-
<location:@L> "lambda" <p:ParameterList<UntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> =>? {
1423+
<location:@L> "lambda" <p:ParameterList<UntypedParameter, UntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> =>? {
14171424
let p = validate_arguments(
14181425
p.unwrap_or_else(|| {
14191426
ast::Arguments {

compiler/parser/src/parser.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,18 @@ match x:
803803
match x:
804804
case (0,):
805805
y = 0
806+
"#,
807+
"<test>",
808+
)
809+
.unwrap();
810+
insta::assert_debug_snapshot!(parse_ast);
811+
}
812+
813+
#[test]
814+
fn test_variadic_generics() {
815+
let parse_ast = parse_program(
816+
r#"
817+
def args_to_tuple(*args: *Ts) -> Tuple[*Ts]: ...
806818
"#,
807819
"<test>",
808820
)

compiler/parser/src/snapshots/rustpython_parser__parser__tests__variadic_generics.snap

Lines changed: 188 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)