Skip to content

Commit 0d7b948

Browse files
committed
Allow type variable tuple for *args
1 parent f43e5b7 commit 0d7b948

3 files changed

Lines changed: 214 additions & 7 deletions

File tree

‎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 {

‎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
)
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
---
2+
source: compiler/parser/src/parser.rs
3+
expression: parse_ast
4+
---
5+
[
6+
Located {
7+
location: Location {
8+
row: 2,
9+
column: 0,
10+
},
11+
end_location: Some(
12+
Location {
13+
row: 2,
14+
column: 48,
15+
},
16+
),
17+
custom: (),
18+
node: FunctionDef {
19+
name: "args_to_tuple",
20+
args: Arguments {
21+
posonlyargs: [],
22+
args: [],
23+
vararg: Some(
24+
Located {
25+
location: Location {
26+
row: 2,
27+
column: 19,
28+
},
29+
end_location: Some(
30+
Location {
31+
row: 2,
32+
column: 28,
33+
},
34+
),
35+
custom: (),
36+
node: ArgData {
37+
arg: "args",
38+
annotation: Some(
39+
Located {
40+
location: Location {
41+
row: 2,
42+
column: 25,
43+
},
44+
end_location: Some(
45+
Location {
46+
row: 2,
47+
column: 28,
48+
},
49+
),
50+
custom: (),
51+
node: Starred {
52+
value: Located {
53+
location: Location {
54+
row: 2,
55+
column: 26,
56+
},
57+
end_location: Some(
58+
Location {
59+
row: 2,
60+
column: 28,
61+
},
62+
),
63+
custom: (),
64+
node: Name {
65+
id: "Ts",
66+
ctx: Load,
67+
},
68+
},
69+
ctx: Load,
70+
},
71+
},
72+
),
73+
type_comment: None,
74+
},
75+
},
76+
),
77+
kwonlyargs: [],
78+
kw_defaults: [],
79+
kwarg: None,
80+
defaults: [],
81+
},
82+
body: [
83+
Located {
84+
location: Location {
85+
row: 2,
86+
column: 45,
87+
},
88+
end_location: Some(
89+
Location {
90+
row: 2,
91+
column: 48,
92+
},
93+
),
94+
custom: (),
95+
node: Expr {
96+
value: Located {
97+
location: Location {
98+
row: 2,
99+
column: 45,
100+
},
101+
end_location: Some(
102+
Location {
103+
row: 2,
104+
column: 48,
105+
},
106+
),
107+
custom: (),
108+
node: Constant {
109+
value: Ellipsis,
110+
kind: None,
111+
},
112+
},
113+
},
114+
},
115+
],
116+
decorator_list: [],
117+
returns: Some(
118+
Located {
119+
location: Location {
120+
row: 2,
121+
column: 33,
122+
},
123+
end_location: Some(
124+
Location {
125+
row: 2,
126+
column: 43,
127+
},
128+
),
129+
custom: (),
130+
node: Subscript {
131+
value: Located {
132+
location: Location {
133+
row: 2,
134+
column: 33,
135+
},
136+
end_location: Some(
137+
Location {
138+
row: 2,
139+
column: 38,
140+
},
141+
),
142+
custom: (),
143+
node: Name {
144+
id: "Tuple",
145+
ctx: Load,
146+
},
147+
},
148+
slice: Located {
149+
location: Location {
150+
row: 2,
151+
column: 39,
152+
},
153+
end_location: Some(
154+
Location {
155+
row: 2,
156+
column: 42,
157+
},
158+
),
159+
custom: (),
160+
node: Starred {
161+
value: Located {
162+
location: Location {
163+
row: 2,
164+
column: 40,
165+
},
166+
end_location: Some(
167+
Location {
168+
row: 2,
169+
column: 42,
170+
},
171+
),
172+
custom: (),
173+
node: Name {
174+
id: "Ts",
175+
ctx: Load,
176+
},
177+
},
178+
ctx: Load,
179+
},
180+
},
181+
ctx: Load,
182+
},
183+
},
184+
),
185+
type_comment: None,
186+
},
187+
},
188+
]

0 commit comments

Comments
 (0)