Upgrade RustPython (#4747)

This commit is contained in:
Micha Reiser 2023-05-31 10:26:35 +02:00 committed by GitHub
parent 06bcb85f81
commit 6c1ff6a85f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 104 additions and 93 deletions

12
Cargo.lock generated
View file

@ -2049,7 +2049,7 @@ dependencies = [
[[package]] [[package]]
name = "ruff_text_size" name = "ruff_text_size"
version = "0.0.0" version = "0.0.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=335780aeeac1e6fcd85994ba001d7b8ce99fcf65#335780aeeac1e6fcd85994ba001d7b8ce99fcf65" source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd#7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd"
dependencies = [ dependencies = [
"schemars", "schemars",
"serde", "serde",
@ -2119,7 +2119,7 @@ dependencies = [
[[package]] [[package]]
name = "rustpython-ast" name = "rustpython-ast"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=335780aeeac1e6fcd85994ba001d7b8ce99fcf65#335780aeeac1e6fcd85994ba001d7b8ce99fcf65" source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd#7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd"
dependencies = [ dependencies = [
"is-macro", "is-macro",
"num-bigint", "num-bigint",
@ -2130,7 +2130,7 @@ dependencies = [
[[package]] [[package]]
name = "rustpython-format" name = "rustpython-format"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=335780aeeac1e6fcd85994ba001d7b8ce99fcf65#335780aeeac1e6fcd85994ba001d7b8ce99fcf65" source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd#7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd"
dependencies = [ dependencies = [
"bitflags 2.3.1", "bitflags 2.3.1",
"itertools", "itertools",
@ -2142,7 +2142,7 @@ dependencies = [
[[package]] [[package]]
name = "rustpython-literal" name = "rustpython-literal"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=335780aeeac1e6fcd85994ba001d7b8ce99fcf65#335780aeeac1e6fcd85994ba001d7b8ce99fcf65" source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd#7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd"
dependencies = [ dependencies = [
"hexf-parse", "hexf-parse",
"is-macro", "is-macro",
@ -2154,7 +2154,7 @@ dependencies = [
[[package]] [[package]]
name = "rustpython-parser" name = "rustpython-parser"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=335780aeeac1e6fcd85994ba001d7b8ce99fcf65#335780aeeac1e6fcd85994ba001d7b8ce99fcf65" source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd#7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"is-macro", "is-macro",
@ -2177,7 +2177,7 @@ dependencies = [
[[package]] [[package]]
name = "rustpython-parser-core" name = "rustpython-parser-core"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=335780aeeac1e6fcd85994ba001d7b8ce99fcf65#335780aeeac1e6fcd85994ba001d7b8ce99fcf65" source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd#7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd"
dependencies = [ dependencies = [
"is-macro", "is-macro",
"ruff_text_size", "ruff_text_size",

View file

@ -34,11 +34,11 @@ proc-macro2 = { version = "1.0.51" }
quote = { version = "1.0.23" } quote = { version = "1.0.23" }
regex = { version = "1.7.1" } regex = { version = "1.7.1" }
rustc-hash = { version = "1.1.0" } rustc-hash = { version = "1.1.0" }
ruff_text_size = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "335780aeeac1e6fcd85994ba001d7b8ce99fcf65" } ruff_text_size = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd" }
rustpython-ast = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "335780aeeac1e6fcd85994ba001d7b8ce99fcf65", default-features = false, features = ["all-nodes-with-ranges"]} rustpython-ast = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd", default-features = false, features = ["all-nodes-with-ranges"]}
rustpython-format = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "335780aeeac1e6fcd85994ba001d7b8ce99fcf65" } rustpython-format = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd" }
rustpython-literal = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "335780aeeac1e6fcd85994ba001d7b8ce99fcf65" } rustpython-literal = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd" }
rustpython-parser = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "335780aeeac1e6fcd85994ba001d7b8ce99fcf65", default-features = false, features = ["full-lexer", "all-nodes-with-ranges"] } rustpython-parser = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "7a3eedbf6fb4ea7068a1bf7fe0e97e963ea95ffd", default-features = false, features = ["full-lexer", "all-nodes-with-ranges"] }
schemars = { version = "0.8.12" } schemars = { version = "0.8.12" }
serde = { version = "1.0.152", features = ["derive"] } serde = { version = "1.0.152", features = ["derive"] }
serde_json = { version = "1.0.93", features = ["preserve_order"] } serde_json = { version = "1.0.93", features = ["preserve_order"] }

View file

@ -424,7 +424,8 @@ pub(crate) fn remove_argument(
mod tests { mod tests {
use anyhow::Result; use anyhow::Result;
use ruff_text_size::TextSize; use ruff_text_size::TextSize;
use rustpython_parser as parser; use rustpython_parser::ast::Suite;
use rustpython_parser::Parse;
use ruff_python_ast::source_code::Locator; use ruff_python_ast::source_code::Locator;
@ -433,19 +434,19 @@ mod tests {
#[test] #[test]
fn find_semicolon() -> Result<()> { fn find_semicolon() -> Result<()> {
let contents = "x = 1"; let contents = "x = 1";
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert_eq!(trailing_semicolon(stmt, &locator), None); assert_eq!(trailing_semicolon(stmt, &locator), None);
let contents = "x = 1; y = 1"; let contents = "x = 1; y = 1";
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert_eq!(trailing_semicolon(stmt, &locator), Some(TextSize::from(5))); assert_eq!(trailing_semicolon(stmt, &locator), Some(TextSize::from(5)));
let contents = "x = 1 ; y = 1"; let contents = "x = 1 ; y = 1";
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert_eq!(trailing_semicolon(stmt, &locator), Some(TextSize::from(6))); assert_eq!(trailing_semicolon(stmt, &locator), Some(TextSize::from(6)));
@ -455,7 +456,7 @@ x = 1 \
; y = 1 ; y = 1
"# "#
.trim(); .trim();
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert_eq!(trailing_semicolon(stmt, &locator), Some(TextSize::from(10))); assert_eq!(trailing_semicolon(stmt, &locator), Some(TextSize::from(10)));

View file

@ -139,8 +139,9 @@ fn match_docstring_end(body: &[Stmt]) -> Option<TextSize> {
mod tests { mod tests {
use anyhow::Result; use anyhow::Result;
use ruff_text_size::TextSize; use ruff_text_size::TextSize;
use rustpython_parser as parser; use rustpython_parser::ast::Suite;
use rustpython_parser::lexer::LexResult; use rustpython_parser::lexer::LexResult;
use rustpython_parser::Parse;
use ruff_python_ast::newlines::LineEnding; use ruff_python_ast::newlines::LineEnding;
use ruff_python_ast::source_code::{Locator, Stylist}; use ruff_python_ast::source_code::{Locator, Stylist};
@ -148,7 +149,7 @@ mod tests {
use super::Insertion; use super::Insertion;
fn insert(contents: &str) -> Result<Insertion> { fn insert(contents: &str) -> Result<Insertion> {
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let tokens: Vec<LexResult> = ruff_rustpython::tokenize(contents); let tokens: Vec<LexResult> = ruff_rustpython::tokenize(contents);
let locator = Locator::new(contents); let locator = Locator::new(contents);
let stylist = Stylist::from_tokens(&tokens, &locator); let stylist = Stylist::from_tokens(&tokens, &locator);

View file

@ -1,7 +1,8 @@
/// See: [eradicate.py](https://github.com/myint/eradicate/blob/98f199940979c94447a461d50d27862b118b282d/eradicate.py) /// See: [eradicate.py](https://github.com/myint/eradicate/blob/98f199940979c94447a461d50d27862b118b282d/eradicate.py)
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use regex::Regex; use regex::Regex;
use rustpython_parser as parser; use rustpython_parser::ast::Suite;
use rustpython_parser::Parse;
static ALLOWLIST_REGEX: Lazy<Regex> = Lazy::new(|| { static ALLOWLIST_REGEX: Lazy<Regex> = Lazy::new(|| {
Regex::new( Regex::new(
@ -78,7 +79,7 @@ pub(crate) fn comment_contains_code(line: &str, task_tags: &[String]) -> bool {
} }
// Finally, compile the source code. // Finally, compile the source code.
parser::parse_program(&line, "<filename>").is_ok() Suite::parse(&line, "<filename>").is_ok()
} }
/// Returns `true` if a line is probably part of some multiline code. /// Returns `true` if a line is probably part of some multiline code.

View file

@ -1,7 +1,7 @@
use log::error; use log::error;
use ruff_text_size::{TextRange, TextSize}; use ruff_text_size::{TextRange, TextSize};
use rustpython_parser as parser;
use rustpython_parser::ast::{self, Stmt, Suite}; use rustpython_parser::ast::{self, Stmt, Suite};
use rustpython_parser::Parse;
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix}; use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix};
use ruff_macros::{derive_message_formats, violation}; use ruff_macros::{derive_message_formats, violation};
@ -140,7 +140,7 @@ pub(crate) fn add_required_imports(
.required_imports .required_imports
.iter() .iter()
.flat_map(|required_import| { .flat_map(|required_import| {
let Ok(body) = parser::parse_program(required_import, "<filename>") else { let Ok(body) = Suite::parse(required_import, "<filename>") else {
error!("Failed to parse required import: `{}`", required_import); error!("Failed to parse required import: `{}`", required_import);
return vec![]; return vec![];
}; };

View file

@ -162,7 +162,8 @@ pub(crate) fn function_is_too_complex(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use anyhow::Result; use anyhow::Result;
use rustpython_parser as parser; use rustpython_parser::ast::Suite;
use rustpython_parser::Parse;
use super::get_complexity_number; use super::get_complexity_number;
@ -172,7 +173,7 @@ mod tests {
def trivial(): def trivial():
pass pass
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 1); assert_eq!(get_complexity_number(&stmts), 1);
Ok(()) Ok(())
} }
@ -183,7 +184,7 @@ def trivial():
def expr_as_statement(): def expr_as_statement():
0xF00D 0xF00D
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 1); assert_eq!(get_complexity_number(&stmts), 1);
Ok(()) Ok(())
} }
@ -196,7 +197,7 @@ def sequential(n):
s = k + n s = k + n
return s return s
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 1); assert_eq!(get_complexity_number(&stmts), 1);
Ok(()) Ok(())
} }
@ -212,7 +213,7 @@ def if_elif_else_dead_path(n):
else: else:
return "smaller than or equal to three" return "smaller than or equal to three"
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 3); assert_eq!(get_complexity_number(&stmts), 3);
Ok(()) Ok(())
} }
@ -229,7 +230,7 @@ def nested_ifs():
else: else:
return "smaller than or equal to three" return "smaller than or equal to three"
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 3); assert_eq!(get_complexity_number(&stmts), 3);
Ok(()) Ok(())
} }
@ -241,7 +242,7 @@ def for_loop():
for i in range(10): for i in range(10):
print(i) print(i)
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 2); assert_eq!(get_complexity_number(&stmts), 2);
Ok(()) Ok(())
} }
@ -255,7 +256,7 @@ def for_else(mylist):
else: else:
print(None) print(None)
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 2); assert_eq!(get_complexity_number(&stmts), 2);
Ok(()) Ok(())
} }
@ -269,7 +270,7 @@ def recursive(n):
else: else:
return n return n
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 2); assert_eq!(get_complexity_number(&stmts), 2);
Ok(()) Ok(())
} }
@ -286,7 +287,7 @@ def nested_functions():
a() a()
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 3); assert_eq!(get_complexity_number(&stmts), 3);
Ok(()) Ok(())
} }
@ -304,7 +305,7 @@ def try_else():
else: else:
print(4) print(4)
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 4); assert_eq!(get_complexity_number(&stmts), 4);
Ok(()) Ok(())
} }
@ -321,7 +322,7 @@ def nested_try_finally():
finally: finally:
print(3) print(3)
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 1); assert_eq!(get_complexity_number(&stmts), 1);
Ok(()) Ok(())
} }
@ -338,7 +339,7 @@ async def foobar(a, b, c):
async for x in a: async for x in a:
pass pass
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 3); assert_eq!(get_complexity_number(&stmts), 3);
Ok(()) Ok(())
} }
@ -349,7 +350,7 @@ async def foobar(a, b, c):
def annotated_assign(): def annotated_assign():
x: Any = None x: Any = None
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 1); assert_eq!(get_complexity_number(&stmts), 1);
Ok(()) Ok(())
} }
@ -385,7 +386,7 @@ class Class:
return ServiceProvider(Logger()) return ServiceProvider(Logger())
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 9); assert_eq!(get_complexity_number(&stmts), 9);
Ok(()) Ok(())
} }
@ -399,7 +400,7 @@ def process_detect_lines():
finally: finally:
pass pass
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 1); assert_eq!(get_complexity_number(&stmts), 1);
Ok(()) Ok(())
} }
@ -414,7 +415,7 @@ def process_detect_lines():
if res: if res:
errors.append(f"Non-zero exit code {res}") errors.append(f"Non-zero exit code {res}")
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 2); assert_eq!(get_complexity_number(&stmts), 2);
Ok(()) Ok(())
} }
@ -427,7 +428,7 @@ def with_lock():
if foo: if foo:
print('bar') print('bar')
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(get_complexity_number(&stmts), 2); assert_eq!(get_complexity_number(&stmts), 2);
Ok(()) Ok(())
} }

View file

@ -185,12 +185,13 @@ pub(crate) fn too_many_branches(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use anyhow::Result; use anyhow::Result;
use rustpython_parser as parser; use rustpython_parser::ast::Suite;
use rustpython_parser::Parse;
use super::num_branches; use super::num_branches;
fn test_helper(source: &str, expected_num_branches: usize) -> Result<()> { fn test_helper(source: &str, expected_num_branches: usize) -> Result<()> {
let branches = parser::parse_program(source, "<filename>")?; let branches = Suite::parse(source, "<filename>")?;
assert_eq!(num_branches(&branches), expected_num_branches); assert_eq!(num_branches(&branches), expected_num_branches);
Ok(()) Ok(())
} }

View file

@ -99,12 +99,13 @@ pub(crate) fn too_many_return_statements(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use anyhow::Result; use anyhow::Result;
use rustpython_parser as parser; use rustpython_parser::ast::Suite;
use rustpython_parser::Parse;
use super::num_returns; use super::num_returns;
fn test_helper(source: &str, expected: usize) -> Result<()> { fn test_helper(source: &str, expected: usize) -> Result<()> {
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_returns(&stmts), expected); assert_eq!(num_returns(&stmts), expected);
Ok(()) Ok(())
} }

View file

@ -168,7 +168,8 @@ pub(crate) fn too_many_statements(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use anyhow::Result; use anyhow::Result;
use rustpython_parser as parser; use rustpython_parser::ast::Suite;
use rustpython_parser::Parse;
use super::num_statements; use super::num_statements;
@ -178,7 +179,7 @@ mod tests {
def f(): # 2 def f(): # 2
pass pass
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 2); assert_eq!(num_statements(&stmts), 2);
Ok(()) Ok(())
} }
@ -192,7 +193,7 @@ def f():
else: else:
print() print()
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 5); assert_eq!(num_statements(&stmts), 5);
Ok(()) Ok(())
} }
@ -207,7 +208,7 @@ def f():
if a: if a:
print() print()
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 5); assert_eq!(num_statements(&stmts), 5);
Ok(()) Ok(())
} }
@ -221,7 +222,7 @@ def f(): # 5
elif a: elif a:
print() print()
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 5); assert_eq!(num_statements(&stmts), 5);
Ok(()) Ok(())
} }
@ -239,7 +240,7 @@ def f(): # 9
else: else:
print() print()
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 9); assert_eq!(num_statements(&stmts), 9);
Ok(()) Ok(())
} }
@ -268,7 +269,7 @@ async def f(): # 19
import time import time
pass pass
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 19); assert_eq!(num_statements(&stmts), 19);
Ok(()) Ok(())
} }
@ -280,7 +281,7 @@ def f(): # 2
for i in range(10): for i in range(10):
pass pass
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 2); assert_eq!(num_statements(&stmts), 2);
Ok(()) Ok(())
} }
@ -294,7 +295,7 @@ def f(): # 3
else: else:
print() print()
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 3); assert_eq!(num_statements(&stmts), 3);
Ok(()) Ok(())
} }
@ -309,7 +310,7 @@ def f(): # 5
print() print()
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 5); assert_eq!(num_statements(&stmts), 5);
Ok(()) Ok(())
} }
@ -327,7 +328,7 @@ def f(): # 3
print() print()
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 3); assert_eq!(num_statements(&stmts), 3);
Ok(()) Ok(())
} }
@ -338,7 +339,7 @@ def f(): # 3
def f(): def f():
return return
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 1); assert_eq!(num_statements(&stmts), 1);
Ok(()) Ok(())
} }
@ -354,7 +355,7 @@ def f(): # 6
print() print()
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 6); assert_eq!(num_statements(&stmts), 6);
Ok(()) Ok(())
} }
@ -368,7 +369,7 @@ def f(): # 5
except Exception: except Exception:
raise raise
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 5); assert_eq!(num_statements(&stmts), 5);
Ok(()) Ok(())
} }
@ -384,7 +385,7 @@ def f(): # 7
else: else:
print() print()
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 7); assert_eq!(num_statements(&stmts), 7);
Ok(()) Ok(())
} }
@ -402,7 +403,7 @@ def f(): # 10
finally: finally:
pass pass
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 10); assert_eq!(num_statements(&stmts), 10);
Ok(()) Ok(())
} }
@ -418,7 +419,7 @@ def f(): # 8
except Exception: except Exception:
raise raise
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 8); assert_eq!(num_statements(&stmts), 8);
Ok(()) Ok(())
} }
@ -436,7 +437,7 @@ def f(): # 11
finally: finally:
print() print()
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 11); assert_eq!(num_statements(&stmts), 11);
Ok(()) Ok(())
} }
@ -448,7 +449,7 @@ def f(): # 2
for i in range(10): for i in range(10):
yield i yield i
"#; "#;
let stmts = parser::parse_program(source, "<filename>")?; let stmts = Suite::parse(source, "<filename>")?;
assert_eq!(num_statements(&stmts), 2); assert_eq!(num_statements(&stmts), 2);
Ok(()) Ok(())
} }

View file

@ -2,10 +2,10 @@ use std::time::Duration;
use criterion::measurement::WallTime; use criterion::measurement::WallTime;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use rustpython_parser::ast::Stmt;
use ruff_benchmark::{TestCase, TestCaseSpeed, TestFile, TestFileDownloadError}; use ruff_benchmark::{TestCase, TestCaseSpeed, TestFile, TestFileDownloadError};
use ruff_python_ast::statement_visitor::{walk_stmt, StatementVisitor}; use ruff_python_ast::statement_visitor::{walk_stmt, StatementVisitor};
use rustpython_parser::ast::{Stmt, Suite};
use rustpython_parser::Parse;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
#[global_allocator] #[global_allocator]
@ -66,8 +66,7 @@ fn benchmark_parser(criterion: &mut Criterion<WallTime>) {
&case, &case,
|b, case| { |b, case| {
b.iter(|| { b.iter(|| {
let parsed = let parsed = Suite::parse(case.code(), case.name()).unwrap();
rustpython_parser::parse_program(case.code(), case.name()).unwrap();
let mut visitor = CountVisitor { count: 0 }; let mut visitor = CountVisitor { count: 0 };
visitor.visit_body(&parsed); visitor.visit_body(&parsed);

View file

@ -5,7 +5,8 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::Result; use anyhow::Result;
use rustpython_parser as parser; use rustpython_parser::ast::Suite;
use rustpython_parser::Parse;
#[derive(clap::Args)] #[derive(clap::Args)]
pub(crate) struct Args { pub(crate) struct Args {
@ -16,7 +17,7 @@ pub(crate) struct Args {
pub(crate) fn main(args: &Args) -> Result<()> { pub(crate) fn main(args: &Args) -> Result<()> {
let contents = fs::read_to_string(&args.file)?; let contents = fs::read_to_string(&args.file)?;
let python_ast = parser::parse_program(&contents, &args.file.to_string_lossy())?; let python_ast = Suite::parse(&contents, &args.file.to_string_lossy())?;
println!("{python_ast:#?}"); println!("{python_ast:#?}");
Ok(()) Ok(())
} }

View file

@ -1596,8 +1596,9 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use ruff_text_size::{TextLen, TextRange, TextSize}; use ruff_text_size::{TextLen, TextRange, TextSize};
use rustpython_parser as parser; use rustpython_ast::Suite;
use rustpython_parser::ast::Cmpop; use rustpython_parser::ast::Cmpop;
use rustpython_parser::Parse;
use crate::helpers::{ use crate::helpers::{
elif_else_range, else_range, first_colon_range, has_trailing_content, identifier_range, elif_else_range, else_range, first_colon_range, has_trailing_content, identifier_range,
@ -1608,25 +1609,25 @@ mod tests {
#[test] #[test]
fn trailing_content() -> Result<()> { fn trailing_content() -> Result<()> {
let contents = "x = 1"; let contents = "x = 1";
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert!(!has_trailing_content(stmt, &locator)); assert!(!has_trailing_content(stmt, &locator));
let contents = "x = 1; y = 2"; let contents = "x = 1; y = 2";
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert!(has_trailing_content(stmt, &locator)); assert!(has_trailing_content(stmt, &locator));
let contents = "x = 1 "; let contents = "x = 1 ";
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert!(!has_trailing_content(stmt, &locator)); assert!(!has_trailing_content(stmt, &locator));
let contents = "x = 1 # Comment"; let contents = "x = 1 # Comment";
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert!(!has_trailing_content(stmt, &locator)); assert!(!has_trailing_content(stmt, &locator));
@ -1636,7 +1637,7 @@ x = 1
y = 2 y = 2
"# "#
.trim(); .trim();
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert!(!has_trailing_content(stmt, &locator)); assert!(!has_trailing_content(stmt, &locator));
@ -1647,7 +1648,7 @@ y = 2
#[test] #[test]
fn extract_identifier_range() -> Result<()> { fn extract_identifier_range() -> Result<()> {
let contents = "def f(): pass".trim(); let contents = "def f(): pass".trim();
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert_eq!( assert_eq!(
@ -1661,7 +1662,7 @@ def \
pass pass
"# "#
.trim(); .trim();
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert_eq!( assert_eq!(
@ -1670,7 +1671,7 @@ def \
); );
let contents = "class Class(): pass".trim(); let contents = "class Class(): pass".trim();
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert_eq!( assert_eq!(
@ -1679,7 +1680,7 @@ def \
); );
let contents = "class Class: pass".trim(); let contents = "class Class: pass".trim();
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert_eq!( assert_eq!(
@ -1693,7 +1694,7 @@ class Class():
pass pass
"# "#
.trim(); .trim();
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert_eq!( assert_eq!(
@ -1702,7 +1703,7 @@ class Class():
); );
let contents = r#"x = y + 1"#.trim(); let contents = r#"x = y + 1"#.trim();
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
assert_eq!( assert_eq!(
@ -1759,7 +1760,7 @@ else:
pass pass
"# "#
.trim(); .trim();
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
let range = else_range(stmt, &locator).unwrap(); let range = else_range(stmt, &locator).unwrap();
@ -1793,7 +1794,7 @@ elif b:
... ...
" "
.trim_start(); .trim_start();
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
let range = elif_else_range(stmt, &locator).unwrap(); let range = elif_else_range(stmt, &locator).unwrap();
@ -1807,7 +1808,7 @@ else:
... ...
" "
.trim_start(); .trim_start();
let program = parser::parse_program(contents, "<filename>")?; let program = Suite::parse(contents, "<filename>")?;
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let locator = Locator::new(contents); let locator = Locator::new(contents);
let range = elif_else_range(stmt, &locator).unwrap(); let range = elif_else_range(stmt, &locator).unwrap();

View file

@ -1456,7 +1456,8 @@ impl<'a> Generator<'a> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use rustpython_parser as parser; use rustpython_ast::Suite;
use rustpython_parser::Parse;
use crate::newlines::LineEnding; use crate::newlines::LineEnding;
use crate::source_code::stylist::{Indentation, Quote}; use crate::source_code::stylist::{Indentation, Quote};
@ -1466,7 +1467,7 @@ mod tests {
let indentation = Indentation::default(); let indentation = Indentation::default();
let quote = Quote::default(); let quote = Quote::default();
let line_ending = LineEnding::default(); let line_ending = LineEnding::default();
let program = parser::parse_program(contents, "<filename>").unwrap(); let program = Suite::parse(contents, "<filename>").unwrap();
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let mut generator = Generator::new(&indentation, quote, line_ending); let mut generator = Generator::new(&indentation, quote, line_ending);
generator.unparse_stmt(stmt); generator.unparse_stmt(stmt);
@ -1479,7 +1480,7 @@ mod tests {
line_ending: LineEnding, line_ending: LineEnding,
contents: &str, contents: &str,
) -> String { ) -> String {
let program = parser::parse_program(contents, "<filename>").unwrap(); let program = Suite::parse(contents, "<filename>").unwrap();
let stmt = program.first().unwrap(); let stmt = program.first().unwrap();
let mut generator = Generator::new(indentation, quote, line_ending); let mut generator = Generator::new(indentation, quote, line_ending);
generator.unparse_stmt(stmt); generator.unparse_stmt(stmt);

View file

@ -3,8 +3,7 @@ use std::fmt::{Debug, Formatter};
use std::sync::Arc; use std::sync::Arc;
use ruff_text_size::{TextRange, TextSize}; use ruff_text_size::{TextRange, TextSize};
use rustpython_parser as parser; use rustpython_parser::{ast, lexer, Mode, Parse, ParseError};
use rustpython_parser::{lexer, Mode, ParseError};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -26,7 +25,7 @@ mod stylist;
/// Run round-trip source code generation on a given Python code. /// Run round-trip source code generation on a given Python code.
pub fn round_trip(code: &str, source_path: &str) -> Result<String, ParseError> { pub fn round_trip(code: &str, source_path: &str) -> Result<String, ParseError> {
let locator = Locator::new(code); let locator = Locator::new(code);
let python_ast = parser::parse_program(code, source_path)?; let python_ast = ast::Suite::parse(code, source_path)?;
let tokens: Vec<_> = lexer::lex(code, Mode::Module).collect(); let tokens: Vec<_> = lexer::lex(code, Mode::Module).collect();
let stylist = Stylist::from_tokens(&tokens, &locator); let stylist = Stylist::from_tokens(&tokens, &locator);
let mut generator: Generator = (&stylist).into(); let mut generator: Generator = (&stylist).into();

View file

@ -1,7 +1,7 @@
use anyhow::Result; use anyhow::Result;
use ruff_text_size::{TextLen, TextRange}; use ruff_text_size::{TextLen, TextRange};
use rustpython_parser as parser;
use rustpython_parser::ast::Expr; use rustpython_parser::ast::Expr;
use rustpython_parser::Parse;
use crate::relocate::relocate_expr; use crate::relocate::relocate_expr;
use crate::source_code::Locator; use crate::source_code::Locator;
@ -35,7 +35,7 @@ pub fn parse_type_annotation(
// isn't the case, e.g., for implicit concatenations, or for annotations that contain // isn't the case, e.g., for implicit concatenations, or for annotations that contain
// escaped quotes. // escaped quotes.
let leading_quote = str::leading_quote(expression).unwrap(); let leading_quote = str::leading_quote(expression).unwrap();
let expr = parser::parse_expression_starts_at( let expr = Expr::parse_starts_at(
value, value,
"<filename>", "<filename>",
range.start() + leading_quote.text_len(), range.start() + leading_quote.text_len(),
@ -43,7 +43,7 @@ pub fn parse_type_annotation(
Ok((expr, AnnotationKind::Simple)) Ok((expr, AnnotationKind::Simple))
} else { } else {
// Otherwise, consider this a "complex" annotation. // Otherwise, consider this a "complex" annotation.
let mut expr = parser::parse_expression(value, "<filename>")?; let mut expr = Expr::parse(value, "<filename>")?;
relocate_expr(&mut expr, range); relocate_expr(&mut expr, range);
Ok((expr, AnnotationKind::Complex)) Ok((expr, AnnotationKind::Complex))
} }

View file

@ -214,6 +214,7 @@ break;
continue_statement.as_ref().into(), continue_statement.as_ref().into(),
SourceComment { SourceComment {
slice: source_code.slice(TextRange::at(TextSize::new(0), TextSize::new(17))), slice: source_code.slice(TextRange::at(TextSize::new(0), TextSize::new(17))),
#[cfg(debug_assertions)]
formatted: Cell::new(false), formatted: Cell::new(false),
position: CommentTextPosition::OwnLine, position: CommentTextPosition::OwnLine,
}, },
@ -223,6 +224,7 @@ break;
continue_statement.as_ref().into(), continue_statement.as_ref().into(),
SourceComment { SourceComment {
slice: source_code.slice(TextRange::at(TextSize::new(28), TextSize::new(10))), slice: source_code.slice(TextRange::at(TextSize::new(28), TextSize::new(10))),
#[cfg(debug_assertions)]
formatted: Cell::new(false), formatted: Cell::new(false),
position: CommentTextPosition::EndOfLine, position: CommentTextPosition::EndOfLine,
}, },
@ -232,6 +234,7 @@ break;
break_statement.as_ref().into(), break_statement.as_ref().into(),
SourceComment { SourceComment {
slice: source_code.slice(TextRange::at(TextSize::new(39), TextSize::new(15))), slice: source_code.slice(TextRange::at(TextSize::new(39), TextSize::new(15))),
#[cfg(debug_assertions)]
formatted: Cell::new(false), formatted: Cell::new(false),
position: CommentTextPosition::OwnLine, position: CommentTextPosition::OwnLine,
}, },