Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd278fb8

Browse files
authored
Merge pull requestRustPython#597 from RustPython/type_hints
Add type annotations to parser.
2 parentsb7c03b4 +f7a2225 commitd278fb8

File tree

6 files changed

+112
-40
lines changed

6 files changed

+112
-40
lines changed

‎parser/src/ast.rs‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ pub enum Statement {
122122
// docstring: String,
123123
body:Vec<LocatedStatement>,
124124
decorator_list:Vec<Expression>,
125+
returns:Option<Expression>,
125126
},
126127
}
127128

@@ -271,14 +272,20 @@ impl Expression {
271272
*/
272273
#[derive(Debug,PartialEq,Default)]
273274
pubstructParameters{
274-
pubargs:Vec<String>,
275-
pubkwonlyargs:Vec<String>,
276-
pubvararg:Option<Option<String>>,// Optionally we handle optionally named '*args' or '*'
277-
pubkwarg:Option<Option<String>>,
275+
pubargs:Vec<Parameter>,
276+
pubkwonlyargs:Vec<Parameter>,
277+
pubvararg:Option<Option<Parameter>>,// Optionally we handle optionally named '*args' or '*'
278+
pubkwarg:Option<Option<Parameter>>,
278279
pubdefaults:Vec<Expression>,
279280
pubkw_defaults:Vec<Option<Expression>>,
280281
}
281282

283+
#[derive(Debug,PartialEq,Default)]
284+
pubstructParameter{
285+
pubarg:String,
286+
pubannotation:Option<Box<Expression>>,
287+
}
288+
282289
#[derive(Debug,PartialEq)]
283290
pubenumComprehensionKind{
284291
GeneratorExpression{element:Expression},

‎parser/src/parser.rs‎

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,16 @@ mod tests {
244244
node: ast::Statement::Expression{
245245
expression: ast::Expression::Lambda{
246246
args: ast::Parameters{
247-
args: vec![String::from("x"),String::from("y")],
247+
args: vec![
248+
ast::Parameter{
249+
arg:String::from("x"),
250+
annotation:None,
251+
},
252+
ast::Parameter{
253+
arg:String::from("y"),
254+
annotation:None,
255+
}
256+
],
248257
kwonlyargs: vec![],
249258
vararg:None,
250259
kwarg:None,
@@ -330,7 +339,10 @@ mod tests {
330339
node: ast::Statement::FunctionDef{
331340
name:String::from("__init__"),
332341
args: ast::Parameters{
333-
args: vec![String::from("self")],
342+
args: vec![ast::Parameter{
343+
arg:String::from("self"),
344+
annotation:None,
345+
}],
334346
kwonlyargs: vec![],
335347
vararg:None,
336348
kwarg:None,
@@ -342,14 +354,24 @@ mod tests {
342354
node: ast::Statement::Pass,
343355
}],
344356
decorator_list: vec![],
357+
returns:None,
345358
}
346359
},
347360
ast::LocatedStatement{
348361
location: ast::Location::new(4,2),
349362
node: ast::Statement::FunctionDef{
350363
name:String::from("method_with_default"),
351364
args: ast::Parameters{
352-
args: vec![String::from("self"),String::from("arg"),],
365+
args: vec![
366+
ast::Parameter{
367+
arg:String::from("self"),
368+
annotation:None,
369+
},
370+
ast::Parameter{
371+
arg:String::from("arg"),
372+
annotation:None,
373+
}
374+
],
353375
kwonlyargs: vec![],
354376
vararg:None,
355377
kwarg:None,
@@ -365,6 +387,7 @@ mod tests {
365387
node: ast::Statement::Pass,
366388
}],
367389
decorator_list: vec![],
390+
returns:None,
368391
}
369392
}
370393
],

‎parser/src/python.lalrpop‎

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -446,21 +446,22 @@ WithItem: ast::WithItem = {
446446
};
447447

448448
FuncDef: ast::LocatedStatement = {
449-
<d:Decorator*> <loc:@L> "def" <i:Identifier> <a:Parameters> ":" <s:Suite> => {
449+
<d:Decorator*> <loc:@L> "def" <i:Identifier> <a:Parameters><r:("->" Test)?>":" <s:Suite> => {
450450
ast::LocatedStatement {
451451
location: loc,
452452
node: ast::Statement::FunctionDef {
453453
name: i,
454454
args: a,
455455
body: s,
456456
decorator_list: d,
457+
returns: r.map(|x| x.1),
457458
}
458459
}
459460
},
460461
};
461462

462463
Parameters: ast::Parameters = {
463-
"(" <a: (TypedArgsList)?> ")" => {
464+
"(" <a: (TypedArgsList<TypedParameter>)?> ")" => {
464465
match a {
465466
Some(a) => a,
466467
None => Default::default(),
@@ -470,8 +471,10 @@ Parameters: ast::Parameters = {
470471

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

477480
// Now gather rest of parameters:
@@ -489,7 +492,7 @@ TypedArgsList: ast::Parameters = {
489492
kw_defaults: kw_defaults,
490493
}
491494
},
492-
<param1:TypedParameters> <kw:("," KwargParameter)> => {
495+
<param1:TypedParameters<ArgType>> <kw:("," KwargParameter<ArgType>)> => {
493496
let (names, default_elements) = param1;
494497

495498
// Now gather rest of parameters:
@@ -507,7 +510,7 @@ TypedArgsList: ast::Parameters = {
507510
kw_defaults: kw_defaults,
508511
}
509512
},
510-
<params:ParameterListStarArgs> => {
513+
<params:ParameterListStarArgs<ArgType>> => {
511514
let (vararg, kwonlyargs, kw_defaults, kwarg) = params;
512515
ast::Parameters {
513516
args: vec![],
@@ -518,7 +521,7 @@ TypedArgsList: ast::Parameters = {
518521
kw_defaults: kw_defaults,
519522
}
520523
},
521-
<kw:KwargParameter> => {
524+
<kw:KwargParameter<ArgType>> => {
522525
ast::Parameters {
523526
args: vec![],
524527
kwonlyargs: vec![],
@@ -532,8 +535,8 @@ TypedArgsList: ast::Parameters = {
532535

533536
// Use inline here to make sure the "," is not creating an ambiguity.
534537
#[inline]
535-
TypedParameters: (Vec<String>, Vec<ast::Expression>) = {
536-
<param1:TypedParameterDef> <param2:("," TypedParameterDef)*> => {
538+
TypedParameters<ArgType>: (Vec<ast::Parameter>, Vec<ast::Expression>) = {
539+
<param1:TypedParameterDef<ArgType>> <param2:("," TypedParameterDef<ArgType>)*> => {
537540
// Combine first parameters:
538541
let mut args = vec![param1];
539542
args.extend(param2.into_iter().map(|x| x.1));
@@ -542,7 +545,6 @@ TypedParameters: (Vec<String>, Vec<ast::Expression>) = {
542545
let mut default_elements = vec![];
543546

544547
for (name, default) in args.into_iter() {
545-
names.push(name.clone());
546548
if let Some(default) = default {
547549
default_elements.push(default);
548550
} else {
@@ -551,28 +553,35 @@ TypedParameters: (Vec<String>, Vec<ast::Expression>) = {
551553
// have defaults
552554
panic!(
553555
"non-default argument follows default argument: {}",
554-
name
556+
&name.arg
555557
);
556558
}
557559
}
560+
names.push(name);
558561
}
559562

560563
(names, default_elements)
561564
}
562565
};
563566

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

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

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

593-
KwargParameter: Option<String> = {
594-
"**" <kwarg:Identifier?> => {
602+
KwargParameter<ArgType>: Option<ast::Parameter> = {
603+
"**" <kwarg:ArgType?> => {
595604
kwarg
596605
}
597606
};
@@ -675,7 +684,7 @@ Test: ast::Expression = {
675684
};
676685

677686
LambdaDef: ast::Expression = {
678-
"lambda" <p:TypedArgsList?> ":" <b:Test> =>
687+
"lambda" <p:TypedArgsList<UntypedParameter>?> ":" <b:Test> =>
679688
ast::Expression::Lambda {
680689
args: p.unwrap_or(Default::default()),
681690
body:Box::new(b)
@@ -1088,6 +1097,7 @@ extern {
10881097
"<=" => lexer::Tok::LessEqual,
10891098
">" => lexer::Tok::Greater,
10901099
">=" => lexer::Tok::GreaterEqual,
1100+
"->" => lexer::Tok::Rarrow,
10911101
"and" => lexer::Tok::And,
10921102
"as" => lexer::Tok::As,
10931103
"assert" => lexer::Tok::Assert,

‎tests/snippets/type_hints.py‎

Lines changed: 7 additions & 0 deletions
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+
defcurry(foo:int)->float:
5+
returnfoo*3.1415926*2
6+
7+
assertcurry(2)>10

‎vm/src/compile.rs‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ impl Compiler {
300300
args,
301301
body,
302302
decorator_list,
303-
} =>self.compile_function_def(name, args, body, decorator_list)?,
303+
returns,
304+
} =>self.compile_function_def(name, args, body, decorator_list, returns)?,
304305
ast::Statement::ClassDef{
305306
name,
306307
body,
@@ -442,10 +443,14 @@ impl Compiler {
442443

443444
let line_number =self.get_source_line_number();
444445
self.code_object_stack.push(CodeObject::new(
445-
args.args.clone(),
446-
args.vararg.clone(),
447-
args.kwonlyargs.clone(),
448-
args.kwarg.clone(),
446+
args.args.iter().map(|a| a.arg.clone()).collect(),
447+
args.vararg
448+
.as_ref()
449+
.map(|x| x.as_ref().map(|a| a.arg.clone())),
450+
args.kwonlyargs.iter().map(|a| a.arg.clone()).collect(),
451+
args.kwarg
452+
.as_ref()
453+
.map(|x| x.as_ref().map(|a| a.arg.clone())),
449454
self.source_path.clone().unwrap(),
450455
line_number,
451456
name.to_string(),
@@ -584,6 +589,7 @@ impl Compiler {
584589
args:&ast::Parameters,
585590
body:&[ast::LocatedStatement],
586591
decorator_list:&[ast::Expression],
592+
_returns:&Option<ast::Expression>,// TODO: use type hint somehow..
587593
) ->Result<(),CompileError>{
588594
// Create bytecode for this function:
589595
// remember to restore self.in_loop to the original after the function is compiled

‎vm/src/stdlib/ast.rs‎

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ fn statement_to_ast(ctx: &PyContext, statement: &ast::LocatedStatement) -> PyObj
8282
args,
8383
body,
8484
decorator_list,
85+
returns,
8586
} =>{
8687
let node =create_node(ctx,"FunctionDef");
8788

@@ -96,6 +97,13 @@ fn statement_to_ast(ctx: &PyContext, statement: &ast::LocatedStatement) -> PyObj
9697

9798
let py_decorator_list =expressions_to_ast(ctx, decorator_list);
9899
ctx.set_attr(&node,"decorator_list", py_decorator_list);
100+
101+
let py_returns =ifletSome(hint) = returns{
102+
expression_to_ast(ctx, hint)
103+
}else{
104+
ctx.none()
105+
};
106+
ctx.set_attr(&node,"returns", py_returns);
99107
node
100108
}
101109
ast::Statement::Continue =>create_node(ctx,"Continue"),
@@ -538,17 +546,28 @@ fn parameters_to_ast(ctx: &PyContext, args: &ast::Parameters) -> PyObjectRef {
538546
ctx.set_attr(
539547
&node,
540548
"args",
541-
ctx.new_list(
542-
args.args
543-
.iter()
544-
.map(|a| ctx.new_str(a.to_string()))
545-
.collect(),
546-
),
549+
ctx.new_list(args.args.iter().map(|a|parameter_to_ast(ctx, a)).collect()),
547550
);
548551

549552
node
550553
}
551554

555+
fnparameter_to_ast(ctx:&PyContext,parameter:&ast::Parameter) ->PyObjectRef{
556+
let node =create_node(ctx,"arg");
557+
558+
let py_arg = ctx.new_str(parameter.arg.to_string());
559+
ctx.set_attr(&node,"arg", py_arg);
560+
561+
let py_annotation =ifletSome(annotation) =&parameter.annotation{
562+
expression_to_ast(ctx, annotation)
563+
}else{
564+
ctx.none()
565+
};
566+
ctx.set_attr(&node,"annotation", py_annotation);
567+
568+
node
569+
}
570+
552571
fncomprehension_to_ast(ctx:&PyContext,comprehension:&ast::Comprehension) ->PyObjectRef{
553572
let node =create_node(ctx,"comprehension");
554573

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp