| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c5e7fba commit 2fdfcb9
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1702,6 +1702,10 @@ impl Compiler { | |||
| 1702 | 1702 | ||
| 1703 | 1703 | let mut loop_labels = vec![]; | |
| 1704 | 1704 | for generator in generators { | |
| 1705 | + if generator.is_async { | ||
| 1706 | + unimplemented!("async for comprehensions"); | ||
| 1707 | + } | ||
| 1708 | + | ||
| 1705 | 1709 | if loop_labels.is_empty() { | |
| 1706 | 1710 | // Load iterator onto stack (passed as first argument): | |
| 1707 | 1711 | self.emit(Instruction::LoadName { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,7 +14,8 @@ extern crate log; | |||
| 14 | 14 | use clap::{App, Arg}; | |
| 15 | 15 | ||
| 16 | 16 | use rustpython_parser::{ast, parser}; | |
| 17 | - use std::path::Path; | ||
| 17 | + use std::path::{Path, PathBuf}; | ||
| 18 | + use std::time::Instant; | ||
| 18 | 19 | ||
| 19 | 20 | fn main() { | |
| 20 | 21 | env_logger::init(); | |
@@ -32,14 +33,21 @@ fn main() { | |||
| 32 | 33 | let folder = Path::new(matches.value_of("folder").unwrap()); | |
| 33 | 34 | if folder.exists() && folder.is_dir() { | |
| 34 | 35 | println!("Parsing folder of python code: {:?}", folder); | |
| 35 | - let res = parse_folder(&folder).unwrap(); | ||
| 36 | - println!("Processed {:?} files", res.len()); | ||
| 36 | + let t1 = Instant::now(); | ||
| 37 | + let parsed_files = parse_folder(&folder).unwrap(); | ||
| 38 | + let t2 = Instant::now(); | ||
| 39 | + let results = ScanResult { | ||
| 40 | + t1, | ||
| 41 | + t2, | ||
| 42 | + parsed_files, | ||
| 43 | + }; | ||
| 44 | + statistics(results); | ||
| 37 | 45 | } else { | |
| 38 | 46 | println!("{:?} is not a folder.", folder); | |
| 39 | 47 | } | |
| 40 | 48 | } | |
| 41 | 49 | ||
| 42 | - fn parse_folder(path: &Path) -> std::io::Result<Vec<ast::Program>> { | ||
| 50 | + fn parse_folder(path: &Path) -> std::io::Result<Vec<ParsedFile>> { | ||
| 43 | 51 | let mut res = vec![]; | |
| 44 | 52 | info!("Parsing folder of python code: {:?}", path); | |
| 45 | 53 | for entry in path.read_dir()? { | |
@@ -49,22 +57,66 @@ fn parse_folder(path: &Path) -> std::io::Result<Vec<ast::Program>> { | |||
| 49 | 57 | ||
| 50 | 58 | let path = entry.path(); | |
| 51 | 59 | if metadata.is_dir() { | |
| 52 | - let x = parse_folder(&path)?; | ||
| 53 | - res.extend(x); | ||
| 60 | + res.extend(parse_folder(&path)?); | ||
| 54 | 61 | } | |
| 55 | 62 | ||
| 56 | 63 | if metadata.is_file() && path.extension().and_then(|s| s.to_str()) == Some("py") { | |
| 57 | - match parse_python_file(&path) { | ||
| 58 | - Ok(x) => res.push(x), | ||
| 64 | + let result = parse_python_file(&path); | ||
| 65 | + match &result { | ||
| 66 | + Ok(_) => {} | ||
| 59 | 67 | Err(y) => error!("Erreur in file {:?} {:?}", path, y), | |
| 60 | 68 | } | |
| 69 | + res.push(ParsedFile { | ||
| 70 | + filename: Box::new(path), | ||
| 71 | + result, | ||
| 72 | + }); | ||
| 61 | 73 | } | |
| 62 | 74 | } | |
| 63 | 75 | Ok(res) | |
| 64 | 76 | } | |
| 65 | 77 | ||
| 66 | - fn parse_python_file(filename: &Path) -> Result<ast::Program, String> { | ||
| 78 | + fn parse_python_file(filename: &Path) -> ParseResult { | ||
| 67 | 79 | info!("Parsing file {:?}", filename); | |
| 68 | 80 | let source = std::fs::read_to_string(filename).map_err(|e| e.to_string())?; | |
| 69 | 81 | parser::parse_program(&source).map_err(|e| e.to_string()) | |
| 70 | 82 | } | |
| 83 | + | ||
| 84 | + fn statistics(results: ScanResult) { | ||
| 85 | + // println!("Processed {:?} files", res.len()); | ||
| 86 | + println!("Scanned a total of {} files", results.parsed_files.len()); | ||
| 87 | + let total = results.parsed_files.len(); | ||
| 88 | + let failed = results | ||
| 89 | + .parsed_files | ||
| 90 | + .iter() | ||
| 91 | + .filter(|p| p.result.is_err()) | ||
| 92 | + .count(); | ||
| 93 | + let passed = results | ||
| 94 | + .parsed_files | ||
| 95 | + .iter() | ||
| 96 | + .filter(|p| p.result.is_ok()) | ||
| 97 | + .count(); | ||
| 98 | + println!("Passed: {} Failed: {} Total: {}", passed, failed, total); | ||
| 99 | + println!( | ||
| 100 | + "That is {} % success rate.", | ||
| 101 | + (passed as f64 * 100.0) / total as f64 | ||
| 102 | + ); | ||
| 103 | + let duration = results.t2 - results.t1; | ||
| 104 | + println!("Total time spend: {:?}", duration); | ||
| 105 | + println!( | ||
| 106 | + "File processing rate: {} files/second", | ||
| 107 | + (total * 1_000_000) as f64 / duration.as_micros() as f64 | ||
| 108 | + ); | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + struct ScanResult { | ||
| 112 | + t1: Instant, | ||
| 113 | + t2: Instant, | ||
| 114 | + parsed_files: Vec<ParsedFile>, | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + struct ParsedFile { | ||
| 118 | + filename: Box<PathBuf>, | ||
| 119 | + result: ParseResult, | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + type ParseResult = Result<ast::Program, String>; | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -318,6 +318,7 @@ pub struct Comprehension { | |||
| 318 | 318 | pub target: Expression, | |
| 319 | 319 | pub iter: Expression, | |
| 320 | 320 | pub ifs: Vec<Expression>, | |
| 321 | + pub is_async: bool, | ||
| 321 | 322 | } | |
| 322 | 323 | ||
| 323 | 324 | #[derive(Debug, PartialEq)] | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -386,6 +386,7 @@ mod tests { | |||
| 386 | 386 | target: mk_ident("y", 1, 8), | |
| 387 | 387 | iter: mk_ident("z", 1, 13), | |
| 388 | 388 | ifs: vec![], | |
| 389 | + is_async: false, | ||
| 389 | 390 | }], | |
| 390 | 391 | } | |
| 391 | 392 | } | |
@@ -415,6 +416,7 @@ mod tests { | |||
| 415 | 416 | }, | |
| 416 | 417 | iter: mk_ident("z", 1, 17), | |
| 417 | 418 | ifs: vec![], | |
| 419 | + is_async: false, | ||
| 418 | 420 | }, | |
| 419 | 421 | ast::Comprehension { | |
| 420 | 422 | location: ast::Location::new(1, 19), | |
@@ -436,6 +438,7 @@ mod tests { | |||
| 436 | 438 | }, | |
| 437 | 439 | }, | |
| 438 | 440 | ], | |
| 441 | + is_async: false, | ||
| 439 | 442 | } | |
| 440 | 443 | ], | |
| 441 | 444 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -908,6 +908,7 @@ Atom: ast::Expression = { | |||
| 908 | 908 | node: ast::ExpressionType::Tuple { elements: Vec::new() } | |
| 909 | 909 | }) | |
| 910 | 910 | }, | |
| 911 | + "(" <e:YieldExpr> ")" => e, | ||
| 911 | 912 | <location:@L> "(" <element:Test> <generators:CompFor> ")" => { | |
| 912 | 913 | ast::Expression { | |
| 913 | 914 | location, | |
@@ -1021,8 +1022,9 @@ StarExpr: ast::Expression = { | |||
| 1021 | 1022 | CompFor: Vec<ast::Comprehension> = <c:SingleForComprehension+> => c; | |
| 1022 | 1023 | ||
| 1023 | 1024 | SingleForComprehension: ast::Comprehension = { | |
| 1024 | - <location:@L> "for" <target:ExpressionList> "in" <iter:OrTest> <ifs:ComprehensionIf*> => { | ||
| 1025 | - ast::Comprehension { location, target, iter, ifs } | ||
| 1025 | + <location:@L> <is_async:"async"?> "for" <target:ExpressionList> "in" <iter:OrTest> <ifs:ComprehensionIf*> => { | ||
| 1026 | + let is_async = is_async.is_some(); | ||
| 1027 | + ast::Comprehension { location, target, iter, ifs, is_async } | ||
| 1026 | 1028 | } | |
| 1027 | 1029 | }; | |
| 1028 | 1030 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -64,3 +64,26 @@ def catch_exception(): | |||
| 64 | 64 | ||
| 65 | 65 | with assertRaises(KeyError): | |
| 66 | 66 | assert g.throw(KeyError, KeyError(), None) == 2 | |
| 67 | + | ||
| 68 | + | ||
| 69 | + r = [] | ||
| 70 | + def p(a, b, c): | ||
| 71 | + # print(a, b, c) | ||
| 72 | + r.append(a) | ||
| 73 | + r.append(b) | ||
| 74 | + r.append(c) | ||
| 75 | + | ||
| 76 | + | ||
| 77 | + def g5(): | ||
| 78 | + p('a', (yield 2), (yield 5)) | ||
| 79 | + yield 99 | ||
| 80 | + | ||
| 81 | + g = g5() | ||
| 82 | + g.send(None) | ||
| 83 | + g.send(66) | ||
| 84 | + # g.send(88) | ||
| 85 | + l = list(g) | ||
| 86 | + # print(r) | ||
| 87 | + # print(l) | ||
| 88 | + assert l == [99] | ||
| 89 | + assert r == ['a', 66, None] | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -579,6 +579,7 @@ fn comprehension_to_ast( | |||
| 579 | 579 | target => expression_to_ast(vm, &comprehension.target)?, | |
| 580 | 580 | iter => expression_to_ast(vm, &comprehension.iter)?, | |
| 581 | 581 | ifs => expressions_to_ast(vm, &comprehension.ifs)?, | |
| 582 | + is_async => vm.new_bool(comprehension.is_async), | ||
| 582 | 583 | })) | |
| 583 | 584 | } | |
| 584 | 585 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments