Skip to content

Commit 6544f60

Browse files
committed
Add type annotations to parser.
1 parent a7c3f85 commit 6544f60

File tree

5 files changed

+55
-30
lines changed

5 files changed

+55
-30
lines changed

parser/src/ast.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -269,14 +269,20 @@ impl Expression {
269269
*/
270270
#[derive(Debug, PartialEq, Default)]
271271
pub struct Parameters {
272-
pub args: Vec<String>,
273-
pub kwonlyargs: Vec<String>,
274-
pub vararg: Option<Option<String>>, // Optionally we handle optionally named '*args' or '*'
275-
pub kwarg: Option<Option<String>>,
272+
pub args: Vec<Parameter>,
273+
pub kwonlyargs: Vec<Parameter>,
274+
pub vararg: Option<Option<Parameter>>, // Optionally we handle optionally named '*args' or '*'
275+
pub kwarg: Option<Option<Parameter>>,
276276
pub defaults: Vec<Expression>,
277277
pub kw_defaults: Vec<Option<Expression>>,
278278
}
279279

280+
#[derive(Debug, PartialEq, Default)]
281+
pub struct Parameter {
282+
pub arg: String,
283+
pub annotation: Option<Box<Expression>>,
284+
}
285+
280286
#[derive(Debug, PartialEq)]
281287
pub enum ComprehensionKind {
282288
GeneratorExpression { element: Expression },

parser/src/python.lalrpop

+29-21
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ FuncDef: ast::LocatedStatement = {
460460
};
461461

462462
Parameters: ast::Parameters = {
463-
"(" <a: (TypedArgsList)?> ")" => {
463+
"(" <a: (TypedArgsList<TypedParameter>)?> ")" => {
464464
match a {
465465
Some(a) => a,
466466
None => Default::default(),
@@ -470,8 +470,10 @@ Parameters: ast::Parameters = {
470470

471471
// parameters are (String, None), kwargs are (String, Some(Test)) where Test is
472472
// the default
473-
TypedArgsList: ast::Parameters = {
474-
<param1:TypedParameters> <args2:("," ParameterListStarArgs)?> => {
473+
// Note that this is a macro which is used once for function defs, and
474+
// once for lambda defs.
475+
TypedArgsList<ArgType>: ast::Parameters = {
476+
<param1:TypedParameters<ArgType>> <args2:("," ParameterListStarArgs<ArgType>)?> => {
475477
let (names, default_elements) = param1;
476478

477479
// Now gather rest of parameters:
@@ -489,7 +491,7 @@ TypedArgsList: ast::Parameters = {
489491
kw_defaults: kw_defaults,
490492
}
491493
},
492-
<param1:TypedParameters> <kw:("," KwargParameter)> => {
494+
<param1:TypedParameters<ArgType>> <kw:("," KwargParameter<ArgType>)> => {
493495
let (names, default_elements) = param1;
494496

495497
// Now gather rest of parameters:
@@ -507,7 +509,7 @@ TypedArgsList: ast::Parameters = {
507509
kw_defaults: kw_defaults,
508510
}
509511
},
510-
<params:ParameterListStarArgs> => {
512+
<params:ParameterListStarArgs<ArgType>> => {
511513
let (vararg, kwonlyargs, kw_defaults, kwarg) = params;
512514
ast::Parameters {
513515
args: vec![],
@@ -518,7 +520,7 @@ TypedArgsList: ast::Parameters = {
518520
kw_defaults: kw_defaults,
519521
}
520522
},
521-
<kw:KwargParameter> => {
523+
<kw:KwargParameter<ArgType>> => {
522524
ast::Parameters {
523525
args: vec![],
524526
kwonlyargs: vec![],
@@ -532,8 +534,8 @@ TypedArgsList: ast::Parameters = {
532534

533535
// Use inline here to make sure the "," is not creating an ambiguity.
534536
#[inline]
535-
TypedParameters: (Vec<String>, Vec<ast::Expression>) = {
536-
<param1:TypedParameterDef> <param2:("," TypedParameterDef)*> => {
537+
TypedParameters<ArgType>: (Vec<ast::Parameter>, Vec<ast::Expression>) = {
538+
<param1:TypedParameterDef<ArgType>> <param2:("," TypedParameterDef<ArgType>)*> => {
537539
// Combine first parameters:
538540
let mut args = vec![param1];
539541
args.extend(param2.into_iter().map(|x| x.1));
@@ -542,7 +544,6 @@ TypedParameters: (Vec<String>, Vec<ast::Expression>) = {
542544
let mut default_elements = vec![];
543545

544546
for (name, default) in args.into_iter() {
545-
names.push(name.clone());
546547
if let Some(default) = default {
547548
default_elements.push(default);
548549
} else {
@@ -551,28 +552,35 @@ TypedParameters: (Vec<String>, Vec<ast::Expression>) = {
551552
// have defaults
552553
panic!(
553554
"non-default argument follows default argument: {}",
554-
name
555+
&name.arg
555556
);
556557
}
557558
}
559+
names.push(name);
558560
}
559561

560562
(names, default_elements)
561563
}
562564
};
563565

564-
TypedParameterDef: (String, Option<ast::Expression>) = {
565-
<i:TypedParameter> => (i, None),
566-
<i:TypedParameter> "=" <e:Test> => (i, Some(e)),
566+
TypedParameterDef<ArgType>: (ast::Parameter, Option<ast::Expression>) = {
567+
<i:ArgType> => (i, None),
568+
<i:ArgType> "=" <e:Test> => (i, Some(e)),
567569
};
568570

569-
// TODO: add type annotations here:
570-
TypedParameter: String = {
571-
Identifier,
571+
UntypedParameter: ast::Parameter = {
572+
<i:Identifier> => ast::Parameter { arg: i, annotation: None },
572573
};
573574

574-
ParameterListStarArgs: (Option<Option<String>>, Vec<String>, Vec<Option<ast::Expression>>, Option<Option<String>>) = {
575-
"*" <va:Identifier?> <kw:("," TypedParameterDef)*> <kwarg:("," KwargParameter)?> => {
575+
TypedParameter: ast::Parameter = {
576+
<arg:Identifier> <a:(":" Test)?>=> {
577+
let annotation = a.map(|x| Box::new(x.1));
578+
ast::Parameter { arg, annotation }
579+
},
580+
};
581+
582+
ParameterListStarArgs<ArgType>: (Option<Option<ast::Parameter>>, Vec<ast::Parameter>, Vec<Option<ast::Expression>>, Option<Option<ast::Parameter>>) = {
583+
"*" <va:ArgType?> <kw:("," TypedParameterDef<ArgType>)*> <kwarg:("," KwargParameter<ArgType>)?> => {
576584
// Extract keyword arguments:
577585
let mut kwonlyargs = vec![];
578586
let mut kw_defaults = vec![];
@@ -590,8 +598,8 @@ ParameterListStarArgs: (Option<Option<String>>, Vec<String>, Vec<Option<ast::Exp
590598
}
591599
};
592600

593-
KwargParameter: Option<String> = {
594-
"**" <kwarg:Identifier?> => {
601+
KwargParameter<ArgType>: Option<ast::Parameter> = {
602+
"**" <kwarg:ArgType?> => {
595603
kwarg
596604
}
597605
};
@@ -675,7 +683,7 @@ Test: ast::Expression = {
675683
};
676684

677685
LambdaDef: ast::Expression = {
678-
"lambda" <p:TypedArgsList?> ":" <b:Test> =>
686+
"lambda" <p:TypedArgsList<UntypedParameter>?> ":" <b:Test> =>
679687
ast::Expression::Lambda {
680688
args: p.unwrap_or(Default::default()),
681689
body:Box::new(b)

tests/snippets/type_hints.py

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
# See also: https://github.com/RustPython/RustPython/issues/587
3+
4+
def curry(foo: int): # TODO: -> float:
5+
return foo * 3.1415926 * 2
6+
7+
assert curry(2) > 10

vm/src/compile.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -442,10 +442,14 @@ impl Compiler {
442442

443443
let line_number = self.get_source_line_number();
444444
self.code_object_stack.push(CodeObject::new(
445-
args.args.clone(),
446-
args.vararg.clone(),
447-
args.kwonlyargs.clone(),
448-
args.kwarg.clone(),
445+
args.args.iter().map(|a| a.arg.clone()).collect(),
446+
args.vararg
447+
.as_ref()
448+
.map(|x| x.as_ref().map(|a| a.arg.clone())),
449+
args.kwonlyargs.iter().map(|a| a.arg.clone()).collect(),
450+
args.kwarg
451+
.as_ref()
452+
.map(|x| x.as_ref().map(|a| a.arg.clone())),
449453
self.source_path.clone().unwrap(),
450454
line_number,
451455
name.to_string(),

vm/src/stdlib/ast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ fn parameters_to_ast(ctx: &PyContext, args: &ast::Parameters) -> PyObjectRef {
540540
ctx.new_list(
541541
args.args
542542
.iter()
543-
.map(|a| ctx.new_str(a.to_string()))
543+
.map(|a| ctx.new_str(a.arg.to_string()))
544544
.collect(),
545545
),
546546
);

0 commit comments

Comments
 (0)