mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-02 18:02:23 +00:00
Update to Rust 1.74 and use new clippy lints table (#8722)
Update to [Rust 1.74](https://blog.rust-lang.org/2023/11/16/Rust-1.74.0.html) and use the new clippy lints table. The update itself introduced a new clippy lint about superfluous hashes in raw strings, which got removed. I moved our lint config from `rustflags` to the newly stabilized [workspace.lints](https://doc.rust-lang.org/stable/cargo/reference/workspaces.html#the-lints-table). One consequence is that we have to `unsafe_code = "warn"` instead of "forbid" because the latter now actually bans unsafe code: ``` error[E0453]: allow(unsafe_code) incompatible with previous forbid --> crates/ruff_source_file/src/newlines.rs:62:17 | 62 | #[allow(unsafe_code)] | ^^^^^^^^^^^ overruled by previous forbid | = note: `forbid` lint level was set on command line ``` --------- Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
This commit is contained in:
parent
6d5d079a18
commit
14e65afdc6
71 changed files with 1124 additions and 1054 deletions
|
@ -1,37 +1,3 @@
|
||||||
[alias]
|
[alias]
|
||||||
dev = "run --package ruff_dev --bin ruff_dev"
|
dev = "run --package ruff_dev --bin ruff_dev"
|
||||||
benchmark = "bench -p ruff_benchmark --bench linter --bench formatter --"
|
benchmark = "bench -p ruff_benchmark --bench linter --bench formatter --"
|
||||||
|
|
||||||
[target.'cfg(all())']
|
|
||||||
rustflags = [
|
|
||||||
# CLIPPY LINT SETTINGS
|
|
||||||
# This is a workaround to configure lints for the entire workspace, pending the ability to configure this via TOML.
|
|
||||||
# See: `https://github.com/rust-lang/cargo/issues/5034`
|
|
||||||
# `https://github.com/EmbarkStudios/rust-ecosystem/issues/22#issuecomment-947011395`
|
|
||||||
"-Dunsafe_code",
|
|
||||||
"-Wclippy::pedantic",
|
|
||||||
# Allowed pedantic lints
|
|
||||||
"-Wclippy::char_lit_as_u8",
|
|
||||||
"-Aclippy::collapsible_else_if",
|
|
||||||
"-Aclippy::collapsible_if",
|
|
||||||
"-Aclippy::implicit_hasher",
|
|
||||||
"-Aclippy::match_same_arms",
|
|
||||||
"-Aclippy::missing_errors_doc",
|
|
||||||
"-Aclippy::missing_panics_doc",
|
|
||||||
"-Aclippy::module_name_repetitions",
|
|
||||||
"-Aclippy::must_use_candidate",
|
|
||||||
"-Aclippy::similar_names",
|
|
||||||
"-Aclippy::too_many_lines",
|
|
||||||
# Disallowed restriction lints
|
|
||||||
"-Wclippy::print_stdout",
|
|
||||||
"-Wclippy::print_stderr",
|
|
||||||
"-Wclippy::dbg_macro",
|
|
||||||
"-Wclippy::empty_drop",
|
|
||||||
"-Wclippy::empty_structs_with_brackets",
|
|
||||||
"-Wclippy::exit",
|
|
||||||
"-Wclippy::get_unwrap",
|
|
||||||
"-Wclippy::rc_buffer",
|
|
||||||
"-Wclippy::rc_mutex",
|
|
||||||
"-Wclippy::rest_pat_in_fully_bound_structs",
|
|
||||||
"-Wunreachable_pub"
|
|
||||||
]
|
|
||||||
|
|
32
Cargo.toml
32
Cargo.toml
|
@ -55,6 +55,38 @@ unicode-width = { version = "0.1.11" }
|
||||||
uuid = { version = "1.5.0", features = ["v4", "fast-rng", "macro-diagnostics", "js"] }
|
uuid = { version = "1.5.0", features = ["v4", "fast-rng", "macro-diagnostics", "js"] }
|
||||||
wsl = { version = "0.1.0" }
|
wsl = { version = "0.1.0" }
|
||||||
|
|
||||||
|
[workspace.lints.rust]
|
||||||
|
unsafe_code = "warn"
|
||||||
|
unreachable_pub = "warn"
|
||||||
|
|
||||||
|
[workspace.lints.clippy]
|
||||||
|
pedantic = { level = "warn", priority = -2 }
|
||||||
|
# Allowed pedantic lints
|
||||||
|
char_lit_as_u8 = "allow"
|
||||||
|
collapsible_else_if = "allow"
|
||||||
|
collapsible_if = "allow"
|
||||||
|
implicit_hasher = "allow"
|
||||||
|
match_same_arms = "allow"
|
||||||
|
missing_errors_doc = "allow"
|
||||||
|
missing_panics_doc = "allow"
|
||||||
|
module_name_repetitions = "allow"
|
||||||
|
must_use_candidate = "allow"
|
||||||
|
similar_names = "allow"
|
||||||
|
too_many_lines = "allow"
|
||||||
|
# To allow `#[allow(clippy::all)]` in `crates/ruff_python_parser/src/python.rs`.
|
||||||
|
needless_raw_string_hashes = "allow"
|
||||||
|
# Disallowed restriction lints
|
||||||
|
print_stdout = "warn"
|
||||||
|
print_stderr = "warn"
|
||||||
|
dbg_macro = "warn"
|
||||||
|
empty_drop = "warn"
|
||||||
|
empty_structs_with_brackets = "warn"
|
||||||
|
exit = "warn"
|
||||||
|
get_unwrap = "warn"
|
||||||
|
rc_buffer = "warn"
|
||||||
|
rc_mutex = "warn"
|
||||||
|
rest_pat_in_fully_bound_structs = "warn"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = "fat"
|
lto = "fat"
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
|
|
@ -34,3 +34,6 @@ toml = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "1.3.0"
|
pretty_assertions = "1.3.0"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -46,6 +46,9 @@ ruff_python_formatter = { path = "../ruff_python_formatter" }
|
||||||
ruff_python_index = { path = "../ruff_python_index" }
|
ruff_python_index = { path = "../ruff_python_index" }
|
||||||
ruff_python_parser = { path = "../ruff_python_parser" }
|
ruff_python_parser = { path = "../ruff_python_parser" }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
codspeed = ["codspeed-criterion-compat"]
|
codspeed = ["codspeed-criterion-compat"]
|
||||||
|
|
||||||
|
|
|
@ -20,3 +20,6 @@ seahash = "4.1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ruff_macros = { path = "../ruff_macros" }
|
ruff_macros = { path = "../ruff_macros" }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -76,3 +76,6 @@ mimalloc = "0.1.39"
|
||||||
|
|
||||||
[target.'cfg(all(not(target_os = "windows"), not(target_os = "openbsd"), any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "powerpc64")))'.dependencies]
|
[target.'cfg(all(not(target_os = "windows"), not(target_os = "openbsd"), any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "powerpc64")))'.dependencies]
|
||||||
tikv-jemallocator = "0.5.0"
|
tikv-jemallocator = "0.5.0"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -202,12 +202,12 @@ fn lint_path(
|
||||||
match result {
|
match result {
|
||||||
Ok(inner) => inner,
|
Ok(inner) => inner,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let message = r#"This indicates a bug in Ruff. If you could open an issue at:
|
let message = r"This indicates a bug in Ruff. If you could open an issue at:
|
||||||
|
|
||||||
https://github.com/astral-sh/ruff/issues/new?title=%5BLinter%20panic%5D
|
https://github.com/astral-sh/ruff/issues/new?title=%5BLinter%20panic%5D
|
||||||
|
|
||||||
...with the relevant file contents, the `pyproject.toml` settings, and the following stack trace, we'd be very appreciative!
|
...with the relevant file contents, the `pyproject.toml` settings, and the following stack trace, we'd be very appreciative!
|
||||||
"#;
|
";
|
||||||
|
|
||||||
error!(
|
error!(
|
||||||
"{}{}{} {message}\n{error}",
|
"{}{}{} {message}\n{error}",
|
||||||
|
|
|
@ -660,12 +660,12 @@ impl Display for FormatCommandError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Panic(path, err) => {
|
Self::Panic(path, err) => {
|
||||||
let message = r#"This indicates a bug in Ruff. If you could open an issue at:
|
let message = r"This indicates a bug in Ruff. If you could open an issue at:
|
||||||
|
|
||||||
https://github.com/astral-sh/ruff/issues/new?title=%5BFormatter%20panic%5D
|
https://github.com/astral-sh/ruff/issues/new?title=%5BFormatter%20panic%5D
|
||||||
|
|
||||||
...with the relevant file contents, the `pyproject.toml` settings, and the following stack trace, we'd be very appreciative!
|
...with the relevant file contents, the `pyproject.toml` settings, and the following stack trace, we'd be very appreciative!
|
||||||
"#;
|
";
|
||||||
if let Some(path) = path {
|
if let Some(path) = path {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
|
|
@ -63,7 +63,7 @@ fn format_rule_text(rule: Rule) -> String {
|
||||||
|
|
||||||
if rule.is_preview() || rule.is_nursery() {
|
if rule.is_preview() || rule.is_nursery() {
|
||||||
output.push_str(
|
output.push_str(
|
||||||
r#"This rule is in preview and is not stable. The `--preview` flag is required for use."#,
|
r"This rule is in preview and is not stable. The `--preview` flag is required for use.",
|
||||||
);
|
);
|
||||||
output.push('\n');
|
output.push('\n');
|
||||||
output.push('\n');
|
output.push('\n');
|
||||||
|
|
|
@ -395,9 +395,9 @@ fn deprecated_options() -> Result<()> {
|
||||||
let ruff_toml = tempdir.path().join("ruff.toml");
|
let ruff_toml = tempdir.path().join("ruff.toml");
|
||||||
fs::write(
|
fs::write(
|
||||||
&ruff_toml,
|
&ruff_toml,
|
||||||
r#"
|
r"
|
||||||
tab-size = 2
|
tab-size = 2
|
||||||
"#,
|
",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
insta::with_settings!({filters => vec![
|
insta::with_settings!({filters => vec![
|
||||||
|
@ -407,10 +407,10 @@ tab-size = 2
|
||||||
.args(["format", "--config"])
|
.args(["format", "--config"])
|
||||||
.arg(&ruff_toml)
|
.arg(&ruff_toml)
|
||||||
.arg("-")
|
.arg("-")
|
||||||
.pass_stdin(r#"
|
.pass_stdin(r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#), @r###"
|
"), @r###"
|
||||||
success: true
|
success: true
|
||||||
exit_code: 0
|
exit_code: 0
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
@ -443,9 +443,9 @@ format = "json"
|
||||||
.args(["check", "--select", "F401", "--no-cache", "--config"])
|
.args(["check", "--select", "F401", "--no-cache", "--config"])
|
||||||
.arg(&ruff_toml)
|
.arg(&ruff_toml)
|
||||||
.arg("-")
|
.arg("-")
|
||||||
.pass_stdin(r#"
|
.pass_stdin(r"
|
||||||
import os
|
import os
|
||||||
"#), @r###"
|
"), @r###"
|
||||||
success: false
|
success: false
|
||||||
exit_code: 2
|
exit_code: 2
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
|
@ -48,9 +48,12 @@ tracing-indicatif = { workspace = true }
|
||||||
tracing-subscriber = { workspace = true, features = ["env-filter"] }
|
tracing-subscriber = { workspace = true, features = ["env-filter"] }
|
||||||
imara-diff = "0.1.5"
|
imara-diff = "0.1.5"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
indoc = "2.0.4"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# Turn off rayon for profiling
|
# Turn off rayon for profiling
|
||||||
singlethreaded = []
|
singlethreaded = []
|
||||||
|
|
||||||
[dev-dependencies]
|
[lints]
|
||||||
indoc = "2.0.4"
|
workspace = true
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub(crate) fn main(args: &Args) -> Result<()> {
|
||||||
|
|
||||||
if rule.is_preview() || rule.is_nursery() {
|
if rule.is_preview() || rule.is_nursery() {
|
||||||
output.push_str(
|
output.push_str(
|
||||||
r#"This rule is unstable and in [preview](../preview.md). The `--preview` flag is required for use."#,
|
r"This rule is unstable and in [preview](../preview.md). The `--preview` flag is required for use.",
|
||||||
);
|
);
|
||||||
output.push('\n');
|
output.push('\n');
|
||||||
output.push('\n');
|
output.push('\n');
|
||||||
|
|
|
@ -29,3 +29,6 @@ insta = { workspace = true }
|
||||||
[features]
|
[features]
|
||||||
serde = ["dep:serde", "ruff_text_size/serde"]
|
serde = ["dep:serde", "ruff_text_size/serde"]
|
||||||
schemars = ["dep:schemars", "ruff_text_size/schemars"]
|
schemars = ["dep:schemars", "ruff_text_size/schemars"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -1711,14 +1711,14 @@ mod tests {
|
||||||
));
|
));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
r#"a
|
"a
|
||||||
b
|
b
|
||||||
c
|
c
|
||||||
d
|
d
|
||||||
d
|
d
|
||||||
c
|
c
|
||||||
b
|
b
|
||||||
a"#,
|
a",
|
||||||
formatted.as_code()
|
formatted.as_code()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2047,10 +2047,10 @@ two lines`,
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
printed.as_code(),
|
printed.as_code(),
|
||||||
r#"Group with id-2
|
"Group with id-2
|
||||||
Group with id-1 does not fit on the line because it exceeds the line width of 80 characters by
|
Group with id-1 does not fit on the line because it exceeds the line width of 80 characters by
|
||||||
Group 2 fits
|
Group 2 fits
|
||||||
Group 1 breaks"#
|
Group 1 breaks"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,3 +17,6 @@ ruff_macros = { path = "../ruff_macros" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
static_assertions = "1.1.0"
|
static_assertions = "1.1.0"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -86,3 +86,6 @@ default = []
|
||||||
schemars = ["dep:schemars"]
|
schemars = ["dep:schemars"]
|
||||||
# Enables the UnreachableCode rule
|
# Enables the UnreachableCode rule
|
||||||
unreachable-code = []
|
unreachable-code = []
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -171,7 +171,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn empty_file() {
|
fn empty_file() {
|
||||||
let locator = Locator::new(r#""#);
|
let locator = Locator::new(r"");
|
||||||
let diagnostics = create_diagnostics([]);
|
let diagnostics = create_diagnostics([]);
|
||||||
let FixResult {
|
let FixResult {
|
||||||
code,
|
code,
|
||||||
|
@ -225,10 +225,10 @@ print("hello world")
|
||||||
#[test]
|
#[test]
|
||||||
fn apply_one_replacement() {
|
fn apply_one_replacement() {
|
||||||
let locator = Locator::new(
|
let locator = Locator::new(
|
||||||
r#"
|
r"
|
||||||
class A(object):
|
class A(object):
|
||||||
...
|
...
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
);
|
);
|
||||||
let diagnostics = create_diagnostics([Edit::replacement(
|
let diagnostics = create_diagnostics([Edit::replacement(
|
||||||
|
@ -243,10 +243,10 @@ class A(object):
|
||||||
} = apply_fixes(diagnostics.iter(), &locator);
|
} = apply_fixes(diagnostics.iter(), &locator);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
code,
|
code,
|
||||||
r#"
|
r"
|
||||||
class A(Bar):
|
class A(Bar):
|
||||||
...
|
...
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
);
|
);
|
||||||
assert_eq!(fixes.values().sum::<usize>(), 1);
|
assert_eq!(fixes.values().sum::<usize>(), 1);
|
||||||
|
@ -262,10 +262,10 @@ class A(Bar):
|
||||||
#[test]
|
#[test]
|
||||||
fn apply_one_removal() {
|
fn apply_one_removal() {
|
||||||
let locator = Locator::new(
|
let locator = Locator::new(
|
||||||
r#"
|
r"
|
||||||
class A(object):
|
class A(object):
|
||||||
...
|
...
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
);
|
);
|
||||||
let diagnostics = create_diagnostics([Edit::deletion(TextSize::new(7), TextSize::new(15))]);
|
let diagnostics = create_diagnostics([Edit::deletion(TextSize::new(7), TextSize::new(15))]);
|
||||||
|
@ -276,10 +276,10 @@ class A(object):
|
||||||
} = apply_fixes(diagnostics.iter(), &locator);
|
} = apply_fixes(diagnostics.iter(), &locator);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
code,
|
code,
|
||||||
r#"
|
r"
|
||||||
class A:
|
class A:
|
||||||
...
|
...
|
||||||
"#
|
"
|
||||||
.trim()
|
.trim()
|
||||||
);
|
);
|
||||||
assert_eq!(fixes.values().sum::<usize>(), 1);
|
assert_eq!(fixes.values().sum::<usize>(), 1);
|
||||||
|
@ -295,10 +295,10 @@ class A:
|
||||||
#[test]
|
#[test]
|
||||||
fn apply_two_removals() {
|
fn apply_two_removals() {
|
||||||
let locator = Locator::new(
|
let locator = Locator::new(
|
||||||
r#"
|
r"
|
||||||
class A(object, object, object):
|
class A(object, object, object):
|
||||||
...
|
...
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
);
|
);
|
||||||
let diagnostics = create_diagnostics([
|
let diagnostics = create_diagnostics([
|
||||||
|
@ -313,10 +313,10 @@ class A(object, object, object):
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
code,
|
code,
|
||||||
r#"
|
r"
|
||||||
class A(object):
|
class A(object):
|
||||||
...
|
...
|
||||||
"#
|
"
|
||||||
.trim()
|
.trim()
|
||||||
);
|
);
|
||||||
assert_eq!(fixes.values().sum::<usize>(), 2);
|
assert_eq!(fixes.values().sum::<usize>(), 2);
|
||||||
|
@ -334,10 +334,10 @@ class A(object):
|
||||||
#[test]
|
#[test]
|
||||||
fn ignore_overlapping_fixes() {
|
fn ignore_overlapping_fixes() {
|
||||||
let locator = Locator::new(
|
let locator = Locator::new(
|
||||||
r#"
|
r"
|
||||||
class A(object):
|
class A(object):
|
||||||
...
|
...
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
);
|
);
|
||||||
let diagnostics = create_diagnostics([
|
let diagnostics = create_diagnostics([
|
||||||
|
@ -351,10 +351,10 @@ class A(object):
|
||||||
} = apply_fixes(diagnostics.iter(), &locator);
|
} = apply_fixes(diagnostics.iter(), &locator);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
code,
|
code,
|
||||||
r#"
|
r"
|
||||||
class A:
|
class A:
|
||||||
...
|
...
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
);
|
);
|
||||||
assert_eq!(fixes.values().sum::<usize>(), 1);
|
assert_eq!(fixes.values().sum::<usize>(), 1);
|
||||||
|
|
|
@ -373,18 +373,18 @@ mod tests {
|
||||||
Insertion::own_line("", TextSize::from(40), "\n")
|
Insertion::own_line("", TextSize::from(40), "\n")
|
||||||
);
|
);
|
||||||
|
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
x = 1
|
x = 1
|
||||||
"#
|
"
|
||||||
.trim_start();
|
.trim_start();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
insert(contents)?,
|
insert(contents)?,
|
||||||
Insertion::own_line("", TextSize::from(0), "\n")
|
Insertion::own_line("", TextSize::from(0), "\n")
|
||||||
);
|
);
|
||||||
|
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"#
|
"
|
||||||
.trim_start();
|
.trim_start();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
insert(contents)?,
|
insert(contents)?,
|
||||||
|
@ -457,10 +457,10 @@ x = 1
|
||||||
Insertion::inline("", TextSize::from(9), "; ")
|
Insertion::inline("", TextSize::from(9), "; ")
|
||||||
);
|
);
|
||||||
|
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
.trim_start();
|
.trim_start();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
insert(contents, TextSize::from(0)),
|
insert(contents, TextSize::from(0)),
|
||||||
|
|
|
@ -199,7 +199,7 @@ def fibonacci(n):
|
||||||
TextSize::from(99),
|
TextSize::from(99),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
let file_2 = r#"if a == 1: pass"#;
|
let file_2 = r"if a == 1: pass";
|
||||||
|
|
||||||
let undefined_name = Diagnostic::new(
|
let undefined_name = Diagnostic::new(
|
||||||
DiagnosticKind {
|
DiagnosticKind {
|
||||||
|
|
|
@ -12,11 +12,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn notice() {
|
fn notice() {
|
||||||
let diagnostics = test_snippet(
|
let diagnostics = test_snippet(
|
||||||
r#"
|
r"
|
||||||
# Copyright 2023
|
# Copyright 2023
|
||||||
|
|
||||||
import os
|
import os
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
||||||
);
|
);
|
||||||
|
@ -26,11 +26,11 @@ import os
|
||||||
#[test]
|
#[test]
|
||||||
fn notice_with_c() {
|
fn notice_with_c() {
|
||||||
let diagnostics = test_snippet(
|
let diagnostics = test_snippet(
|
||||||
r#"
|
r"
|
||||||
# Copyright (C) 2023
|
# Copyright (C) 2023
|
||||||
|
|
||||||
import os
|
import os
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
||||||
);
|
);
|
||||||
|
@ -40,11 +40,11 @@ import os
|
||||||
#[test]
|
#[test]
|
||||||
fn notice_with_caps() {
|
fn notice_with_caps() {
|
||||||
let diagnostics = test_snippet(
|
let diagnostics = test_snippet(
|
||||||
r#"
|
r"
|
||||||
# COPYRIGHT (C) 2023
|
# COPYRIGHT (C) 2023
|
||||||
|
|
||||||
import os
|
import os
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
||||||
);
|
);
|
||||||
|
@ -54,11 +54,11 @@ import os
|
||||||
#[test]
|
#[test]
|
||||||
fn notice_with_range() {
|
fn notice_with_range() {
|
||||||
let diagnostics = test_snippet(
|
let diagnostics = test_snippet(
|
||||||
r#"
|
r"
|
||||||
# Copyright (C) 2021-2023
|
# Copyright (C) 2021-2023
|
||||||
|
|
||||||
import os
|
import os
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
||||||
);
|
);
|
||||||
|
@ -68,11 +68,11 @@ import os
|
||||||
#[test]
|
#[test]
|
||||||
fn valid_author() {
|
fn valid_author() {
|
||||||
let diagnostics = test_snippet(
|
let diagnostics = test_snippet(
|
||||||
r#"
|
r"
|
||||||
# Copyright (C) 2023 Ruff
|
# Copyright (C) 2023 Ruff
|
||||||
|
|
||||||
import os
|
import os
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
&settings::LinterSettings {
|
&settings::LinterSettings {
|
||||||
flake8_copyright: super::settings::Settings {
|
flake8_copyright: super::settings::Settings {
|
||||||
|
@ -88,11 +88,11 @@ import os
|
||||||
#[test]
|
#[test]
|
||||||
fn invalid_author() {
|
fn invalid_author() {
|
||||||
let diagnostics = test_snippet(
|
let diagnostics = test_snippet(
|
||||||
r#"
|
r"
|
||||||
# Copyright (C) 2023 Some Author
|
# Copyright (C) 2023 Some Author
|
||||||
|
|
||||||
import os
|
import os
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
&settings::LinterSettings {
|
&settings::LinterSettings {
|
||||||
flake8_copyright: super::settings::Settings {
|
flake8_copyright: super::settings::Settings {
|
||||||
|
@ -108,9 +108,9 @@ import os
|
||||||
#[test]
|
#[test]
|
||||||
fn small_file() {
|
fn small_file() {
|
||||||
let diagnostics = test_snippet(
|
let diagnostics = test_snippet(
|
||||||
r#"
|
r"
|
||||||
import os
|
import os
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
&settings::LinterSettings {
|
&settings::LinterSettings {
|
||||||
flake8_copyright: super::settings::Settings {
|
flake8_copyright: super::settings::Settings {
|
||||||
|
@ -126,7 +126,7 @@ import os
|
||||||
#[test]
|
#[test]
|
||||||
fn late_notice() {
|
fn late_notice() {
|
||||||
let diagnostics = test_snippet(
|
let diagnostics = test_snippet(
|
||||||
r#"
|
r"
|
||||||
# Content Content Content Content Content Content Content Content Content Content
|
# Content Content Content Content Content Content Content Content Content Content
|
||||||
# Content Content Content Content Content Content Content Content Content Content
|
# Content Content Content Content Content Content Content Content Content Content
|
||||||
# Content Content Content Content Content Content Content Content Content Content
|
# Content Content Content Content Content Content Content Content Content Content
|
||||||
|
@ -149,7 +149,7 @@ import os
|
||||||
# Content Content Content Content Content Content Content Content Content Content
|
# Content Content Content Content Content Content Content Content Content Content
|
||||||
|
|
||||||
# Copyright 2023
|
# Copyright 2023
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
||||||
);
|
);
|
||||||
|
@ -159,8 +159,8 @@ import os
|
||||||
#[test]
|
#[test]
|
||||||
fn char_boundary() {
|
fn char_boundary() {
|
||||||
let diagnostics = test_snippet(
|
let diagnostics = test_snippet(
|
||||||
r#"কককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককক
|
r"কককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককককক
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
|
||||||
);
|
);
|
||||||
|
|
|
@ -171,18 +171,18 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
def f(x: pd.DataFrame):
|
def f(x: pd.DataFrame):
|
||||||
pass
|
pass
|
||||||
"#,
|
",
|
||||||
"no_typing_import"
|
"no_typing_import"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
@ -191,11 +191,11 @@ mod tests {
|
||||||
|
|
||||||
def f(x: pd.DataFrame):
|
def f(x: pd.DataFrame):
|
||||||
pass
|
pass
|
||||||
"#,
|
",
|
||||||
"typing_import_before_package_import"
|
"typing_import_before_package_import"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
@ -204,11 +204,11 @@ mod tests {
|
||||||
|
|
||||||
def f(x: pd.DataFrame):
|
def f(x: pd.DataFrame):
|
||||||
pass
|
pass
|
||||||
"#,
|
",
|
||||||
"typing_import_after_package_import"
|
"typing_import_after_package_import"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
@ -217,11 +217,11 @@ mod tests {
|
||||||
pass
|
pass
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
"#,
|
",
|
||||||
"typing_import_after_usage"
|
"typing_import_after_usage"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
@ -233,11 +233,11 @@ mod tests {
|
||||||
|
|
||||||
def f(x: pd.DataFrame):
|
def f(x: pd.DataFrame):
|
||||||
pass
|
pass
|
||||||
"#,
|
",
|
||||||
"type_checking_block_own_line"
|
"type_checking_block_own_line"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
@ -248,11 +248,11 @@ mod tests {
|
||||||
|
|
||||||
def f(x: pd.DataFrame):
|
def f(x: pd.DataFrame):
|
||||||
pass
|
pass
|
||||||
"#,
|
",
|
||||||
"type_checking_block_inline"
|
"type_checking_block_inline"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
@ -265,11 +265,11 @@ mod tests {
|
||||||
|
|
||||||
def f(x: pd.DataFrame):
|
def f(x: pd.DataFrame):
|
||||||
pass
|
pass
|
||||||
"#,
|
",
|
||||||
"type_checking_block_comment"
|
"type_checking_block_comment"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
@ -281,11 +281,11 @@ mod tests {
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
import os
|
import os
|
||||||
"#,
|
",
|
||||||
"type_checking_block_after_usage"
|
"type_checking_block_after_usage"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from pandas import (
|
from pandas import (
|
||||||
|
@ -295,11 +295,11 @@ mod tests {
|
||||||
|
|
||||||
def f(x: DataFrame):
|
def f(x: DataFrame):
|
||||||
pass
|
pass
|
||||||
"#,
|
",
|
||||||
"import_from"
|
"import_from"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
@ -314,11 +314,11 @@ mod tests {
|
||||||
|
|
||||||
def f(x: DataFrame):
|
def f(x: DataFrame):
|
||||||
pass
|
pass
|
||||||
"#,
|
",
|
||||||
"import_from_type_checking_block"
|
"import_from_type_checking_block"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
@ -330,11 +330,11 @@ mod tests {
|
||||||
|
|
||||||
def f(x: DataFrame, y: Series):
|
def f(x: DataFrame, y: Series):
|
||||||
pass
|
pass
|
||||||
"#,
|
",
|
||||||
"multiple_members"
|
"multiple_members"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
@ -343,11 +343,11 @@ mod tests {
|
||||||
|
|
||||||
def f(x: os, y: sys):
|
def f(x: os, y: sys):
|
||||||
pass
|
pass
|
||||||
"#,
|
",
|
||||||
"multiple_modules_same_type"
|
"multiple_modules_same_type"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
@ -356,7 +356,7 @@ mod tests {
|
||||||
|
|
||||||
def f(x: os, y: pandas):
|
def f(x: os, y: pandas):
|
||||||
pass
|
pass
|
||||||
"#,
|
",
|
||||||
"multiple_modules_different_types"
|
"multiple_modules_different_types"
|
||||||
)]
|
)]
|
||||||
fn contents(contents: &str, snapshot: &str) {
|
fn contents(contents: &str, snapshot: &str) {
|
||||||
|
|
|
@ -166,10 +166,10 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn trivial() -> Result<()> {
|
fn trivial() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def trivial():
|
def trivial():
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 1);
|
assert_eq!(get_complexity_number(&stmts), 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -177,10 +177,10 @@ def trivial():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn expr_as_statement() -> Result<()> {
|
fn expr_as_statement() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def expr_as_statement():
|
def expr_as_statement():
|
||||||
0xF00D
|
0xF00D
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 1);
|
assert_eq!(get_complexity_number(&stmts), 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -188,12 +188,12 @@ def expr_as_statement():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sequential() -> Result<()> {
|
fn sequential() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def sequential(n):
|
def sequential(n):
|
||||||
k = n + 4
|
k = n + 4
|
||||||
s = k + n
|
s = k + n
|
||||||
return s
|
return s
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 1);
|
assert_eq!(get_complexity_number(&stmts), 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -234,11 +234,11 @@ def nested_ifs():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn for_loop() -> Result<()> {
|
fn for_loop() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def for_loop():
|
def for_loop():
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
print(i)
|
print(i)
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 2);
|
assert_eq!(get_complexity_number(&stmts), 2);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -246,13 +246,13 @@ def for_loop():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn for_else() -> Result<()> {
|
fn for_else() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def for_else(mylist):
|
def for_else(mylist):
|
||||||
for i in mylist:
|
for i in mylist:
|
||||||
print(i)
|
print(i)
|
||||||
else:
|
else:
|
||||||
print(None)
|
print(None)
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 2);
|
assert_eq!(get_complexity_number(&stmts), 2);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -260,13 +260,13 @@ def for_else(mylist):
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn recursive() -> Result<()> {
|
fn recursive() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def recursive(n):
|
def recursive(n):
|
||||||
if n > 4:
|
if n > 4:
|
||||||
return f(n - 1)
|
return f(n - 1)
|
||||||
else:
|
else:
|
||||||
return n
|
return n
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 2);
|
assert_eq!(get_complexity_number(&stmts), 2);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -274,7 +274,7 @@ def recursive(n):
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nested_functions() -> Result<()> {
|
fn nested_functions() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def nested_functions():
|
def nested_functions():
|
||||||
def a():
|
def a():
|
||||||
def b():
|
def b():
|
||||||
|
@ -283,7 +283,7 @@ def nested_functions():
|
||||||
b()
|
b()
|
||||||
|
|
||||||
a()
|
a()
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 3);
|
assert_eq!(get_complexity_number(&stmts), 3);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -291,7 +291,7 @@ def nested_functions():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn try_else() -> Result<()> {
|
fn try_else() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def try_else():
|
def try_else():
|
||||||
try:
|
try:
|
||||||
print(1)
|
print(1)
|
||||||
|
@ -301,7 +301,7 @@ def try_else():
|
||||||
print(3)
|
print(3)
|
||||||
else:
|
else:
|
||||||
print(4)
|
print(4)
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 4);
|
assert_eq!(get_complexity_number(&stmts), 4);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -309,7 +309,7 @@ def try_else():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nested_try_finally() -> Result<()> {
|
fn nested_try_finally() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def nested_try_finally():
|
def nested_try_finally():
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
|
@ -318,7 +318,7 @@ def nested_try_finally():
|
||||||
print(2)
|
print(2)
|
||||||
finally:
|
finally:
|
||||||
print(3)
|
print(3)
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 1);
|
assert_eq!(get_complexity_number(&stmts), 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -326,7 +326,7 @@ def nested_try_finally():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn foobar() -> Result<()> {
|
fn foobar() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
async def foobar(a, b, c):
|
async def foobar(a, b, c):
|
||||||
await whatever(a, b, c)
|
await whatever(a, b, c)
|
||||||
if await b:
|
if await b:
|
||||||
|
@ -335,7 +335,7 @@ async def foobar(a, b, c):
|
||||||
pass
|
pass
|
||||||
async for x in a:
|
async for x in a:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 3);
|
assert_eq!(get_complexity_number(&stmts), 3);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -343,10 +343,10 @@ async def foobar(a, b, c):
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn annotated_assign() -> Result<()> {
|
fn annotated_assign() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def annotated_assign():
|
def annotated_assign():
|
||||||
x: Any = None
|
x: Any = None
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 1);
|
assert_eq!(get_complexity_number(&stmts), 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -354,7 +354,7 @@ def annotated_assign():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn class() -> Result<()> {
|
fn class() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
class Class:
|
class Class:
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
if args:
|
if args:
|
||||||
|
@ -382,7 +382,7 @@ class Class:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return ServiceProvider(Logger())
|
return ServiceProvider(Logger())
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 9);
|
assert_eq!(get_complexity_number(&stmts), 9);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -390,13 +390,13 @@ class Class:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn finally() -> Result<()> {
|
fn finally() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def process_detect_lines():
|
def process_detect_lines():
|
||||||
try:
|
try:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 1);
|
assert_eq!(get_complexity_number(&stmts), 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -419,12 +419,12 @@ def process_detect_lines():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn with() -> Result<()> {
|
fn with() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def with_lock():
|
def with_lock():
|
||||||
with lock:
|
with lock:
|
||||||
if foo:
|
if foo:
|
||||||
print('bar')
|
print('bar')
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(get_complexity_number(&stmts), 2);
|
assert_eq!(get_complexity_number(&stmts), 2);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -30,17 +30,17 @@ mod tests {
|
||||||
"PD002_fail"
|
"PD002_fail"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
nas = pd.isna(val)
|
nas = pd.isna(val)
|
||||||
"#,
|
",
|
||||||
"PD003_pass"
|
"PD003_pass"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
nulls = pd.isnull(val)
|
nulls = pd.isnull(val)
|
||||||
"#,
|
",
|
||||||
"PD003_fail"
|
"PD003_fail"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
|
@ -51,17 +51,17 @@ mod tests {
|
||||||
"PD003_allows_other_calls"
|
"PD003_allows_other_calls"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
not_nas = pd.notna(val)
|
not_nas = pd.notna(val)
|
||||||
"#,
|
",
|
||||||
"PD004_pass"
|
"PD004_pass"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
not_nulls = pd.notnull(val)
|
not_nulls = pd.notnull(val)
|
||||||
"#,
|
",
|
||||||
"PD004_fail"
|
"PD004_fail"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
|
@ -73,11 +73,11 @@ mod tests {
|
||||||
"PD007_pass_loc"
|
"PD007_pass_loc"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
x = pd.DataFrame()
|
x = pd.DataFrame()
|
||||||
new_x = x.iloc[[1, 3, 5], [1, 3]]
|
new_x = x.iloc[[1, 3, 5], [1, 3]]
|
||||||
"#,
|
",
|
||||||
"PD007_pass_iloc"
|
"PD007_pass_iloc"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
|
@ -134,19 +134,19 @@ mod tests {
|
||||||
"PD008_fail"
|
"PD008_fail"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
x = pd.DataFrame()
|
x = pd.DataFrame()
|
||||||
index = x.iloc[:, 1:3]
|
index = x.iloc[:, 1:3]
|
||||||
"#,
|
",
|
||||||
"PD009_pass"
|
"PD009_pass"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
x = pd.DataFrame()
|
x = pd.DataFrame()
|
||||||
index = x.iat[:, 1:3]
|
index = x.iat[:, 1:3]
|
||||||
"#,
|
",
|
||||||
"PD009_fail"
|
"PD009_fail"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
|
@ -178,80 +178,80 @@ mod tests {
|
||||||
"PD010_fail_pivot"
|
"PD010_fail_pivot"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
x = pd.DataFrame()
|
x = pd.DataFrame()
|
||||||
result = x.to_array()
|
result = x.to_array()
|
||||||
"#,
|
",
|
||||||
"PD011_pass_to_array"
|
"PD011_pass_to_array"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
x = pd.DataFrame()
|
x = pd.DataFrame()
|
||||||
result = x.array
|
result = x.array
|
||||||
"#,
|
",
|
||||||
"PD011_pass_array"
|
"PD011_pass_array"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
x = pd.DataFrame()
|
x = pd.DataFrame()
|
||||||
result = x.values
|
result = x.values
|
||||||
"#,
|
",
|
||||||
"PD011_fail_values"
|
"PD011_fail_values"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
x = pd.DataFrame()
|
x = pd.DataFrame()
|
||||||
result = x.values()
|
result = x.values()
|
||||||
"#,
|
",
|
||||||
"PD011_pass_values_call"
|
"PD011_pass_values_call"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
x = pd.DataFrame()
|
x = pd.DataFrame()
|
||||||
x.values = 1
|
x.values = 1
|
||||||
"#,
|
",
|
||||||
"PD011_pass_values_store"
|
"PD011_pass_values_store"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
class Class:
|
class Class:
|
||||||
def __init__(self, values: str) -> None:
|
def __init__(self, values: str) -> None:
|
||||||
self.values = values
|
self.values = values
|
||||||
print(self.values)
|
print(self.values)
|
||||||
"#,
|
",
|
||||||
"PD011_pass_values_instance"
|
"PD011_pass_values_instance"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
result = {}.values
|
result = {}.values
|
||||||
"#,
|
",
|
||||||
"PD011_pass_values_dict"
|
"PD011_pass_values_dict"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
result = pd.values
|
result = pd.values
|
||||||
"#,
|
",
|
||||||
"PD011_pass_values_import"
|
"PD011_pass_values_import"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
result = x.values
|
result = x.values
|
||||||
"#,
|
",
|
||||||
"PD011_pass_values_unbound"
|
"PD011_pass_values_unbound"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
result = values
|
result = values
|
||||||
"#,
|
",
|
||||||
"PD011_pass_node_name"
|
"PD011_pass_node_name"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
|
@ -267,33 +267,33 @@ mod tests {
|
||||||
"PD013_pass"
|
"PD013_pass"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import numpy as np
|
import numpy as np
|
||||||
arrays = [np.random.randn(3, 4) for _ in range(10)]
|
arrays = [np.random.randn(3, 4) for _ in range(10)]
|
||||||
np.stack(arrays, axis=0).shape
|
np.stack(arrays, axis=0).shape
|
||||||
"#,
|
",
|
||||||
"PD013_pass_numpy"
|
"PD013_pass_numpy"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
y = x.stack(level=-1, dropna=True)
|
y = x.stack(level=-1, dropna=True)
|
||||||
"#,
|
",
|
||||||
"PD013_pass_unbound"
|
"PD013_pass_unbound"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
x = pd.DataFrame()
|
x = pd.DataFrame()
|
||||||
y = x.stack(level=-1, dropna=True)
|
y = x.stack(level=-1, dropna=True)
|
||||||
"#,
|
",
|
||||||
"PD013_fail_stack"
|
"PD013_fail_stack"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
pd.stack(
|
pd.stack(
|
||||||
"#,
|
",
|
||||||
"PD015_pass_merge_on_dataframe"
|
"PD015_pass_merge_on_dataframe"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
|
@ -306,12 +306,12 @@ mod tests {
|
||||||
"PD015_pass_merge_on_dataframe_with_multiple_args"
|
"PD015_pass_merge_on_dataframe_with_multiple_args"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
x = pd.DataFrame()
|
x = pd.DataFrame()
|
||||||
y = pd.DataFrame()
|
y = pd.DataFrame()
|
||||||
pd.merge(x, y)
|
pd.merge(x, y)
|
||||||
"#,
|
",
|
||||||
"PD015_fail_merge_on_pandas_object"
|
"PD015_fail_merge_on_pandas_object"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
|
@ -321,31 +321,31 @@ mod tests {
|
||||||
"PD015_pass_other_pd_function"
|
"PD015_pass_other_pd_function"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
employees = pd.DataFrame(employee_dict)
|
employees = pd.DataFrame(employee_dict)
|
||||||
"#,
|
",
|
||||||
"PD901_pass_non_df"
|
"PD901_pass_non_df"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
employees_df = pd.DataFrame(employee_dict)
|
employees_df = pd.DataFrame(employee_dict)
|
||||||
"#,
|
",
|
||||||
"PD901_pass_part_df"
|
"PD901_pass_part_df"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
my_function(df=data)
|
my_function(df=data)
|
||||||
"#,
|
",
|
||||||
"PD901_pass_df_param"
|
"PD901_pass_df_param"
|
||||||
)]
|
)]
|
||||||
#[test_case(
|
#[test_case(
|
||||||
r#"
|
r"
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
df = pd.DataFrame()
|
df = pd.DataFrame()
|
||||||
"#,
|
",
|
||||||
"PD901_fail_df_var"
|
"PD901_fail_df_var"
|
||||||
)]
|
)]
|
||||||
fn contents(contents: &str, snapshot: &str) {
|
fn contents(contents: &str, snapshot: &str) {
|
||||||
|
|
|
@ -518,10 +518,10 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn multi_line() {
|
fn multi_line() {
|
||||||
assert_logical_lines(
|
assert_logical_lines(
|
||||||
r#"
|
r"
|
||||||
x = 1
|
x = 1
|
||||||
y = 2
|
y = 2
|
||||||
z = x + 1"#
|
z = x + 1"
|
||||||
.trim(),
|
.trim(),
|
||||||
&["x = 1", "y = 2", "z = x + 1"],
|
&["x = 1", "y = 2", "z = x + 1"],
|
||||||
);
|
);
|
||||||
|
@ -530,14 +530,14 @@ z = x + 1"#
|
||||||
#[test]
|
#[test]
|
||||||
fn indented() {
|
fn indented() {
|
||||||
assert_logical_lines(
|
assert_logical_lines(
|
||||||
r#"
|
r"
|
||||||
x = [
|
x = [
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
3,
|
3,
|
||||||
]
|
]
|
||||||
y = 2
|
y = 2
|
||||||
z = x + 1"#
|
z = x + 1"
|
||||||
.trim(),
|
.trim(),
|
||||||
&["x = [\n 1,\n 2,\n 3,\n]", "y = 2", "z = x + 1"],
|
&["x = [\n 1,\n 2,\n 3,\n]", "y = 2", "z = x + 1"],
|
||||||
);
|
);
|
||||||
|
@ -551,11 +551,11 @@ z = x + 1"#
|
||||||
#[test]
|
#[test]
|
||||||
fn function_definition() {
|
fn function_definition() {
|
||||||
assert_logical_lines(
|
assert_logical_lines(
|
||||||
r#"
|
r"
|
||||||
def f():
|
def f():
|
||||||
x = 1
|
x = 1
|
||||||
f()"#
|
f()"
|
||||||
.trim(),
|
.trim(),
|
||||||
&["def f():", "x = 1", "f()"],
|
&["def f():", "x = 1", "f()"],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -583,11 +583,11 @@ f()"#
|
||||||
#[test]
|
#[test]
|
||||||
fn empty_line() {
|
fn empty_line() {
|
||||||
assert_logical_lines(
|
assert_logical_lines(
|
||||||
r#"
|
r"
|
||||||
if False:
|
if False:
|
||||||
|
|
||||||
print()
|
print()
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
&["if False:", "print()", ""],
|
&["if False:", "print()", ""],
|
||||||
);
|
);
|
||||||
|
|
|
@ -44,7 +44,7 @@ impl Violation for TripleSingleQuotes {
|
||||||
let TripleSingleQuotes { expected_quote } = self;
|
let TripleSingleQuotes { expected_quote } = self;
|
||||||
match expected_quote {
|
match expected_quote {
|
||||||
Quote::Double => format!(r#"Use triple double quotes `"""`"#),
|
Quote::Double => format!(r#"Use triple double quotes `"""`"#),
|
||||||
Quote::Single => format!(r#"Use triple single quotes `'''`"#),
|
Quote::Single => format!(r"Use triple single quotes `'''`"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -187,7 +187,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_else_nested_if_else() -> Result<()> {
|
fn if_else_nested_if_else() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
if x == 0: # 3
|
if x == 0: # 3
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
@ -195,19 +195,19 @@ else:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
test_helper(source, 4)?;
|
test_helper(source, 4)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn for_else() -> Result<()> {
|
fn for_else() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
for _ in range(x): # 2
|
for _ in range(x): # 2
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 2)?;
|
test_helper(source, 2)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -215,14 +215,14 @@ else:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn while_if_else_if() -> Result<()> {
|
fn while_if_else_if() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
while x < 1: # 4
|
while x < 1: # 4
|
||||||
if x:
|
if x:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if x:
|
if x:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 4)?;
|
test_helper(source, 4)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -230,7 +230,7 @@ else:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nested_def() -> Result<()> {
|
fn nested_def() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
if x: # 2
|
if x: # 2
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -241,7 +241,7 @@ def g(x):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 2)?;
|
test_helper(source, 2)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -249,7 +249,7 @@ return 1
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn try_except_except_else_finally() -> Result<()> {
|
fn try_except_except_else_finally() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
try:
|
try:
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
|
@ -260,7 +260,7 @@ else:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 5)?;
|
test_helper(source, 5)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -110,7 +110,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_() -> Result<()> {
|
fn if_() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
x = 1
|
x = 1
|
||||||
if x == 1: # 9
|
if x == 1: # 9
|
||||||
return
|
return
|
||||||
|
@ -130,7 +130,7 @@ if x == 8:
|
||||||
return
|
return
|
||||||
if x == 9:
|
if x == 9:
|
||||||
return
|
return
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 9)?;
|
test_helper(source, 9)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -138,12 +138,12 @@ if x == 9:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn for_else() -> Result<()> {
|
fn for_else() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
for _i in range(10):
|
for _i in range(10):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 2)?;
|
test_helper(source, 2)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -151,12 +151,12 @@ else:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn async_for_else() -> Result<()> {
|
fn async_for_else() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
async for _i in range(10):
|
async for _i in range(10):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 2)?;
|
test_helper(source, 2)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -164,7 +164,7 @@ else:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nested_def_ignored() -> Result<()> {
|
fn nested_def_ignored() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def f():
|
def f():
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ if x == 1:
|
||||||
print()
|
print()
|
||||||
else:
|
else:
|
||||||
print()
|
print()
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 0)?;
|
test_helper(source, 0)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -181,7 +181,7 @@ else:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn while_nested_if() -> Result<()> {
|
fn while_nested_if() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
x = 1
|
x = 1
|
||||||
while x < 10:
|
while x < 10:
|
||||||
print()
|
print()
|
||||||
|
@ -189,7 +189,7 @@ while x < 10:
|
||||||
return
|
return
|
||||||
x += 1
|
x += 1
|
||||||
return
|
return
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 2)?;
|
test_helper(source, 2)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -197,12 +197,12 @@ return
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn with_if() -> Result<()> {
|
fn with_if() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
with a as f:
|
with a as f:
|
||||||
return
|
return
|
||||||
if f == 1:
|
if f == 1:
|
||||||
return
|
return
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 2)?;
|
test_helper(source, 2)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -210,12 +210,12 @@ with a as f:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn async_with_if() -> Result<()> {
|
fn async_with_if() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
async with a as f:
|
async with a as f:
|
||||||
return
|
return
|
||||||
if f == 1:
|
if f == 1:
|
||||||
return
|
return
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 2)?;
|
test_helper(source, 2)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -223,7 +223,7 @@ async with a as f:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn try_except_except_else_finally() -> Result<()> {
|
fn try_except_except_else_finally() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
try:
|
try:
|
||||||
print()
|
print()
|
||||||
return
|
return
|
||||||
|
@ -235,7 +235,7 @@ else:
|
||||||
return
|
return
|
||||||
finally:
|
finally:
|
||||||
return
|
return
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 5)?;
|
test_helper(source, 5)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -243,14 +243,14 @@ finally:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn class_def_ignored() -> Result<()> {
|
fn class_def_ignored() -> Result<()> {
|
||||||
let source = r#"
|
let source = r"
|
||||||
class A:
|
class A:
|
||||||
def f(self):
|
def f(self):
|
||||||
return
|
return
|
||||||
|
|
||||||
def g(self):
|
def g(self):
|
||||||
return
|
return
|
||||||
"#;
|
";
|
||||||
|
|
||||||
test_helper(source, 0)?;
|
test_helper(source, 0)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -163,10 +163,10 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn pass() -> Result<()> {
|
fn pass() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 2);
|
assert_eq!(num_statements(&stmts), 2);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -174,13 +174,13 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_else() -> Result<()> {
|
fn if_else() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
if a:
|
if a:
|
||||||
print()
|
print()
|
||||||
else:
|
else:
|
||||||
print()
|
print()
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 5);
|
assert_eq!(num_statements(&stmts), 5);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -188,14 +188,14 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_else_if_corner() -> Result<()> {
|
fn if_else_if_corner() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
if a:
|
if a:
|
||||||
print()
|
print()
|
||||||
else:
|
else:
|
||||||
if a:
|
if a:
|
||||||
print()
|
print()
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 6);
|
assert_eq!(num_statements(&stmts), 6);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -203,13 +203,13 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_elif() -> Result<()> {
|
fn if_elif() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
if a:
|
if a:
|
||||||
print()
|
print()
|
||||||
elif a:
|
elif a:
|
||||||
print()
|
print()
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 5);
|
assert_eq!(num_statements(&stmts), 5);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -217,7 +217,7 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_elif_else() -> Result<()> {
|
fn if_elif_else() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
if a:
|
if a:
|
||||||
print()
|
print()
|
||||||
|
@ -227,7 +227,7 @@ def f():
|
||||||
print()
|
print()
|
||||||
else:
|
else:
|
||||||
print()
|
print()
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 9);
|
assert_eq!(num_statements(&stmts), 9);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -235,7 +235,7 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn many_statements() -> Result<()> {
|
fn many_statements() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
async def f():
|
async def f():
|
||||||
a = 1
|
a = 1
|
||||||
b = 2
|
b = 2
|
||||||
|
@ -256,7 +256,7 @@ async def f():
|
||||||
a -= 1
|
a -= 1
|
||||||
import time
|
import time
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 19);
|
assert_eq!(num_statements(&stmts), 19);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -264,11 +264,11 @@ async def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn for_() -> Result<()> {
|
fn for_() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 2);
|
assert_eq!(num_statements(&stmts), 2);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -276,13 +276,13 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn for_else() -> Result<()> {
|
fn for_else() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
print()
|
print()
|
||||||
else:
|
else:
|
||||||
print()
|
print()
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 3);
|
assert_eq!(num_statements(&stmts), 3);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -290,14 +290,14 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nested_def() -> Result<()> {
|
fn nested_def() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
def g():
|
def g():
|
||||||
print()
|
print()
|
||||||
print()
|
print()
|
||||||
|
|
||||||
print()
|
print()
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 5);
|
assert_eq!(num_statements(&stmts), 5);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -305,7 +305,7 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nested_class() -> Result<()> {
|
fn nested_class() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
class A:
|
class A:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -315,7 +315,7 @@ def f():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
print()
|
print()
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 3);
|
assert_eq!(num_statements(&stmts), 3);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -323,10 +323,10 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn return_not_counted() -> Result<()> {
|
fn return_not_counted() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
return
|
return
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 1);
|
assert_eq!(num_statements(&stmts), 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -334,7 +334,7 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn with() -> Result<()> {
|
fn with() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
with a:
|
with a:
|
||||||
if a:
|
if a:
|
||||||
|
@ -342,7 +342,7 @@ def f():
|
||||||
else:
|
else:
|
||||||
print()
|
print()
|
||||||
|
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 6);
|
assert_eq!(num_statements(&stmts), 6);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -350,13 +350,13 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn try_except() -> Result<()> {
|
fn try_except() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
try:
|
try:
|
||||||
print()
|
print()
|
||||||
except Exception:
|
except Exception:
|
||||||
raise
|
raise
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 5);
|
assert_eq!(num_statements(&stmts), 5);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -364,7 +364,7 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn try_except_else() -> Result<()> {
|
fn try_except_else() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
try:
|
try:
|
||||||
print()
|
print()
|
||||||
|
@ -372,7 +372,7 @@ def f():
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
print()
|
print()
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 7);
|
assert_eq!(num_statements(&stmts), 7);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -380,7 +380,7 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn try_except_else_finally() -> Result<()> {
|
fn try_except_else_finally() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
try:
|
try:
|
||||||
print()
|
print()
|
||||||
|
@ -390,7 +390,7 @@ def f():
|
||||||
print()
|
print()
|
||||||
finally:
|
finally:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 10);
|
assert_eq!(num_statements(&stmts), 10);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -398,7 +398,7 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn try_except_except() -> Result<()> {
|
fn try_except_except() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
try:
|
try:
|
||||||
print()
|
print()
|
||||||
|
@ -406,7 +406,7 @@ def f():
|
||||||
pass
|
pass
|
||||||
except Exception:
|
except Exception:
|
||||||
raise
|
raise
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 8);
|
assert_eq!(num_statements(&stmts), 8);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -414,7 +414,7 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn try_except_except_finally() -> Result<()> {
|
fn try_except_except_finally() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
try:
|
try:
|
||||||
print()
|
print()
|
||||||
|
@ -424,7 +424,7 @@ def f():
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
print()
|
print()
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 11);
|
assert_eq!(num_statements(&stmts), 11);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -432,11 +432,11 @@ def f():
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn yield_() -> Result<()> {
|
fn yield_() -> Result<()> {
|
||||||
let source: &str = r#"
|
let source: &str = r"
|
||||||
def f():
|
def f():
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
yield i
|
yield i
|
||||||
"#;
|
";
|
||||||
let stmts = parse_suite(source, "<filename>")?;
|
let stmts = parse_suite(source, "<filename>")?;
|
||||||
assert_eq!(num_statements(&stmts), 2);
|
assert_eq!(num_statements(&stmts), 2);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -104,145 +104,145 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn once() {
|
fn once() {
|
||||||
let source = r#"from foo import bar, baz, bop, qux as q"#;
|
let source = r"from foo import bar, baz, bop, qux as q";
|
||||||
let expected = r#"from foo import bar, baz, qux as q"#;
|
let expected = r"from foo import bar, baz, qux as q";
|
||||||
let actual = remove_import_members(source, &["bop"]);
|
let actual = remove_import_members(source, &["bop"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn twice() {
|
fn twice() {
|
||||||
let source = r#"from foo import bar, baz, bop, qux as q"#;
|
let source = r"from foo import bar, baz, bop, qux as q";
|
||||||
let expected = r#"from foo import bar, qux as q"#;
|
let expected = r"from foo import bar, qux as q";
|
||||||
let actual = remove_import_members(source, &["baz", "bop"]);
|
let actual = remove_import_members(source, &["baz", "bop"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn aliased() {
|
fn aliased() {
|
||||||
let source = r#"from foo import bar, baz, bop as boop, qux as q"#;
|
let source = r"from foo import bar, baz, bop as boop, qux as q";
|
||||||
let expected = r#"from foo import bar, baz, qux as q"#;
|
let expected = r"from foo import bar, baz, qux as q";
|
||||||
let actual = remove_import_members(source, &["bop"]);
|
let actual = remove_import_members(source, &["bop"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parenthesized() {
|
fn parenthesized() {
|
||||||
let source = r#"from foo import (bar, baz, bop, qux as q)"#;
|
let source = r"from foo import (bar, baz, bop, qux as q)";
|
||||||
let expected = r#"from foo import (bar, baz, qux as q)"#;
|
let expected = r"from foo import (bar, baz, qux as q)";
|
||||||
let actual = remove_import_members(source, &["bop"]);
|
let actual = remove_import_members(source, &["bop"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn last_import() {
|
fn last_import() {
|
||||||
let source = r#"from foo import bar, baz, bop, qux as q"#;
|
let source = r"from foo import bar, baz, bop, qux as q";
|
||||||
let expected = r#"from foo import bar, baz, bop"#;
|
let expected = r"from foo import bar, baz, bop";
|
||||||
let actual = remove_import_members(source, &["qux"]);
|
let actual = remove_import_members(source, &["qux"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn first_import() {
|
fn first_import() {
|
||||||
let source = r#"from foo import bar, baz, bop, qux as q"#;
|
let source = r"from foo import bar, baz, bop, qux as q";
|
||||||
let expected = r#"from foo import baz, bop, qux as q"#;
|
let expected = r"from foo import baz, bop, qux as q";
|
||||||
let actual = remove_import_members(source, &["bar"]);
|
let actual = remove_import_members(source, &["bar"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn first_two_imports() {
|
fn first_two_imports() {
|
||||||
let source = r#"from foo import bar, baz, bop, qux as q"#;
|
let source = r"from foo import bar, baz, bop, qux as q";
|
||||||
let expected = r#"from foo import bop, qux as q"#;
|
let expected = r"from foo import bop, qux as q";
|
||||||
let actual = remove_import_members(source, &["bar", "baz"]);
|
let actual = remove_import_members(source, &["bar", "baz"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn first_two_imports_multiline() {
|
fn first_two_imports_multiline() {
|
||||||
let source = r#"from foo import (
|
let source = r"from foo import (
|
||||||
bar,
|
bar,
|
||||||
baz,
|
baz,
|
||||||
bop,
|
bop,
|
||||||
qux as q
|
qux as q
|
||||||
)"#;
|
)";
|
||||||
let expected = r#"from foo import (
|
let expected = r"from foo import (
|
||||||
bop,
|
bop,
|
||||||
qux as q
|
qux as q
|
||||||
)"#;
|
)";
|
||||||
let actual = remove_import_members(source, &["bar", "baz"]);
|
let actual = remove_import_members(source, &["bar", "baz"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiline_once() {
|
fn multiline_once() {
|
||||||
let source = r#"from foo import (
|
let source = r"from foo import (
|
||||||
bar,
|
bar,
|
||||||
baz,
|
baz,
|
||||||
bop,
|
bop,
|
||||||
qux as q,
|
qux as q,
|
||||||
)"#;
|
)";
|
||||||
let expected = r#"from foo import (
|
let expected = r"from foo import (
|
||||||
bar,
|
bar,
|
||||||
baz,
|
baz,
|
||||||
qux as q,
|
qux as q,
|
||||||
)"#;
|
)";
|
||||||
let actual = remove_import_members(source, &["bop"]);
|
let actual = remove_import_members(source, &["bop"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiline_twice() {
|
fn multiline_twice() {
|
||||||
let source = r#"from foo import (
|
let source = r"from foo import (
|
||||||
bar,
|
bar,
|
||||||
baz,
|
baz,
|
||||||
bop,
|
bop,
|
||||||
qux as q,
|
qux as q,
|
||||||
)"#;
|
)";
|
||||||
let expected = r#"from foo import (
|
let expected = r"from foo import (
|
||||||
bar,
|
bar,
|
||||||
qux as q,
|
qux as q,
|
||||||
)"#;
|
)";
|
||||||
let actual = remove_import_members(source, &["baz", "bop"]);
|
let actual = remove_import_members(source, &["baz", "bop"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiline_comment() {
|
fn multiline_comment() {
|
||||||
let source = r#"from foo import (
|
let source = r"from foo import (
|
||||||
bar,
|
bar,
|
||||||
baz,
|
baz,
|
||||||
# This comment should be removed.
|
# This comment should be removed.
|
||||||
bop,
|
bop,
|
||||||
# This comment should be retained.
|
# This comment should be retained.
|
||||||
qux as q,
|
qux as q,
|
||||||
)"#;
|
)";
|
||||||
let expected = r#"from foo import (
|
let expected = r"from foo import (
|
||||||
bar,
|
bar,
|
||||||
baz,
|
baz,
|
||||||
# This comment should be retained.
|
# This comment should be retained.
|
||||||
qux as q,
|
qux as q,
|
||||||
)"#;
|
)";
|
||||||
let actual = remove_import_members(source, &["bop"]);
|
let actual = remove_import_members(source, &["bop"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multi_comment_first_import() {
|
fn multi_comment_first_import() {
|
||||||
let source = r#"from foo import (
|
let source = r"from foo import (
|
||||||
# This comment should be retained.
|
# This comment should be retained.
|
||||||
bar,
|
bar,
|
||||||
# This comment should be removed.
|
# This comment should be removed.
|
||||||
baz,
|
baz,
|
||||||
bop,
|
bop,
|
||||||
qux as q,
|
qux as q,
|
||||||
)"#;
|
)";
|
||||||
let expected = r#"from foo import (
|
let expected = r"from foo import (
|
||||||
# This comment should be retained.
|
# This comment should be retained.
|
||||||
baz,
|
baz,
|
||||||
bop,
|
bop,
|
||||||
qux as q,
|
qux as q,
|
||||||
)"#;
|
)";
|
||||||
let actual = remove_import_members(source, &["bar"]);
|
let actual = remove_import_members(source, &["bar"]);
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1045,7 +1045,7 @@ mod tests {
|
||||||
#[test_case("match.py")]
|
#[test_case("match.py")]
|
||||||
fn control_flow_graph(filename: &str) {
|
fn control_flow_graph(filename: &str) {
|
||||||
let path = PathBuf::from_iter(["resources/test/fixtures/control-flow-graph", filename]);
|
let path = PathBuf::from_iter(["resources/test/fixtures/control-flow-graph", filename]);
|
||||||
let source = fs::read_to_string(&path).expect("failed to read file");
|
let source = fs::read_to_string(path).expect("failed to read file");
|
||||||
let stmts = parse(&source, Mode::Module, filename)
|
let stmts = parse(&source, Mode::Module, filename)
|
||||||
.unwrap_or_else(|err| panic!("failed to parse source: '{source}': {err}"))
|
.unwrap_or_else(|err| panic!("failed to parse source: '{source}': {err}"))
|
||||||
.expect_module()
|
.expect_module()
|
||||||
|
|
|
@ -21,3 +21,6 @@ proc-macro2 = { workspace = true }
|
||||||
quote = { workspace = true }
|
quote = { workspace = true }
|
||||||
syn = { workspace = true, features = ["derive", "parsing", "extra-traits", "full"] }
|
syn = { workspace = true, features = ["derive", "parsing", "extra-traits", "full"] }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenS
|
||||||
.iter()
|
.iter()
|
||||||
.find(|attr| attr.path().is_ident("doc"))
|
.find(|attr| attr.path().is_ident("doc"))
|
||||||
else {
|
else {
|
||||||
return Err(Error::new(variant.span(), r#"expected a doc comment"#));
|
return Err(Error::new(variant.span(), "expected a doc comment"));
|
||||||
};
|
};
|
||||||
|
|
||||||
let variant_ident = variant.ident;
|
let variant_ident = variant.ident;
|
||||||
|
@ -155,7 +155,7 @@ fn parse_doc_attr(doc_attr: &Attribute) -> syn::Result<(String, String)> {
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::new(
|
Error::new(
|
||||||
doc_lit.span(),
|
doc_lit.span(),
|
||||||
r#"expected doc comment to be in the form of `/// [name](https://example.com/)`"#,
|
"expected doc comment to be in the form of `/// [name](https://example.com/)`",
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,3 +29,6 @@ uuid = { workspace = true }
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
insta = { workspace = true }
|
insta = { workspace = true }
|
||||||
test-case = { workspace = true }
|
test-case = { workspace = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -33,3 +33,6 @@ ruff_python_parser = { path = "../ruff_python_parser" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
serde = ["dep:serde", "ruff_text_size/serde"]
|
serde = ["dep:serde", "ruff_text_size/serde"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -229,7 +229,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_global_names() {
|
fn extract_global_names() {
|
||||||
let contents = r#"global X,Y, Z"#.trim();
|
let contents = r"global X,Y, Z".trim();
|
||||||
|
|
||||||
let mut names = IdentifierTokenizer::new(
|
let mut names = IdentifierTokenizer::new(
|
||||||
contents,
|
contents,
|
||||||
|
|
|
@ -5,12 +5,12 @@ use ruff_python_ast::identifier;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_else_range() -> Result<(), ParseError> {
|
fn extract_else_range() -> Result<(), ParseError> {
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
for x in y:
|
for x in y:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
.trim();
|
.trim();
|
||||||
let stmts = parse_suite(contents, "<filename>")?;
|
let stmts = parse_suite(contents, "<filename>")?;
|
||||||
let stmt = stmts.first().unwrap();
|
let stmt = stmts.first().unwrap();
|
||||||
|
|
|
@ -5,7 +5,7 @@ use ruff_text_size::TextRange;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parenthesized_name() {
|
fn test_parenthesized_name() {
|
||||||
let source_code = r#"(x) + 1"#;
|
let source_code = r"(x) + 1";
|
||||||
let expr = parse_expression(source_code, "<filename>").unwrap();
|
let expr = parse_expression(source_code, "<filename>").unwrap();
|
||||||
|
|
||||||
let bin_op = expr.as_bin_op_expr().unwrap();
|
let bin_op = expr.as_bin_op_expr().unwrap();
|
||||||
|
@ -22,7 +22,7 @@ fn test_parenthesized_name() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_non_parenthesized_name() {
|
fn test_non_parenthesized_name() {
|
||||||
let source_code = r#"x + 1"#;
|
let source_code = r"x + 1";
|
||||||
let expr = parse_expression(source_code, "<filename>").unwrap();
|
let expr = parse_expression(source_code, "<filename>").unwrap();
|
||||||
|
|
||||||
let bin_op = expr.as_bin_op_expr().unwrap();
|
let bin_op = expr.as_bin_op_expr().unwrap();
|
||||||
|
@ -39,7 +39,7 @@ fn test_non_parenthesized_name() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parenthesized_argument() {
|
fn test_parenthesized_argument() {
|
||||||
let source_code = r#"f((a))"#;
|
let source_code = r"f((a))";
|
||||||
let expr = parse_expression(source_code, "<filename>").unwrap();
|
let expr = parse_expression(source_code, "<filename>").unwrap();
|
||||||
|
|
||||||
let call = expr.as_call_expr().unwrap();
|
let call = expr.as_call_expr().unwrap();
|
||||||
|
@ -57,7 +57,7 @@ fn test_parenthesized_argument() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_non_parenthesized_argument() {
|
fn test_non_parenthesized_argument() {
|
||||||
let source_code = r#"f(a)"#;
|
let source_code = r"f(a)";
|
||||||
let expr = parse_expression(source_code, "<filename>").unwrap();
|
let expr = parse_expression(source_code, "<filename>").unwrap();
|
||||||
|
|
||||||
let call = expr.as_call_expr().unwrap();
|
let call = expr.as_call_expr().unwrap();
|
||||||
|
@ -75,7 +75,7 @@ fn test_non_parenthesized_argument() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parenthesized_tuple_member() {
|
fn test_parenthesized_tuple_member() {
|
||||||
let source_code = r#"(a, (b))"#;
|
let source_code = r"(a, (b))";
|
||||||
let expr = parse_expression(source_code, "<filename>").unwrap();
|
let expr = parse_expression(source_code, "<filename>").unwrap();
|
||||||
|
|
||||||
let tuple = expr.as_tuple_expr().unwrap();
|
let tuple = expr.as_tuple_expr().unwrap();
|
||||||
|
@ -92,7 +92,7 @@ fn test_parenthesized_tuple_member() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_non_parenthesized_tuple_member() {
|
fn test_non_parenthesized_tuple_member() {
|
||||||
let source_code = r#"(a, b)"#;
|
let source_code = r"(a, b)";
|
||||||
let expr = parse_expression(source_code, "<filename>").unwrap();
|
let expr = parse_expression(source_code, "<filename>").unwrap();
|
||||||
|
|
||||||
let tuple = expr.as_tuple_expr().unwrap();
|
let tuple = expr.as_tuple_expr().unwrap();
|
||||||
|
@ -109,7 +109,7 @@ fn test_non_parenthesized_tuple_member() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_twice_parenthesized_name() {
|
fn test_twice_parenthesized_name() {
|
||||||
let source_code = r#"((x)) + 1"#;
|
let source_code = r"((x)) + 1";
|
||||||
let expr = parse_expression(source_code, "<filename>").unwrap();
|
let expr = parse_expression(source_code, "<filename>").unwrap();
|
||||||
|
|
||||||
let bin_op = expr.as_bin_op_expr().unwrap();
|
let bin_op = expr.as_bin_op_expr().unwrap();
|
||||||
|
@ -126,7 +126,7 @@ fn test_twice_parenthesized_name() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_twice_parenthesized_argument() {
|
fn test_twice_parenthesized_argument() {
|
||||||
let source_code = r#"f(((a + 1)))"#;
|
let source_code = r"f(((a + 1)))";
|
||||||
let expr = parse_expression(source_code, "<filename>").unwrap();
|
let expr = parse_expression(source_code, "<filename>").unwrap();
|
||||||
|
|
||||||
let call = expr.as_call_expr().unwrap();
|
let call = expr.as_call_expr().unwrap();
|
||||||
|
|
|
@ -17,7 +17,7 @@ use ruff_python_parser::{parse_tokens, Mode};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn function_arguments() {
|
fn function_arguments() {
|
||||||
let source = r#"def a(b, c,/, d, e = 20, *args, named=5, other=20, **kwargs): pass"#;
|
let source = r"def a(b, c,/, d, e = 20, *args, named=5, other=20, **kwargs): pass";
|
||||||
|
|
||||||
let trace = trace_preorder_visitation(source);
|
let trace = trace_preorder_visitation(source);
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ fn function_arguments() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn function_positional_only_with_default() {
|
fn function_positional_only_with_default() {
|
||||||
let source = r#"def a(b, c = 34,/, e = 20, *args): pass"#;
|
let source = r"def a(b, c = 34,/, e = 20, *args): pass";
|
||||||
|
|
||||||
let trace = trace_preorder_visitation(source);
|
let trace = trace_preorder_visitation(source);
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ fn function_positional_only_with_default() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn compare() {
|
fn compare() {
|
||||||
let source = r#"4 < x < 5"#;
|
let source = r"4 < x < 5";
|
||||||
|
|
||||||
let trace = trace_preorder_visitation(source);
|
let trace = trace_preorder_visitation(source);
|
||||||
|
|
||||||
|
@ -71,13 +71,13 @@ fn set_comprehension() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn match_class_pattern() {
|
fn match_class_pattern() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
match x:
|
match x:
|
||||||
case Point2D(0, 0):
|
case Point2D(0, 0):
|
||||||
...
|
...
|
||||||
case Point3D(x=0, y=0, z=0):
|
case Point3D(x=0, y=0, z=0):
|
||||||
...
|
...
|
||||||
"#;
|
";
|
||||||
|
|
||||||
let trace = trace_preorder_visitation(source);
|
let trace = trace_preorder_visitation(source);
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ match x:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decorators() {
|
fn decorators() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
@decorator
|
@decorator
|
||||||
def a():
|
def a():
|
||||||
pass
|
pass
|
||||||
|
@ -94,7 +94,7 @@ def a():
|
||||||
@test
|
@test
|
||||||
class A:
|
class A:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
|
|
||||||
let trace = trace_preorder_visitation(source);
|
let trace = trace_preorder_visitation(source);
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ class A:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn type_aliases() {
|
fn type_aliases() {
|
||||||
let source = r#"type X[T: str, U, *Ts, **P] = list[T]"#;
|
let source = r"type X[T: str, U, *Ts, **P] = list[T]";
|
||||||
|
|
||||||
let trace = trace_preorder_visitation(source);
|
let trace = trace_preorder_visitation(source);
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ fn type_aliases() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn class_type_parameters() {
|
fn class_type_parameters() {
|
||||||
let source = r#"class X[T: str, U, *Ts, **P]: ..."#;
|
let source = r"class X[T: str, U, *Ts, **P]: ...";
|
||||||
|
|
||||||
let trace = trace_preorder_visitation(source);
|
let trace = trace_preorder_visitation(source);
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ fn class_type_parameters() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn function_type_parameters() {
|
fn function_type_parameters() {
|
||||||
let source = r#"def X[T: str, U, *Ts, **P](): ..."#;
|
let source = r"def X[T: str, U, *Ts, **P](): ...";
|
||||||
|
|
||||||
let trace = trace_preorder_visitation(source);
|
let trace = trace_preorder_visitation(source);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ use ruff_python_ast::{
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn function_arguments() {
|
fn function_arguments() {
|
||||||
let source = r#"def a(b, c,/, d, e = 20, *args, named=5, other=20, **kwargs): pass"#;
|
let source = r"def a(b, c,/, d, e = 20, *args, named=5, other=20, **kwargs): pass";
|
||||||
|
|
||||||
let trace = trace_visitation(source);
|
let trace = trace_visitation(source);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ fn function_arguments() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn function_positional_only_with_default() {
|
fn function_positional_only_with_default() {
|
||||||
let source = r#"def a(b, c = 34,/, e = 20, *args): pass"#;
|
let source = r"def a(b, c = 34,/, e = 20, *args): pass";
|
||||||
|
|
||||||
let trace = trace_visitation(source);
|
let trace = trace_visitation(source);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ fn function_positional_only_with_default() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn compare() {
|
fn compare() {
|
||||||
let source = r#"4 < x < 5"#;
|
let source = r"4 < x < 5";
|
||||||
|
|
||||||
let trace = trace_visitation(source);
|
let trace = trace_visitation(source);
|
||||||
|
|
||||||
|
@ -72,13 +72,13 @@ fn set_comprehension() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn match_class_pattern() {
|
fn match_class_pattern() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
match x:
|
match x:
|
||||||
case Point2D(0, 0):
|
case Point2D(0, 0):
|
||||||
...
|
...
|
||||||
case Point3D(x=0, y=0, z=0):
|
case Point3D(x=0, y=0, z=0):
|
||||||
...
|
...
|
||||||
"#;
|
";
|
||||||
|
|
||||||
let trace = trace_visitation(source);
|
let trace = trace_visitation(source);
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ match x:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decorators() {
|
fn decorators() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
@decorator
|
@decorator
|
||||||
def a():
|
def a():
|
||||||
pass
|
pass
|
||||||
|
@ -95,7 +95,7 @@ def a():
|
||||||
@test
|
@test
|
||||||
class A:
|
class A:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
|
|
||||||
let trace = trace_visitation(source);
|
let trace = trace_visitation(source);
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ class A:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn type_aliases() {
|
fn type_aliases() {
|
||||||
let source = r#"type X[T: str, U, *Ts, **P] = list[T]"#;
|
let source = r"type X[T: str, U, *Ts, **P] = list[T]";
|
||||||
|
|
||||||
let trace = trace_visitation(source);
|
let trace = trace_visitation(source);
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ fn type_aliases() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn class_type_parameters() {
|
fn class_type_parameters() {
|
||||||
let source = r#"class X[T: str, U, *Ts, **P]: ..."#;
|
let source = r"class X[T: str, U, *Ts, **P]: ...";
|
||||||
|
|
||||||
let trace = trace_visitation(source);
|
let trace = trace_visitation(source);
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ fn class_type_parameters() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn function_type_parameters() {
|
fn function_type_parameters() {
|
||||||
let source = r#"def X[T: str, U, *Ts, **P](): ..."#;
|
let source = r"def X[T: str, U, *Ts, **P](): ...";
|
||||||
|
|
||||||
let trace = trace_visitation(source);
|
let trace = trace_visitation(source);
|
||||||
|
|
||||||
|
|
|
@ -20,3 +20,6 @@ ruff_source_file = { path = "../ruff_source_file" }
|
||||||
|
|
||||||
once_cell = { workspace = true }
|
once_cell = { workspace = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
|
|
@ -1473,7 +1473,7 @@ mod tests {
|
||||||
assert_round_trip!("return await (await bar())");
|
assert_round_trip!("return await (await bar())");
|
||||||
assert_round_trip!("(5).foo");
|
assert_round_trip!("(5).foo");
|
||||||
assert_round_trip!(r#"our_dict = {"a": 1, **{"b": 2, "c": 3}}"#);
|
assert_round_trip!(r#"our_dict = {"a": 1, **{"b": 2, "c": 3}}"#);
|
||||||
assert_round_trip!(r#"j = [1, 2, 3]"#);
|
assert_round_trip!(r"j = [1, 2, 3]");
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def test(a1, a2, b1=j, b2="123", b3={}, b4=[]):
|
r#"def test(a1, a2, b1=j, b2="123", b3={}, b4=[]):
|
||||||
pass"#
|
pass"#
|
||||||
|
@ -1511,32 +1511,32 @@ mod tests {
|
||||||
pass"#
|
pass"#
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"class Foo(Bar, object):
|
r"class Foo(Bar, object):
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"class Foo[T]:
|
r"class Foo[T]:
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"class Foo[T](Bar):
|
r"class Foo[T](Bar):
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"class Foo[*Ts]:
|
r"class Foo[*Ts]:
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"class Foo[**P]:
|
r"class Foo[**P]:
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"class Foo[T, U, *Ts, **P]:
|
r"class Foo[T, U, *Ts, **P]:
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def f() -> (int, str):
|
r"def f() -> (int, str):
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!("[await x async for x in y]");
|
assert_round_trip!("[await x async for x in y]");
|
||||||
assert_round_trip!("[await i for i in b if await c]");
|
assert_round_trip!("[await i for i in b if await c]");
|
||||||
|
@ -1550,102 +1550,102 @@ mod tests {
|
||||||
return datum"#
|
return datum"#
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def f() -> (int, int):
|
r"def f() -> (int, int):
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def test(a, b, /, c, *, d, **kwargs):
|
r"def test(a, b, /, c, *, d, **kwargs):
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def test(a=3, b=4, /, c=7):
|
r"def test(a=3, b=4, /, c=7):
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def test(a, b=4, /, c=8, d=9):
|
r"def test(a, b=4, /, c=8, d=9):
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def test[T]():
|
r"def test[T]():
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def test[*Ts]():
|
r"def test[*Ts]():
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def test[**P]():
|
r"def test[**P]():
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def test[T, U, *Ts, **P]():
|
r"def test[T, U, *Ts, **P]():
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def call(*popenargs, timeout=None, **kwargs):
|
r"def call(*popenargs, timeout=None, **kwargs):
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"@functools.lru_cache(maxsize=None)
|
r"@functools.lru_cache(maxsize=None)
|
||||||
def f(x: int, y: int) -> int:
|
def f(x: int, y: int) -> int:
|
||||||
return x + y"#
|
return x + y"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"try:
|
r"try:
|
||||||
pass
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"try:
|
r"try:
|
||||||
pass
|
pass
|
||||||
except* Exception as e:
|
except* Exception as e:
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"match x:
|
r"match x:
|
||||||
case [1, 2, 3]:
|
case [1, 2, 3]:
|
||||||
return 2
|
return 2
|
||||||
case 4 as y:
|
case 4 as y:
|
||||||
return y"#
|
return y"
|
||||||
);
|
);
|
||||||
assert_eq!(round_trip(r#"x = (1, 2, 3)"#), r#"x = 1, 2, 3"#);
|
assert_eq!(round_trip(r"x = (1, 2, 3)"), r"x = 1, 2, 3");
|
||||||
assert_eq!(round_trip(r#"-(1) + ~(2) + +(3)"#), r#"-1 + ~2 + +3"#);
|
assert_eq!(round_trip(r"-(1) + ~(2) + +(3)"), r"-1 + ~2 + +3");
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"def f():
|
r"def f():
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"@foo
|
r"@foo
|
||||||
def f():
|
def f():
|
||||||
|
|
||||||
@foo
|
@foo
|
||||||
def f():
|
def f():
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
r#"@foo
|
r"@foo
|
||||||
class Foo:
|
class Foo:
|
||||||
|
|
||||||
@foo
|
@foo
|
||||||
def f():
|
def f():
|
||||||
pass"#
|
pass"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_round_trip!(r#"[lambda n: n for n in range(10)]"#);
|
assert_round_trip!(r"[lambda n: n for n in range(10)]");
|
||||||
assert_round_trip!(r#"[n[0:2] for n in range(10)]"#);
|
assert_round_trip!(r"[n[0:2] for n in range(10)]");
|
||||||
assert_round_trip!(r#"[n[0] for n in range(10)]"#);
|
assert_round_trip!(r"[n[0] for n in range(10)]");
|
||||||
assert_round_trip!(r#"[(n, n * 2) for n in range(10)]"#);
|
assert_round_trip!(r"[(n, n * 2) for n in range(10)]");
|
||||||
assert_round_trip!(r#"[1 if n % 2 == 0 else 0 for n in range(10)]"#);
|
assert_round_trip!(r"[1 if n % 2 == 0 else 0 for n in range(10)]");
|
||||||
assert_round_trip!(r#"[n % 2 == 0 or 0 for n in range(10)]"#);
|
assert_round_trip!(r"[n % 2 == 0 or 0 for n in range(10)]");
|
||||||
assert_round_trip!(r#"[(n := 2) for n in range(10)]"#);
|
assert_round_trip!(r"[(n := 2) for n in range(10)]");
|
||||||
assert_round_trip!(r#"((n := 2) for n in range(10))"#);
|
assert_round_trip!(r"((n := 2) for n in range(10))");
|
||||||
assert_round_trip!(r#"[n * 2 for n in range(10)]"#);
|
assert_round_trip!(r"[n * 2 for n in range(10)]");
|
||||||
assert_round_trip!(r#"{n * 2 for n in range(10)}"#);
|
assert_round_trip!(r"{n * 2 for n in range(10)}");
|
||||||
assert_round_trip!(r#"{i: n * 2 for i, n in enumerate(range(10))}"#);
|
assert_round_trip!(r"{i: n * 2 for i, n in enumerate(range(10))}");
|
||||||
assert_round_trip!(
|
assert_round_trip!(
|
||||||
"class SchemaItem(NamedTuple):
|
"class SchemaItem(NamedTuple):
|
||||||
fields: ((\"property_key\", str),)"
|
fields: ((\"property_key\", str),)"
|
||||||
|
@ -1659,25 +1659,25 @@ class Foo:
|
||||||
assert_round_trip!("x += (i := 1)");
|
assert_round_trip!("x += (i := 1)");
|
||||||
|
|
||||||
// Type aliases
|
// Type aliases
|
||||||
assert_round_trip!(r#"type Foo = int | str"#);
|
assert_round_trip!(r"type Foo = int | str");
|
||||||
assert_round_trip!(r#"type Foo[T] = list[T]"#);
|
assert_round_trip!(r"type Foo[T] = list[T]");
|
||||||
assert_round_trip!(r#"type Foo[*Ts] = ..."#);
|
assert_round_trip!(r"type Foo[*Ts] = ...");
|
||||||
assert_round_trip!(r#"type Foo[**P] = ..."#);
|
assert_round_trip!(r"type Foo[**P] = ...");
|
||||||
assert_round_trip!(r#"type Foo[T, U, *Ts, **P] = ..."#);
|
assert_round_trip!(r"type Foo[T, U, *Ts, **P] = ...");
|
||||||
// https://github.com/astral-sh/ruff/issues/6498
|
// https://github.com/astral-sh/ruff/issues/6498
|
||||||
assert_round_trip!(r#"f(a=1, *args, **kwargs)"#);
|
assert_round_trip!(r"f(a=1, *args, **kwargs)");
|
||||||
assert_round_trip!(r#"f(*args, a=1, **kwargs)"#);
|
assert_round_trip!(r"f(*args, a=1, **kwargs)");
|
||||||
assert_round_trip!(r#"f(*args, a=1, *args2, **kwargs)"#);
|
assert_round_trip!(r"f(*args, a=1, *args2, **kwargs)");
|
||||||
assert_round_trip!("class A(*args, a=2, *args2, **kwargs):\n pass");
|
assert_round_trip!("class A(*args, a=2, *args2, **kwargs):\n pass");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn quote() {
|
fn quote() {
|
||||||
assert_eq!(round_trip(r#""hello""#), r#""hello""#);
|
assert_eq!(round_trip(r#""hello""#), r#""hello""#);
|
||||||
assert_eq!(round_trip(r#"'hello'"#), r#""hello""#);
|
assert_eq!(round_trip(r"'hello'"), r#""hello""#);
|
||||||
assert_eq!(round_trip(r#"u'hello'"#), r#"u"hello""#);
|
assert_eq!(round_trip(r"u'hello'"), r#"u"hello""#);
|
||||||
assert_eq!(round_trip(r#"r'hello'"#), r#""hello""#);
|
assert_eq!(round_trip(r"r'hello'"), r#""hello""#);
|
||||||
assert_eq!(round_trip(r#"b'hello'"#), r#"b"hello""#);
|
assert_eq!(round_trip(r"b'hello'"), r#"b"hello""#);
|
||||||
assert_eq!(round_trip(r#"("abc" "def" "ghi")"#), r#""abcdefghi""#);
|
assert_eq!(round_trip(r#"("abc" "def" "ghi")"#), r#""abcdefghi""#);
|
||||||
assert_eq!(round_trip(r#""he\"llo""#), r#"'he"llo'"#);
|
assert_eq!(round_trip(r#""he\"llo""#), r#"'he"llo'"#);
|
||||||
assert_eq!(round_trip(r#"f"abc{'def'}{1}""#), r#"f"abc{'def'}{1}""#);
|
assert_eq!(round_trip(r#"f"abc{'def'}{1}""#), r#"f"abc{'def'}{1}""#);
|
||||||
|
@ -1697,16 +1697,16 @@ class Foo:
|
||||||
fn indent() {
|
fn indent() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
round_trip(
|
round_trip(
|
||||||
r#"
|
r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
),
|
),
|
||||||
r#"
|
r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
.trim()
|
.trim()
|
||||||
.replace('\n', LineEnding::default().as_str())
|
.replace('\n', LineEnding::default().as_str())
|
||||||
);
|
);
|
||||||
|
@ -1730,14 +1730,14 @@ if True:
|
||||||
LineEnding::default(),
|
LineEnding::default(),
|
||||||
r#""hello""#
|
r#""hello""#
|
||||||
),
|
),
|
||||||
r#"'hello'"#
|
r"'hello'"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
round_trip_with(
|
round_trip_with(
|
||||||
&Indentation::default(),
|
&Indentation::default(),
|
||||||
Quote::Double,
|
Quote::Double,
|
||||||
LineEnding::default(),
|
LineEnding::default(),
|
||||||
r#"'hello'"#
|
r"'hello'"
|
||||||
),
|
),
|
||||||
r#""hello""#
|
r#""hello""#
|
||||||
);
|
);
|
||||||
|
@ -1746,9 +1746,9 @@ if True:
|
||||||
&Indentation::default(),
|
&Indentation::default(),
|
||||||
Quote::Single,
|
Quote::Single,
|
||||||
LineEnding::default(),
|
LineEnding::default(),
|
||||||
r#"'hello'"#
|
r"'hello'"
|
||||||
),
|
),
|
||||||
r#"'hello'"#
|
r"'hello'"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1759,16 +1759,16 @@ if True:
|
||||||
&Indentation::new(" ".to_string()),
|
&Indentation::new(" ".to_string()),
|
||||||
Quote::default(),
|
Quote::default(),
|
||||||
LineEnding::default(),
|
LineEnding::default(),
|
||||||
r#"
|
r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
),
|
),
|
||||||
r#"
|
r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
.trim()
|
.trim()
|
||||||
.replace('\n', LineEnding::default().as_str())
|
.replace('\n', LineEnding::default().as_str())
|
||||||
);
|
);
|
||||||
|
@ -1777,16 +1777,16 @@ if True:
|
||||||
&Indentation::new(" ".to_string()),
|
&Indentation::new(" ".to_string()),
|
||||||
Quote::default(),
|
Quote::default(),
|
||||||
LineEnding::default(),
|
LineEnding::default(),
|
||||||
r#"
|
r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
),
|
),
|
||||||
r#"
|
r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
.trim()
|
.trim()
|
||||||
.replace('\n', LineEnding::default().as_str())
|
.replace('\n', LineEnding::default().as_str())
|
||||||
);
|
);
|
||||||
|
@ -1795,16 +1795,16 @@ if True:
|
||||||
&Indentation::new("\t".to_string()),
|
&Indentation::new("\t".to_string()),
|
||||||
Quote::default(),
|
Quote::default(),
|
||||||
LineEnding::default(),
|
LineEnding::default(),
|
||||||
r#"
|
r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
),
|
),
|
||||||
r#"
|
r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
.trim()
|
.trim()
|
||||||
.replace('\n', LineEnding::default().as_str())
|
.replace('\n', LineEnding::default().as_str())
|
||||||
);
|
);
|
||||||
|
|
|
@ -190,7 +190,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn indentation() {
|
fn indentation() {
|
||||||
let contents = r#"x = 1"#;
|
let contents = r"x = 1";
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -198,10 +198,10 @@ mod tests {
|
||||||
&Indentation::default()
|
&Indentation::default()
|
||||||
);
|
);
|
||||||
|
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -209,10 +209,10 @@ if True:
|
||||||
&Indentation(" ".to_string())
|
&Indentation(" ".to_string())
|
||||||
);
|
);
|
||||||
|
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -220,10 +220,10 @@ if True:
|
||||||
&Indentation(" ".to_string())
|
&Indentation(" ".to_string())
|
||||||
);
|
);
|
||||||
|
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -232,13 +232,13 @@ if True:
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO(charlie): Should non-significant whitespace be detected?
|
// TODO(charlie): Should non-significant whitespace be detected?
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
x = (
|
x = (
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
3,
|
3,
|
||||||
)
|
)
|
||||||
"#;
|
";
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -247,11 +247,11 @@ x = (
|
||||||
);
|
);
|
||||||
|
|
||||||
// formfeed indent, see `detect_indention` comment.
|
// formfeed indent, see `detect_indention` comment.
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
class FormFeedIndent:
|
class FormFeedIndent:
|
||||||
def __init__(self, a=[]):
|
def __init__(self, a=[]):
|
||||||
print(a)
|
print(a)
|
||||||
"#;
|
";
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -262,7 +262,7 @@ class FormFeedIndent:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn quote() {
|
fn quote() {
|
||||||
let contents = r#"x = 1"#;
|
let contents = r"x = 1";
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -270,7 +270,7 @@ class FormFeedIndent:
|
||||||
Quote::default()
|
Quote::default()
|
||||||
);
|
);
|
||||||
|
|
||||||
let contents = r#"x = '1'"#;
|
let contents = r"x = '1'";
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -278,7 +278,7 @@ class FormFeedIndent:
|
||||||
Quote::Single
|
Quote::Single
|
||||||
);
|
);
|
||||||
|
|
||||||
let contents = r#"x = f'1'"#;
|
let contents = r"x = f'1'";
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -373,9 +373,9 @@ a = f"v"
|
||||||
Quote::Double
|
Quote::Double
|
||||||
);
|
);
|
||||||
|
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
f'''Module docstring.'''
|
f'''Module docstring.'''
|
||||||
"#;
|
";
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
let tokens: Vec<_> = lex(contents, Mode::Module).collect();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -55,3 +55,6 @@ required-features = ["serde"]
|
||||||
default = ["serde"]
|
default = ["serde"]
|
||||||
serde = ["dep:serde", "ruff_formatter/serde", "ruff_source_file/serde", "ruff_python_ast/serde"]
|
serde = ["dep:serde", "ruff_formatter/serde", "ruff_source_file/serde", "ruff_python_ast/serde"]
|
||||||
schemars = ["dep:schemars", "ruff_formatter/schemars"]
|
schemars = ["dep:schemars", "ruff_formatter/schemars"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -198,11 +198,11 @@ mod tests {
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let source = r#"# leading comment
|
let source = r"# leading comment
|
||||||
continue; # trailing
|
continue; # trailing
|
||||||
# break leading
|
# break leading
|
||||||
break;
|
break;
|
||||||
"#;
|
";
|
||||||
|
|
||||||
let source_code = SourceCode::new(source);
|
let source_code = SourceCode::new(source);
|
||||||
|
|
||||||
|
|
|
@ -610,11 +610,11 @@ test(10, 20)
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn only_comments() {
|
fn only_comments() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
# Some comment
|
# Some comment
|
||||||
|
|
||||||
# another comment
|
# another comment
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -624,7 +624,7 @@ test(10, 20)
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn empty_file() {
|
fn empty_file() {
|
||||||
let source = r#""#;
|
let source = r"";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -634,12 +634,12 @@ test(10, 20)
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dangling_comment() {
|
fn dangling_comment() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def test(
|
def test(
|
||||||
# Some comment
|
# Some comment
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -649,12 +649,12 @@ def test(
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parenthesized_expression() {
|
fn parenthesized_expression() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
a = ( # Trailing comment
|
a = ( # Trailing comment
|
||||||
10 + # More comments
|
10 + # More comments
|
||||||
3
|
3
|
||||||
)
|
)
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -664,11 +664,11 @@ a = ( # Trailing comment
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parenthesized_trailing_comment() {
|
fn parenthesized_trailing_comment() {
|
||||||
let source = r#"(
|
let source = r"(
|
||||||
a
|
a
|
||||||
# comment
|
# comment
|
||||||
)
|
)
|
||||||
"#;
|
";
|
||||||
|
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -728,7 +728,7 @@ print("test")
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_elif_else_comments() {
|
fn if_elif_else_comments() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
if x == y:
|
if x == y:
|
||||||
pass # trailing `pass` comment
|
pass # trailing `pass` comment
|
||||||
# Root `if` trailing comment
|
# Root `if` trailing comment
|
||||||
|
@ -741,7 +741,7 @@ elif x < y:
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
# `else` trailing comment
|
# `else` trailing comment
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -751,7 +751,7 @@ else:
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_elif_if_else_comments() {
|
fn if_elif_if_else_comments() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
if x == y:
|
if x == y:
|
||||||
pass
|
pass
|
||||||
elif x < y:
|
elif x < y:
|
||||||
|
@ -761,7 +761,7 @@ elif x < y:
|
||||||
# Leading else comment
|
# Leading else comment
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -855,10 +855,10 @@ print("Next statement");
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn leading_most_outer() {
|
fn leading_most_outer() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
# leading comment
|
# leading comment
|
||||||
x
|
x
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -869,10 +869,10 @@ x
|
||||||
// Comment should be attached to the statement
|
// Comment should be attached to the statement
|
||||||
#[test]
|
#[test]
|
||||||
fn trailing_most_outer() {
|
fn trailing_most_outer() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
x # trailing comment
|
x # trailing comment
|
||||||
y # trailing last node
|
y # trailing last node
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -882,11 +882,11 @@ y # trailing last node
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn trailing_most_outer_nested() {
|
fn trailing_most_outer_nested() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
x + (
|
x + (
|
||||||
3 # trailing comment
|
3 # trailing comment
|
||||||
) # outer
|
) # outer
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -896,12 +896,12 @@ x + (
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn trailing_after_comma() {
|
fn trailing_after_comma() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def test(
|
def test(
|
||||||
a, # Trailing comment for argument `a`
|
a, # Trailing comment for argument `a`
|
||||||
b,
|
b,
|
||||||
): pass
|
): pass
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -911,7 +911,7 @@ def test(
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn positional_argument_only_comment() {
|
fn positional_argument_only_comment() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def test(
|
def test(
|
||||||
a, # trailing positional comment
|
a, # trailing positional comment
|
||||||
# Positional arguments only after here
|
# Positional arguments only after here
|
||||||
|
@ -919,7 +919,7 @@ def test(
|
||||||
# leading b comment
|
# leading b comment
|
||||||
b,
|
b,
|
||||||
): pass
|
): pass
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -929,7 +929,7 @@ def test(
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn positional_argument_only_leading_comma_comment() {
|
fn positional_argument_only_leading_comma_comment() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def test(
|
def test(
|
||||||
a # trailing positional comment
|
a # trailing positional comment
|
||||||
# Positional arguments only after here
|
# Positional arguments only after here
|
||||||
|
@ -937,7 +937,7 @@ def test(
|
||||||
# leading b comment
|
# leading b comment
|
||||||
b,
|
b,
|
||||||
): pass
|
): pass
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -947,14 +947,14 @@ def test(
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn positional_argument_only_comment_without_following_node() {
|
fn positional_argument_only_comment_without_following_node() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def test(
|
def test(
|
||||||
a, # trailing positional comment
|
a, # trailing positional comment
|
||||||
# Positional arguments only after here
|
# Positional arguments only after here
|
||||||
/, # trailing positional argument comment.
|
/, # trailing positional argument comment.
|
||||||
# Trailing on new line
|
# Trailing on new line
|
||||||
): pass
|
): pass
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -964,7 +964,7 @@ def test(
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn non_positional_arguments_with_defaults() {
|
fn non_positional_arguments_with_defaults() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def test(
|
def test(
|
||||||
a=10 # trailing positional comment
|
a=10 # trailing positional comment
|
||||||
# Positional arguments only after here
|
# Positional arguments only after here
|
||||||
|
@ -972,7 +972,7 @@ def test(
|
||||||
# leading comment for b
|
# leading comment for b
|
||||||
b=20
|
b=20
|
||||||
): pass
|
): pass
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -982,12 +982,12 @@ def test(
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn non_positional_arguments_slash_on_same_line() {
|
fn non_positional_arguments_slash_on_same_line() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
def test(a=10,/, # trailing positional argument comment.
|
def test(a=10,/, # trailing positional argument comment.
|
||||||
# leading comment for b
|
# leading comment for b
|
||||||
b=20
|
b=20
|
||||||
): pass
|
): pass
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -997,7 +997,7 @@ def test(a=10,/, # trailing positional argument comment.
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn binary_expression_left_operand_comment() {
|
fn binary_expression_left_operand_comment() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
a = (
|
a = (
|
||||||
5
|
5
|
||||||
# trailing left comment
|
# trailing left comment
|
||||||
|
@ -1005,7 +1005,7 @@ a = (
|
||||||
# leading right comment
|
# leading right comment
|
||||||
3
|
3
|
||||||
)
|
)
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -1015,14 +1015,14 @@ a = (
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn binary_expression_left_operand_trailing_end_of_line_comment() {
|
fn binary_expression_left_operand_trailing_end_of_line_comment() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
a = (
|
a = (
|
||||||
5 # trailing left comment
|
5 # trailing left comment
|
||||||
+ # trailing operator comment
|
+ # trailing operator comment
|
||||||
# leading right comment
|
# leading right comment
|
||||||
3
|
3
|
||||||
)
|
)
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -1032,7 +1032,7 @@ a = (
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn nested_binary_expression() {
|
fn nested_binary_expression() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
a = (
|
a = (
|
||||||
(5 # trailing left comment
|
(5 # trailing left comment
|
||||||
*
|
*
|
||||||
|
@ -1041,7 +1041,7 @@ a = (
|
||||||
# leading right comment
|
# leading right comment
|
||||||
3
|
3
|
||||||
)
|
)
|
||||||
"#;
|
";
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
let comments = test_case.to_comments();
|
let comments = test_case.to_comments();
|
||||||
|
@ -1051,10 +1051,10 @@ a = (
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn while_trailing_end_of_line_comment() {
|
fn while_trailing_end_of_line_comment() {
|
||||||
let source = r#"while True:
|
let source = r"while True:
|
||||||
if something.changed:
|
if something.changed:
|
||||||
do.stuff() # trailing comment
|
do.stuff() # trailing comment
|
||||||
"#;
|
";
|
||||||
|
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
|
@ -1065,11 +1065,11 @@ a = (
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn while_trailing_else_end_of_line_comment() {
|
fn while_trailing_else_end_of_line_comment() {
|
||||||
let source = r#"while True:
|
let source = r"while True:
|
||||||
pass
|
pass
|
||||||
else: # trailing comment
|
else: # trailing comment
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
|
|
||||||
let test_case = CommentsTestCase::from_code(source);
|
let test_case = CommentsTestCase::from_code(source);
|
||||||
|
|
||||||
|
|
|
@ -2281,10 +2281,10 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
max_empty_lines(
|
max_empty_lines(
|
||||||
r#"# This multiline comments section
|
r"# This multiline comments section
|
||||||
# should be split from the statement
|
# should be split from the statement
|
||||||
# above by two lines.
|
# above by two lines.
|
||||||
"#
|
"
|
||||||
),
|
),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl<'a> AnyString<'a> {
|
||||||
.slice(f_string.range)
|
.slice(f_string.range)
|
||||||
.trim_start_matches(|c| c != '"' && c != '\'');
|
.trim_start_matches(|c| c != '"' && c != '\'');
|
||||||
let triple_quoted =
|
let triple_quoted =
|
||||||
unprefixed.starts_with(r#"""""#) || unprefixed.starts_with(r#"'''"#);
|
unprefixed.starts_with(r#"""""#) || unprefixed.starts_with(r"'''");
|
||||||
if f_string.values.iter().any(|value| match value {
|
if f_string.values.iter().any(|value| match value {
|
||||||
Expr::FormattedValue(ast::ExprFormattedValue { range, .. }) => {
|
Expr::FormattedValue(ast::ExprFormattedValue { range, .. }) => {
|
||||||
let string_content = locator.slice(*range);
|
let string_content = locator.slice(*range);
|
||||||
|
|
|
@ -183,17 +183,17 @@ mod tests {
|
||||||
/// Very basic test intentionally kept very similar to the CLI
|
/// Very basic test intentionally kept very similar to the CLI
|
||||||
#[test]
|
#[test]
|
||||||
fn basic() -> Result<()> {
|
fn basic() -> Result<()> {
|
||||||
let input = r#"
|
let input = r"
|
||||||
# preceding
|
# preceding
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
# trailing
|
# trailing
|
||||||
"#;
|
";
|
||||||
let expected = r#"# preceding
|
let expected = r"# preceding
|
||||||
if True:
|
if True:
|
||||||
pass
|
pass
|
||||||
# trailing
|
# trailing
|
||||||
"#;
|
";
|
||||||
let actual = format_module_source(input, PyFormatOptions::default())?
|
let actual = format_module_source(input, PyFormatOptions::default())?
|
||||||
.as_code()
|
.as_code()
|
||||||
.to_string();
|
.to_string();
|
||||||
|
@ -241,11 +241,11 @@ def main() -> None:
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
printed.as_code(),
|
printed.as_code(),
|
||||||
r#"for converter in connection.ops.get_db_converters(
|
r"for converter in connection.ops.get_db_converters(
|
||||||
expression
|
expression
|
||||||
) + expression.get_db_converters(connection):
|
) + expression.get_db_converters(connection):
|
||||||
...
|
...
|
||||||
"#
|
"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,9 +304,9 @@ def main() -> None:
|
||||||
|
|
||||||
// 77 after g group (leading quote)
|
// 77 after g group (leading quote)
|
||||||
let fits =
|
let fits =
|
||||||
r#"aaaaaaaaaa bbbbbbbbbb cccccccccc dddddddddd eeeeeeeeee ffffffffff gggggggggg h"#;
|
r"aaaaaaaaaa bbbbbbbbbb cccccccccc dddddddddd eeeeeeeeee ffffffffff gggggggggg h";
|
||||||
let breaks =
|
let breaks =
|
||||||
r#"aaaaaaaaaa bbbbbbbbbb cccccccccc dddddddddd eeeeeeeeee ffffffffff gggggggggg hh"#;
|
r"aaaaaaaaaa bbbbbbbbbb cccccccccc dddddddddd eeeeeeeeee ffffffffff gggggggggg hh";
|
||||||
|
|
||||||
let output = format!(
|
let output = format!(
|
||||||
SimpleFormatContext::default(),
|
SimpleFormatContext::default(),
|
||||||
|
|
|
@ -685,7 +685,7 @@ mod tests {
|
||||||
use crate::PyFormatOptions;
|
use crate::PyFormatOptions;
|
||||||
|
|
||||||
fn format_suite(level: SuiteKind) -> String {
|
fn format_suite(level: SuiteKind) -> String {
|
||||||
let source = r#"
|
let source = r"
|
||||||
a = 10
|
a = 10
|
||||||
|
|
||||||
|
|
||||||
|
@ -704,7 +704,7 @@ def func():
|
||||||
pass
|
pass
|
||||||
def trailing_func():
|
def trailing_func():
|
||||||
pass
|
pass
|
||||||
"#;
|
";
|
||||||
|
|
||||||
let statements = parse_suite(source, "test.py").unwrap();
|
let statements = parse_suite(source, "test.py").unwrap();
|
||||||
|
|
||||||
|
@ -730,7 +730,7 @@ def trailing_func():
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
formatted,
|
formatted,
|
||||||
r#"a = 10
|
r"a = 10
|
||||||
|
|
||||||
|
|
||||||
three_leading_newlines = 80
|
three_leading_newlines = 80
|
||||||
|
@ -755,7 +755,7 @@ def func():
|
||||||
|
|
||||||
def trailing_func():
|
def trailing_func():
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,7 +765,7 @@ def trailing_func():
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
formatted,
|
formatted,
|
||||||
r#"a = 10
|
r"a = 10
|
||||||
|
|
||||||
three_leading_newlines = 80
|
three_leading_newlines = 80
|
||||||
|
|
||||||
|
@ -784,7 +784,7 @@ def func():
|
||||||
|
|
||||||
def trailing_func():
|
def trailing_func():
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,3 +23,6 @@ ruff_text_size = { path = "../ruff_text_size" }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -238,18 +238,18 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn continuation() {
|
fn continuation() {
|
||||||
let contents = r#"x = 1"#;
|
let contents = r"x = 1";
|
||||||
let lxr: Vec<LexResult> = lexer::lex(contents, Mode::Module).collect();
|
let lxr: Vec<LexResult> = lexer::lex(contents, Mode::Module).collect();
|
||||||
let indexer = Indexer::from_tokens(&lxr, &Locator::new(contents));
|
let indexer = Indexer::from_tokens(&lxr, &Locator::new(contents));
|
||||||
assert_eq!(indexer.continuation_line_starts(), &[]);
|
assert_eq!(indexer.continuation_line_starts(), &[]);
|
||||||
|
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
# Hello, world!
|
# Hello, world!
|
||||||
|
|
||||||
x = 1
|
x = 1
|
||||||
|
|
||||||
y = 2
|
y = 2
|
||||||
"#
|
"
|
||||||
.trim();
|
.trim();
|
||||||
|
|
||||||
let lxr: Vec<LexResult> = lexer::lex(contents, Mode::Module).collect();
|
let lxr: Vec<LexResult> = lexer::lex(contents, Mode::Module).collect();
|
||||||
|
|
|
@ -21,3 +21,6 @@ unic-ucd-category = "0.9"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -35,3 +35,6 @@ insta = { workspace = true }
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
lalrpop = { version = "0.20.0", default-features = false, optional = true }
|
lalrpop = { version = "0.20.0", default-features = false, optional = true }
|
||||||
tiny-keccak = { version = "2", features = ["sha3"] }
|
tiny-keccak = { version = "2", features = ["sha3"] }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -1973,9 +1973,9 @@ def f(arg=%timeit a = b):
|
||||||
#[test]
|
#[test]
|
||||||
fn tet_too_low_dedent() {
|
fn tet_too_low_dedent() {
|
||||||
let tokens: Vec<_> = lex(
|
let tokens: Vec<_> = lex(
|
||||||
r#"if True:
|
"if True:
|
||||||
pass
|
pass
|
||||||
pass"#,
|
pass",
|
||||||
Mode::Module,
|
Mode::Module,
|
||||||
)
|
)
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -2198,10 +2198,10 @@ f"{(lambda x:{x})}"
|
||||||
assert_eq!(lex_fstring_error(r#"f"""{""""#), UnclosedLbrace);
|
assert_eq!(lex_fstring_error(r#"f"""{""""#), UnclosedLbrace);
|
||||||
|
|
||||||
assert_eq!(lex_fstring_error(r#"f""#), UnterminatedString);
|
assert_eq!(lex_fstring_error(r#"f""#), UnterminatedString);
|
||||||
assert_eq!(lex_fstring_error(r#"f'"#), UnterminatedString);
|
assert_eq!(lex_fstring_error(r"f'"), UnterminatedString);
|
||||||
|
|
||||||
assert_eq!(lex_fstring_error(r#"f""""#), UnterminatedTripleQuotedString);
|
assert_eq!(lex_fstring_error(r#"f""""#), UnterminatedTripleQuotedString);
|
||||||
assert_eq!(lex_fstring_error(r#"f'''"#), UnterminatedTripleQuotedString);
|
assert_eq!(lex_fstring_error(r"f'''"), UnterminatedTripleQuotedString);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
lex_fstring_error(r#"f"""""#),
|
lex_fstring_error(r#"f"""""#),
|
||||||
UnterminatedTripleQuotedString
|
UnterminatedTripleQuotedString
|
||||||
|
|
|
@ -741,12 +741,12 @@ array[3:5, *indexes_to_select]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_try() {
|
fn test_try() {
|
||||||
let parse_ast = parse_suite(
|
let parse_ast = parse_suite(
|
||||||
r#"try:
|
r"try:
|
||||||
raise ValueError(1)
|
raise ValueError(1)
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
print(f'caught {type(e)}')
|
print(f'caught {type(e)}')
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
print(f'caught {type(e)}')"#,
|
print(f'caught {type(e)}')",
|
||||||
"<test>",
|
"<test>",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -865,7 +865,7 @@ x = type = 1
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn numeric_literals() {
|
fn numeric_literals() {
|
||||||
let source = r#"x = 123456789
|
let source = r"x = 123456789
|
||||||
x = 123456
|
x = 123456
|
||||||
x = .1
|
x = .1
|
||||||
x = 1.
|
x = 1.
|
||||||
|
@ -883,14 +883,14 @@ x = 0O777
|
||||||
x = 0.000000006
|
x = 0.000000006
|
||||||
x = 10000
|
x = 10000
|
||||||
x = 133333
|
x = 133333
|
||||||
"#;
|
";
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(parse_suite(source, "<test>").unwrap());
|
insta::assert_debug_snapshot!(parse_suite(source, "<test>").unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn numeric_literals_attribute_access() {
|
fn numeric_literals_attribute_access() {
|
||||||
let source = r#"x = .1.is_integer()
|
let source = r"x = .1.is_integer()
|
||||||
x = 1. .imag
|
x = 1. .imag
|
||||||
x = 1E+1.imag
|
x = 1E+1.imag
|
||||||
x = 1E-1.real
|
x = 1E-1.real
|
||||||
|
@ -910,7 +910,7 @@ if 10 .real:
|
||||||
|
|
||||||
y = 100[no]
|
y = 100[no]
|
||||||
y = 100(no)
|
y = 100(no)
|
||||||
"#;
|
";
|
||||||
assert_debug_snapshot!(parse_suite(source, "<test>").unwrap());
|
assert_debug_snapshot!(parse_suite(source, "<test>").unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1173,9 +1173,9 @@ match x:
|
||||||
#[test]
|
#[test]
|
||||||
fn test_variadic_generics() {
|
fn test_variadic_generics() {
|
||||||
let parse_ast = parse_suite(
|
let parse_ast = parse_suite(
|
||||||
r#"
|
r"
|
||||||
def args_to_tuple(*args: *Ts) -> Tuple[*Ts]: ...
|
def args_to_tuple(*args: *Ts) -> Tuple[*Ts]: ...
|
||||||
"#,
|
",
|
||||||
"<test>",
|
"<test>",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1185,7 +1185,7 @@ def args_to_tuple(*args: *Ts) -> Tuple[*Ts]: ...
|
||||||
#[test]
|
#[test]
|
||||||
fn decorator_ranges() {
|
fn decorator_ranges() {
|
||||||
let parse_ast = parse_suite(
|
let parse_ast = parse_suite(
|
||||||
r#"
|
r"
|
||||||
@my_decorator
|
@my_decorator
|
||||||
def test():
|
def test():
|
||||||
pass
|
pass
|
||||||
|
@ -1193,7 +1193,7 @@ def test():
|
||||||
@class_decorator
|
@class_decorator
|
||||||
class Abcd:
|
class Abcd:
|
||||||
pass
|
pass
|
||||||
"#
|
"
|
||||||
.trim(),
|
.trim(),
|
||||||
"<test>",
|
"<test>",
|
||||||
)
|
)
|
||||||
|
@ -1280,10 +1280,10 @@ foo.bar[0].baz[2].egg??
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ipython_escape_command_parse_error() {
|
fn test_ipython_escape_command_parse_error() {
|
||||||
let source = r#"
|
let source = r"
|
||||||
a = 1
|
a = 1
|
||||||
%timeit a == 1
|
%timeit a == 1
|
||||||
"#
|
"
|
||||||
.trim();
|
.trim();
|
||||||
let lxr = lexer::lex_starts_at(source, Mode::Ipython, TextSize::default());
|
let lxr = lexer::lex_starts_at(source, Mode::Ipython, TextSize::default());
|
||||||
let parse_err = parse_tokens(lxr, source, Mode::Module, "<test>").unwrap_err();
|
let parse_err = parse_tokens(lxr, source, Mode::Module, "<test>").unwrap_err();
|
||||||
|
|
|
@ -20,3 +20,6 @@ log = { workspace = true }
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
tempfile = "3.8.1"
|
tempfile = "3.8.1"
|
||||||
insta = { workspace = true }
|
insta = { workspace = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -116,7 +116,7 @@ fn find_paths_from_pth_files(parent_dir: &Path) -> io::Result<impl Iterator<Item
|
||||||
file_len > 0 && file_len < 64 * 1024
|
file_len > 0 && file_len < 64 * 1024
|
||||||
})
|
})
|
||||||
.filter_map(|path| {
|
.filter_map(|path| {
|
||||||
let data = fs::read_to_string(&path).ok()?;
|
let data = fs::read_to_string(path).ok()?;
|
||||||
for line in data.lines() {
|
for line in data.lines() {
|
||||||
let trimmed_line = line.trim();
|
let trimmed_line = line.trim();
|
||||||
if !trimmed_line.is_empty()
|
if !trimmed_line.is_empty()
|
||||||
|
|
|
@ -26,3 +26,6 @@ smallvec = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ruff_python_parser = { path = "../ruff_python_parser" }
|
ruff_python_parser = { path = "../ruff_python_parser" }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -14,3 +14,6 @@ license = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
unicode-ident = { workspace = true }
|
unicode-ident = { workspace = true }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -23,3 +23,6 @@ unicode-ident = { workspace = true }
|
||||||
insta = { workspace = true }
|
insta = { workspace = true }
|
||||||
ruff_python_ast = { path = "../ruff_python_ast" }
|
ruff_python_ast = { path = "../ruff_python_ast" }
|
||||||
ruff_python_parser = { path = "../ruff_python_parser" }
|
ruff_python_parser = { path = "../ruff_python_parser" }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -337,10 +337,10 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dedent_non_python_whitespace() {
|
fn dedent_non_python_whitespace() {
|
||||||
let text = r#" C = int(f.rea1,0],[-1,0,1]],
|
let text = r" C = int(f.rea1,0],[-1,0,1]],
|
||||||
[[-1,-1,1],[1,1,-1],[0,-1,0]],
|
[[-1,-1,1],[1,1,-1],[0,-1,0]],
|
||||||
[[-1,-1,-1],[1,1,0],[1,0,1]]
|
[[-1,-1,-1],[1,1,0],[1,0,1]]
|
||||||
]"#;
|
]";
|
||||||
assert_eq!(dedent(text), text);
|
assert_eq!(dedent(text), text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1184,9 +1184,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn tokenize_slash() {
|
fn tokenize_slash() {
|
||||||
let source = r#" # trailing positional comment
|
let source = r" # trailing positional comment
|
||||||
# Positional arguments only after here
|
# Positional arguments only after here
|
||||||
,/"#;
|
,/";
|
||||||
|
|
||||||
let test_case = tokenize(source);
|
let test_case = tokenize(source);
|
||||||
|
|
||||||
|
@ -1229,8 +1229,8 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn triple_quoted_multiline_string_containing_comment() {
|
fn triple_quoted_multiline_string_containing_comment() {
|
||||||
let test_case = tokenize(
|
let test_case = tokenize(
|
||||||
r#"'''This string contains a hash looking like a comment
|
r"'''This string contains a hash looking like a comment
|
||||||
# This is not a comment'''"#,
|
# This is not a comment'''",
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_debug_snapshot!(test_case.tokenize_reverse());
|
assert_debug_snapshot!(test_case.tokenize_reverse());
|
||||||
|
@ -1274,7 +1274,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn empty_string_literal() {
|
fn empty_string_literal() {
|
||||||
let test_case = tokenize(r#"'' # a comment '"#);
|
let test_case = tokenize(r"'' # a comment '");
|
||||||
|
|
||||||
assert_debug_snapshot!(test_case.tokenize_reverse());
|
assert_debug_snapshot!(test_case.tokenize_reverse());
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,10 +114,10 @@ mod tests {
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
assert!(!has_trailing_content(stmt.end(), &locator));
|
assert!(!has_trailing_content(stmt.end(), &locator));
|
||||||
|
|
||||||
let contents = r#"
|
let contents = r"
|
||||||
x = 1
|
x = 1
|
||||||
y = 2
|
y = 2
|
||||||
"#
|
"
|
||||||
.trim();
|
.trim();
|
||||||
let program = parse_suite(contents, "<filename>")?;
|
let program = parse_suite(contents, "<filename>")?;
|
||||||
let stmt = program.first().unwrap();
|
let stmt = program.first().unwrap();
|
||||||
|
|
|
@ -16,3 +16,6 @@ ruff_text_size = { path = "../ruff_text_size" }
|
||||||
shlex = "1.2.0"
|
shlex = "1.2.0"
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
tracing-subscriber = { workspace = true, features = ["env-filter"] }
|
tracing-subscriber = { workspace = true, features = ["env-filter"] }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -21,6 +21,8 @@ serde = { workspace = true, optional = true }
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
insta = { workspace = true }
|
insta = { workspace = true }
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
serde = ["dep:serde", "ruff_text_size/serde"]
|
serde = ["dep:serde", "ruff_text_size/serde"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -16,6 +16,9 @@ static_assertions = { version = "1.1.0" }
|
||||||
[features]
|
[features]
|
||||||
serde = ["dep:serde"]
|
serde = ["dep:serde"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[[test]]
|
[[test]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
path = "tests/serde.rs"
|
path = "tests/serde.rs"
|
||||||
|
|
|
@ -42,3 +42,6 @@ js-sys = { version = "0.3.61" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
wasm-bindgen-test = { version = "0.3.34" }
|
wasm-bindgen-test = { version = "0.3.34" }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -44,8 +44,9 @@ toml = { workspace = true }
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3.8.1"
|
tempfile = "3.8.1"
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
default = []
|
||||||
schemars = [ "dep:schemars", "ruff_formatter/schemars", "ruff_python_formatter/schemars" ]
|
schemars = [ "dep:schemars", "ruff_formatter/schemars", "ruff_python_formatter/schemars" ]
|
||||||
|
|
||||||
default = []
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
|
@ -169,21 +169,21 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
|
|
||||||
fn deserialize() -> Result<()> {
|
fn deserialize() -> Result<()> {
|
||||||
let pyproject: Pyproject = toml::from_str(r#""#)?;
|
let pyproject: Pyproject = toml::from_str(r"")?;
|
||||||
assert_eq!(pyproject.tool, None);
|
assert_eq!(pyproject.tool, None);
|
||||||
|
|
||||||
let pyproject: Pyproject = toml::from_str(
|
let pyproject: Pyproject = toml::from_str(
|
||||||
r#"
|
r"
|
||||||
[tool.black]
|
[tool.black]
|
||||||
"#,
|
",
|
||||||
)?;
|
)?;
|
||||||
assert_eq!(pyproject.tool, Some(Tools { ruff: None }));
|
assert_eq!(pyproject.tool, Some(Tools { ruff: None }));
|
||||||
|
|
||||||
let pyproject: Pyproject = toml::from_str(
|
let pyproject: Pyproject = toml::from_str(
|
||||||
r#"
|
r"
|
||||||
[tool.black]
|
[tool.black]
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
"#,
|
",
|
||||||
)?;
|
)?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pyproject.tool,
|
pyproject.tool,
|
||||||
|
@ -193,11 +193,11 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let pyproject: Pyproject = toml::from_str(
|
let pyproject: Pyproject = toml::from_str(
|
||||||
r#"
|
r"
|
||||||
[tool.black]
|
[tool.black]
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line-length = 79
|
line-length = 79
|
||||||
"#,
|
",
|
||||||
)?;
|
)?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pyproject.tool,
|
pyproject.tool,
|
||||||
|
@ -275,11 +275,11 @@ ignore = ["E501"]
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(toml::from_str::<Pyproject>(
|
assert!(toml::from_str::<Pyproject>(
|
||||||
r#"
|
r"
|
||||||
[tool.black]
|
[tool.black]
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line_length = 79
|
line_length = 79
|
||||||
"#,
|
",
|
||||||
)
|
)
|
||||||
.is_err());
|
.is_err());
|
||||||
|
|
||||||
|
@ -293,12 +293,12 @@ select = ["E123"]
|
||||||
.is_err());
|
.is_err());
|
||||||
|
|
||||||
assert!(toml::from_str::<Pyproject>(
|
assert!(toml::from_str::<Pyproject>(
|
||||||
r#"
|
r"
|
||||||
[tool.black]
|
[tool.black]
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line-length = 79
|
line-length = 79
|
||||||
other-attribute = 1
|
other-attribute = 1
|
||||||
"#,
|
",
|
||||||
)
|
)
|
||||||
.is_err());
|
.is_err());
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "1.73"
|
channel = "1.74"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue