mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-31 15:47:41 +00:00
Upgrade RustPython (#5192)
## Summary This PR upgrade RustPython to pull in the changes to `Arguments` (zip defaults with their identifiers) and all the renames to `CmpOp` and friends.
This commit is contained in:
parent
ddfdc3bb01
commit
36e01ad6eb
103 changed files with 1291 additions and 1165 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -2105,7 +2105,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruff_text_size"
|
name = "ruff_text_size"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=0dc8fdf52d146698c5bcf0b842fddc9e398ad8db#0dc8fdf52d146698c5bcf0b842fddc9e398ad8db"
|
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=8d74eee75031b68d2204219963fae54a3f31a394#8d74eee75031b68d2204219963fae54a3f31a394"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -2183,7 +2183,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustpython-ast"
|
name = "rustpython-ast"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=0dc8fdf52d146698c5bcf0b842fddc9e398ad8db#0dc8fdf52d146698c5bcf0b842fddc9e398ad8db"
|
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=8d74eee75031b68d2204219963fae54a3f31a394#8d74eee75031b68d2204219963fae54a3f31a394"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"is-macro",
|
"is-macro",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
|
@ -2194,7 +2194,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustpython-format"
|
name = "rustpython-format"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=0dc8fdf52d146698c5bcf0b842fddc9e398ad8db#0dc8fdf52d146698c5bcf0b842fddc9e398ad8db"
|
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=8d74eee75031b68d2204219963fae54a3f31a394#8d74eee75031b68d2204219963fae54a3f31a394"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.3.1",
|
"bitflags 2.3.1",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
@ -2206,7 +2206,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustpython-literal"
|
name = "rustpython-literal"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=0dc8fdf52d146698c5bcf0b842fddc9e398ad8db#0dc8fdf52d146698c5bcf0b842fddc9e398ad8db"
|
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=8d74eee75031b68d2204219963fae54a3f31a394#8d74eee75031b68d2204219963fae54a3f31a394"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hexf-parse",
|
"hexf-parse",
|
||||||
"is-macro",
|
"is-macro",
|
||||||
|
@ -2218,7 +2218,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustpython-parser"
|
name = "rustpython-parser"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=0dc8fdf52d146698c5bcf0b842fddc9e398ad8db#0dc8fdf52d146698c5bcf0b842fddc9e398ad8db"
|
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=8d74eee75031b68d2204219963fae54a3f31a394#8d74eee75031b68d2204219963fae54a3f31a394"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"is-macro",
|
"is-macro",
|
||||||
|
@ -2241,9 +2241,10 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustpython-parser-core"
|
name = "rustpython-parser-core"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=0dc8fdf52d146698c5bcf0b842fddc9e398ad8db#0dc8fdf52d146698c5bcf0b842fddc9e398ad8db"
|
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=8d74eee75031b68d2204219963fae54a3f31a394#8d74eee75031b68d2204219963fae54a3f31a394"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"is-macro",
|
"is-macro",
|
||||||
|
"memchr",
|
||||||
"ruff_text_size",
|
"ruff_text_size",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -36,11 +36,11 @@ proc-macro2 = { version = "1.0.51" }
|
||||||
quote = { version = "1.0.23" }
|
quote = { version = "1.0.23" }
|
||||||
regex = { version = "1.7.1" }
|
regex = { version = "1.7.1" }
|
||||||
rustc-hash = { version = "1.1.0" }
|
rustc-hash = { version = "1.1.0" }
|
||||||
ruff_text_size = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "0dc8fdf52d146698c5bcf0b842fddc9e398ad8db" }
|
ruff_text_size = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "8d74eee75031b68d2204219963fae54a3f31a394" }
|
||||||
rustpython-ast = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "0dc8fdf52d146698c5bcf0b842fddc9e398ad8db", default-features = false, features = ["all-nodes-with-ranges"]}
|
rustpython-ast = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "8d74eee75031b68d2204219963fae54a3f31a394" , default-features = false, features = ["all-nodes-with-ranges", "num-bigint"]}
|
||||||
rustpython-format = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "0dc8fdf52d146698c5bcf0b842fddc9e398ad8db" }
|
rustpython-format = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "8d74eee75031b68d2204219963fae54a3f31a394", default-features = false, features = ["num-bigint"] }
|
||||||
rustpython-literal = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "0dc8fdf52d146698c5bcf0b842fddc9e398ad8db" }
|
rustpython-literal = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "8d74eee75031b68d2204219963fae54a3f31a394" }
|
||||||
rustpython-parser = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "0dc8fdf52d146698c5bcf0b842fddc9e398ad8db", default-features = false, features = ["full-lexer", "all-nodes-with-ranges"] }
|
rustpython-parser = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "8d74eee75031b68d2204219963fae54a3f31a394" , default-features = false, features = ["full-lexer", "all-nodes-with-ranges", "num-bigint"] }
|
||||||
schemars = { version = "0.8.12" }
|
schemars = { version = "0.8.12" }
|
||||||
serde = { version = "1.0.152", features = ["derive"] }
|
serde = { version = "1.0.152", features = ["derive"] }
|
||||||
serde_json = { version = "1.0.93" }
|
serde_json = { version = "1.0.93" }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Interface for generating autofix edits from higher-level actions (e.g., "remove an argument").
|
//! Interface for generating autofix edits from higher-level actions (e.g., "remove an argument").
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Expr, Keyword, Ranged, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, Expr, Keyword, Ranged, Stmt};
|
||||||
use rustpython_parser::{lexer, Mode, Tok};
|
use rustpython_parser::{lexer, Mode, Tok};
|
||||||
|
|
||||||
use ruff_diagnostics::Edit;
|
use ruff_diagnostics::Edit;
|
||||||
|
@ -218,7 +218,7 @@ fn is_lone_child(child: &Stmt, parent: &Stmt) -> bool {
|
||||||
|| is_only(orelse, child)
|
|| is_only(orelse, child)
|
||||||
|| is_only(finalbody, child)
|
|| is_only(finalbody, child)
|
||||||
|| handlers.iter().any(|handler| match handler {
|
|| handlers.iter().any(|handler| match handler {
|
||||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||||
body, ..
|
body, ..
|
||||||
}) => is_only(body, child),
|
}) => is_only(body, child),
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,8 +5,8 @@ use log::error;
|
||||||
use ruff_text_size::{TextRange, TextSize};
|
use ruff_text_size::{TextRange, TextSize};
|
||||||
use rustpython_format::cformat::{CFormatError, CFormatErrorType};
|
use rustpython_format::cformat::{CFormatError, CFormatErrorType};
|
||||||
use rustpython_parser::ast::{
|
use rustpython_parser::ast::{
|
||||||
self, Arg, Arguments, Comprehension, Constant, Excepthandler, Expr, ExprContext, Keyword,
|
self, Arg, ArgWithDefault, Arguments, Comprehension, Constant, ExceptHandler, Expr,
|
||||||
Operator, Pattern, Ranged, Stmt, Suite, Unaryop,
|
ExprContext, Keyword, Operator, Pattern, Ranged, Stmt, Suite, UnaryOp,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Fix, IsolationLevel};
|
use ruff_diagnostics::{Diagnostic, Fix, IsolationLevel};
|
||||||
|
@ -17,7 +17,7 @@ use ruff_python_ast::source_code::{Generator, Indexer, Locator, Quote, Stylist};
|
||||||
use ruff_python_ast::str::trailing_quote;
|
use ruff_python_ast::str::trailing_quote;
|
||||||
use ruff_python_ast::types::Node;
|
use ruff_python_ast::types::Node;
|
||||||
use ruff_python_ast::typing::{parse_type_annotation, AnnotationKind};
|
use ruff_python_ast::typing::{parse_type_annotation, AnnotationKind};
|
||||||
use ruff_python_ast::visitor::{walk_excepthandler, walk_pattern, Visitor};
|
use ruff_python_ast::visitor::{walk_except_handler, walk_pattern, Visitor};
|
||||||
use ruff_python_ast::{cast, helpers, identifier, str, visitor};
|
use ruff_python_ast::{cast, helpers, identifier, str, visitor};
|
||||||
use ruff_python_semantic::analyze::{branch_detection, typing, visibility};
|
use ruff_python_semantic::analyze::{branch_detection, typing, visibility};
|
||||||
use ruff_python_semantic::{
|
use ruff_python_semantic::{
|
||||||
|
@ -1759,22 +1759,21 @@ where
|
||||||
// are enabled.
|
// are enabled.
|
||||||
let runtime_annotation = !self.semantic.future_annotations();
|
let runtime_annotation = !self.semantic.future_annotations();
|
||||||
|
|
||||||
for arg in &args.posonlyargs {
|
for arg_with_default in args
|
||||||
if let Some(expr) = &arg.annotation {
|
.posonlyargs
|
||||||
|
.iter()
|
||||||
|
.chain(&args.args)
|
||||||
|
.chain(&args.kwonlyargs)
|
||||||
|
{
|
||||||
|
if let Some(expr) = &arg_with_default.def.annotation {
|
||||||
if runtime_annotation {
|
if runtime_annotation {
|
||||||
self.visit_type_definition(expr);
|
self.visit_type_definition(expr);
|
||||||
} else {
|
} else {
|
||||||
self.visit_annotation(expr);
|
self.visit_annotation(expr);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
if let Some(expr) = &arg_with_default.default {
|
||||||
for arg in &args.args {
|
self.visit_expr(expr);
|
||||||
if let Some(expr) = &arg.annotation {
|
|
||||||
if runtime_annotation {
|
|
||||||
self.visit_type_definition(expr);
|
|
||||||
} else {
|
|
||||||
self.visit_annotation(expr);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(arg) = &args.vararg {
|
if let Some(arg) = &args.vararg {
|
||||||
|
@ -1786,15 +1785,6 @@ where
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for arg in &args.kwonlyargs {
|
|
||||||
if let Some(expr) = &arg.annotation {
|
|
||||||
if runtime_annotation {
|
|
||||||
self.visit_type_definition(expr);
|
|
||||||
} else {
|
|
||||||
self.visit_annotation(expr);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(arg) = &args.kwarg {
|
if let Some(arg) = &args.kwarg {
|
||||||
if let Some(expr) = &arg.annotation {
|
if let Some(expr) = &arg.annotation {
|
||||||
if runtime_annotation {
|
if runtime_annotation {
|
||||||
|
@ -1811,12 +1801,6 @@ where
|
||||||
self.visit_annotation(expr);
|
self.visit_annotation(expr);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
for expr in &args.kw_defaults {
|
|
||||||
self.visit_expr(expr);
|
|
||||||
}
|
|
||||||
for expr in &args.defaults {
|
|
||||||
self.visit_expr(expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.add_binding(
|
self.add_binding(
|
||||||
name,
|
name,
|
||||||
|
@ -1929,8 +1913,8 @@ where
|
||||||
self.semantic.handled_exceptions.pop();
|
self.semantic.handled_exceptions.pop();
|
||||||
|
|
||||||
self.semantic.flags |= SemanticModelFlags::EXCEPTION_HANDLER;
|
self.semantic.flags |= SemanticModelFlags::EXCEPTION_HANDLER;
|
||||||
for excepthandler in handlers {
|
for except_handler in handlers {
|
||||||
self.visit_excepthandler(excepthandler);
|
self.visit_except_handler(except_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.visit_body(orelse);
|
self.visit_body(orelse);
|
||||||
|
@ -2100,7 +2084,7 @@ where
|
||||||
expr,
|
expr,
|
||||||
Expr::BoolOp(_)
|
Expr::BoolOp(_)
|
||||||
| Expr::UnaryOp(ast::ExprUnaryOp {
|
| Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::Not,
|
op: UnaryOp::Not,
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
) {
|
) {
|
||||||
|
@ -3301,12 +3285,21 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visit the default arguments, but avoid the body, which will be deferred.
|
// Visit the default arguments, but avoid the body, which will be deferred.
|
||||||
for expr in &args.kw_defaults {
|
for ArgWithDefault {
|
||||||
self.visit_expr(expr);
|
default,
|
||||||
}
|
def: _,
|
||||||
for expr in &args.defaults {
|
range: _,
|
||||||
self.visit_expr(expr);
|
} in args
|
||||||
|
.posonlyargs
|
||||||
|
.iter()
|
||||||
|
.chain(&args.args)
|
||||||
|
.chain(&args.kwonlyargs)
|
||||||
|
{
|
||||||
|
if let Some(expr) = &default {
|
||||||
|
self.visit_expr(expr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.semantic.push_scope(ScopeKind::Lambda(lambda));
|
self.semantic.push_scope(ScopeKind::Lambda(lambda));
|
||||||
}
|
}
|
||||||
Expr::IfExp(ast::ExprIfExp {
|
Expr::IfExp(ast::ExprIfExp {
|
||||||
|
@ -3794,9 +3787,9 @@ where
|
||||||
self.semantic.pop_expr();
|
self.semantic.pop_expr();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_excepthandler(&mut self, excepthandler: &'b Excepthandler) {
|
fn visit_except_handler(&mut self, except_handler: &'b ExceptHandler) {
|
||||||
match excepthandler {
|
match except_handler {
|
||||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||||
type_,
|
type_,
|
||||||
name,
|
name,
|
||||||
body,
|
body,
|
||||||
|
@ -3807,7 +3800,7 @@ where
|
||||||
if let Some(diagnostic) = pycodestyle::rules::bare_except(
|
if let Some(diagnostic) = pycodestyle::rules::bare_except(
|
||||||
type_.as_deref(),
|
type_.as_deref(),
|
||||||
body,
|
body,
|
||||||
excepthandler,
|
except_handler,
|
||||||
self.locator,
|
self.locator,
|
||||||
) {
|
) {
|
||||||
self.diagnostics.push(diagnostic);
|
self.diagnostics.push(diagnostic);
|
||||||
|
@ -3822,7 +3815,7 @@ where
|
||||||
if self.enabled(Rule::TryExceptPass) {
|
if self.enabled(Rule::TryExceptPass) {
|
||||||
flake8_bandit::rules::try_except_pass(
|
flake8_bandit::rules::try_except_pass(
|
||||||
self,
|
self,
|
||||||
excepthandler,
|
except_handler,
|
||||||
type_.as_deref(),
|
type_.as_deref(),
|
||||||
name,
|
name,
|
||||||
body,
|
body,
|
||||||
|
@ -3832,7 +3825,7 @@ where
|
||||||
if self.enabled(Rule::TryExceptContinue) {
|
if self.enabled(Rule::TryExceptContinue) {
|
||||||
flake8_bandit::rules::try_except_continue(
|
flake8_bandit::rules::try_except_continue(
|
||||||
self,
|
self,
|
||||||
excepthandler,
|
except_handler,
|
||||||
type_.as_deref(),
|
type_.as_deref(),
|
||||||
name,
|
name,
|
||||||
body,
|
body,
|
||||||
|
@ -3840,20 +3833,20 @@ where
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if self.enabled(Rule::ExceptWithEmptyTuple) {
|
if self.enabled(Rule::ExceptWithEmptyTuple) {
|
||||||
flake8_bugbear::rules::except_with_empty_tuple(self, excepthandler);
|
flake8_bugbear::rules::except_with_empty_tuple(self, except_handler);
|
||||||
}
|
}
|
||||||
if self.enabled(Rule::ExceptWithNonExceptionClasses) {
|
if self.enabled(Rule::ExceptWithNonExceptionClasses) {
|
||||||
flake8_bugbear::rules::except_with_non_exception_classes(self, excepthandler);
|
flake8_bugbear::rules::except_with_non_exception_classes(self, except_handler);
|
||||||
}
|
}
|
||||||
if self.enabled(Rule::ReraiseNoCause) {
|
if self.enabled(Rule::ReraiseNoCause) {
|
||||||
tryceratops::rules::reraise_no_cause(self, body);
|
tryceratops::rules::reraise_no_cause(self, body);
|
||||||
}
|
}
|
||||||
if self.enabled(Rule::BinaryOpException) {
|
if self.enabled(Rule::BinaryOpException) {
|
||||||
pylint::rules::binary_op_exception(self, excepthandler);
|
pylint::rules::binary_op_exception(self, except_handler);
|
||||||
}
|
}
|
||||||
match name {
|
match name {
|
||||||
Some(name) => {
|
Some(name) => {
|
||||||
let range = excepthandler.try_identifier(self.locator).unwrap();
|
let range = except_handler.try_identifier(self.locator).unwrap();
|
||||||
|
|
||||||
if self.enabled(Rule::AmbiguousVariableName) {
|
if self.enabled(Rule::AmbiguousVariableName) {
|
||||||
if let Some(diagnostic) =
|
if let Some(diagnostic) =
|
||||||
|
@ -3866,7 +3859,7 @@ where
|
||||||
flake8_builtins::rules::builtin_variable_shadowing(
|
flake8_builtins::rules::builtin_variable_shadowing(
|
||||||
self,
|
self,
|
||||||
name,
|
name,
|
||||||
AnyShadowing::from(excepthandler),
|
AnyShadowing::from(except_handler),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3878,7 +3871,7 @@ where
|
||||||
BindingFlags::empty(),
|
BindingFlags::empty(),
|
||||||
);
|
);
|
||||||
|
|
||||||
walk_excepthandler(self, excepthandler);
|
walk_except_handler(self, except_handler);
|
||||||
|
|
||||||
// Remove it from the scope immediately after.
|
// Remove it from the scope immediately after.
|
||||||
self.add_binding(
|
self.add_binding(
|
||||||
|
@ -3898,7 +3891,7 @@ where
|
||||||
if self.patch(Rule::UnusedVariable) {
|
if self.patch(Rule::UnusedVariable) {
|
||||||
diagnostic.try_set_fix(|| {
|
diagnostic.try_set_fix(|| {
|
||||||
pyflakes::fixes::remove_exception_handler_assignment(
|
pyflakes::fixes::remove_exception_handler_assignment(
|
||||||
excepthandler,
|
except_handler,
|
||||||
self.locator,
|
self.locator,
|
||||||
)
|
)
|
||||||
.map(Fix::automatic)
|
.map(Fix::automatic)
|
||||||
|
@ -3908,7 +3901,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => walk_excepthandler(self, excepthandler),
|
None => walk_except_handler(self, except_handler),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3946,17 +3939,17 @@ where
|
||||||
|
|
||||||
// Bind, but intentionally avoid walking default expressions, as we handle them
|
// Bind, but intentionally avoid walking default expressions, as we handle them
|
||||||
// upstream.
|
// upstream.
|
||||||
for arg in &arguments.posonlyargs {
|
for arg_with_default in &arguments.posonlyargs {
|
||||||
self.visit_arg(arg);
|
self.visit_arg(&arg_with_default.def);
|
||||||
}
|
}
|
||||||
for arg in &arguments.args {
|
for arg_with_default in &arguments.args {
|
||||||
self.visit_arg(arg);
|
self.visit_arg(&arg_with_default.def);
|
||||||
}
|
}
|
||||||
if let Some(arg) = &arguments.vararg {
|
if let Some(arg) = &arguments.vararg {
|
||||||
self.visit_arg(arg);
|
self.visit_arg(arg);
|
||||||
}
|
}
|
||||||
for arg in &arguments.kwonlyargs {
|
for arg_with_default in &arguments.kwonlyargs {
|
||||||
self.visit_arg(arg);
|
self.visit_arg(&arg_with_default.def);
|
||||||
}
|
}
|
||||||
if let Some(arg) = &arguments.kwarg {
|
if let Some(arg) = &arguments.kwarg {
|
||||||
self.visit_arg(arg);
|
self.visit_arg(arg);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use rustpython_parser::ast::{self, Cmpop, Constant, Expr, Ranged};
|
use rustpython_parser::ast::{self, CmpOp, Constant, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -66,7 +66,7 @@ impl Violation for SysVersionCmpStr10 {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// YTT103, YTT201, YTT203, YTT204, YTT302
|
/// YTT103, YTT201, YTT203, YTT204, YTT302
|
||||||
pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &[Expr]) {
|
pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[CmpOp], comparators: &[Expr]) {
|
||||||
match left {
|
match left {
|
||||||
Expr::Subscript(ast::ExprSubscript { value, slice, .. })
|
Expr::Subscript(ast::ExprSubscript { value, slice, .. })
|
||||||
if is_sys(value, "version_info", checker.semantic()) =>
|
if is_sys(value, "version_info", checker.semantic()) =>
|
||||||
|
@ -78,7 +78,7 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], compara
|
||||||
{
|
{
|
||||||
if *i == BigInt::from(0) {
|
if *i == BigInt::from(0) {
|
||||||
if let (
|
if let (
|
||||||
[Cmpop::Eq | Cmpop::NotEq],
|
[CmpOp::Eq | CmpOp::NotEq],
|
||||||
[Expr::Constant(ast::ExprConstant {
|
[Expr::Constant(ast::ExprConstant {
|
||||||
value: Constant::Int(n),
|
value: Constant::Int(n),
|
||||||
..
|
..
|
||||||
|
@ -93,7 +93,7 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], compara
|
||||||
}
|
}
|
||||||
} else if *i == BigInt::from(1) {
|
} else if *i == BigInt::from(1) {
|
||||||
if let (
|
if let (
|
||||||
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
[CmpOp::Lt | CmpOp::LtE | CmpOp::Gt | CmpOp::GtE],
|
||||||
[Expr::Constant(ast::ExprConstant {
|
[Expr::Constant(ast::ExprConstant {
|
||||||
value: Constant::Int(_),
|
value: Constant::Int(_),
|
||||||
..
|
..
|
||||||
|
@ -114,7 +114,7 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], compara
|
||||||
if is_sys(value, "version_info", checker.semantic()) && attr == "minor" =>
|
if is_sys(value, "version_info", checker.semantic()) && attr == "minor" =>
|
||||||
{
|
{
|
||||||
if let (
|
if let (
|
||||||
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
[CmpOp::Lt | CmpOp::LtE | CmpOp::Gt | CmpOp::GtE],
|
||||||
[Expr::Constant(ast::ExprConstant {
|
[Expr::Constant(ast::ExprConstant {
|
||||||
value: Constant::Int(_),
|
value: Constant::Int(_),
|
||||||
..
|
..
|
||||||
|
@ -134,7 +134,7 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], compara
|
||||||
|
|
||||||
if is_sys(left, "version", checker.semantic()) {
|
if is_sys(left, "version", checker.semantic()) {
|
||||||
if let (
|
if let (
|
||||||
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
[CmpOp::Lt | CmpOp::LtE | CmpOp::Gt | CmpOp::GtE],
|
||||||
[Expr::Constant(ast::ExprConstant {
|
[Expr::Constant(ast::ExprConstant {
|
||||||
value: Constant::Str(s),
|
value: Constant::Str(s),
|
||||||
..
|
..
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{Expr, Ranged, Stmt};
|
use rustpython_parser::ast::{ArgWithDefault, Expr, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix, Violation};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -471,7 +471,7 @@ pub(crate) fn definition(
|
||||||
_ => return vec![],
|
_ => return vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
let (name, args, returns, body, decorator_list) = match_function_def(stmt);
|
let (name, arguments, returns, body, decorator_list) = match_function_def(stmt);
|
||||||
// Keep track of whether we've seen any typed arguments or return values.
|
// Keep track of whether we've seen any typed arguments or return values.
|
||||||
let mut has_any_typed_arg = false; // Any argument has been typed?
|
let mut has_any_typed_arg = false; // Any argument has been typed?
|
||||||
let mut has_typed_return = false; // Return value has been typed?
|
let mut has_typed_return = false; // Return value has been typed?
|
||||||
|
@ -484,11 +484,15 @@ pub(crate) fn definition(
|
||||||
let is_overridden = visibility::is_override(decorator_list, checker.semantic());
|
let is_overridden = visibility::is_override(decorator_list, checker.semantic());
|
||||||
|
|
||||||
// ANN001, ANN401
|
// ANN001, ANN401
|
||||||
for arg in args
|
for ArgWithDefault {
|
||||||
|
def,
|
||||||
|
default: _,
|
||||||
|
range: _,
|
||||||
|
} in arguments
|
||||||
.posonlyargs
|
.posonlyargs
|
||||||
.iter()
|
.iter()
|
||||||
.chain(args.args.iter())
|
.chain(&arguments.args)
|
||||||
.chain(args.kwonlyargs.iter())
|
.chain(&arguments.kwonlyargs)
|
||||||
.skip(
|
.skip(
|
||||||
// If this is a non-static method, skip `cls` or `self`.
|
// If this is a non-static method, skip `cls` or `self`.
|
||||||
usize::from(
|
usize::from(
|
||||||
|
@ -498,12 +502,12 @@ pub(crate) fn definition(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// ANN401 for dynamically typed arguments
|
// ANN401 for dynamically typed arguments
|
||||||
if let Some(annotation) = &arg.annotation {
|
if let Some(annotation) = &def.annotation {
|
||||||
has_any_typed_arg = true;
|
has_any_typed_arg = true;
|
||||||
if checker.enabled(Rule::AnyType) {
|
if checker.enabled(Rule::AnyType) {
|
||||||
check_dynamically_typed(
|
check_dynamically_typed(
|
||||||
annotation,
|
annotation,
|
||||||
|| arg.arg.to_string(),
|
|| def.arg.to_string(),
|
||||||
&mut diagnostics,
|
&mut diagnostics,
|
||||||
is_overridden,
|
is_overridden,
|
||||||
checker.semantic(),
|
checker.semantic(),
|
||||||
|
@ -511,14 +515,14 @@ pub(crate) fn definition(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !(checker.settings.flake8_annotations.suppress_dummy_args
|
if !(checker.settings.flake8_annotations.suppress_dummy_args
|
||||||
&& checker.settings.dummy_variable_rgx.is_match(&arg.arg))
|
&& checker.settings.dummy_variable_rgx.is_match(&def.arg))
|
||||||
{
|
{
|
||||||
if checker.enabled(Rule::MissingTypeFunctionArgument) {
|
if checker.enabled(Rule::MissingTypeFunctionArgument) {
|
||||||
diagnostics.push(Diagnostic::new(
|
diagnostics.push(Diagnostic::new(
|
||||||
MissingTypeFunctionArgument {
|
MissingTypeFunctionArgument {
|
||||||
name: arg.arg.to_string(),
|
name: def.arg.to_string(),
|
||||||
},
|
},
|
||||||
arg.range(),
|
def.range(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -526,7 +530,7 @@ pub(crate) fn definition(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANN002, ANN401
|
// ANN002, ANN401
|
||||||
if let Some(arg) = &args.vararg {
|
if let Some(arg) = &arguments.vararg {
|
||||||
if let Some(expr) = &arg.annotation {
|
if let Some(expr) = &arg.annotation {
|
||||||
has_any_typed_arg = true;
|
has_any_typed_arg = true;
|
||||||
if !checker.settings.flake8_annotations.allow_star_arg_any {
|
if !checker.settings.flake8_annotations.allow_star_arg_any {
|
||||||
|
@ -558,7 +562,7 @@ pub(crate) fn definition(
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANN003, ANN401
|
// ANN003, ANN401
|
||||||
if let Some(arg) = &args.kwarg {
|
if let Some(arg) = &arguments.kwarg {
|
||||||
if let Some(expr) = &arg.annotation {
|
if let Some(expr) = &arg.annotation {
|
||||||
has_any_typed_arg = true;
|
has_any_typed_arg = true;
|
||||||
if !checker.settings.flake8_annotations.allow_star_arg_any {
|
if !checker.settings.flake8_annotations.allow_star_arg_any {
|
||||||
|
@ -591,24 +595,32 @@ pub(crate) fn definition(
|
||||||
|
|
||||||
// ANN101, ANN102
|
// ANN101, ANN102
|
||||||
if is_method && !visibility::is_staticmethod(cast::decorator_list(stmt), checker.semantic()) {
|
if is_method && !visibility::is_staticmethod(cast::decorator_list(stmt), checker.semantic()) {
|
||||||
if let Some(arg) = args.posonlyargs.first().or_else(|| args.args.first()) {
|
if let Some(ArgWithDefault {
|
||||||
if arg.annotation.is_none() {
|
def,
|
||||||
|
default: _,
|
||||||
|
range: _,
|
||||||
|
}) = arguments
|
||||||
|
.posonlyargs
|
||||||
|
.first()
|
||||||
|
.or_else(|| arguments.args.first())
|
||||||
|
{
|
||||||
|
if def.annotation.is_none() {
|
||||||
if visibility::is_classmethod(cast::decorator_list(stmt), checker.semantic()) {
|
if visibility::is_classmethod(cast::decorator_list(stmt), checker.semantic()) {
|
||||||
if checker.enabled(Rule::MissingTypeCls) {
|
if checker.enabled(Rule::MissingTypeCls) {
|
||||||
diagnostics.push(Diagnostic::new(
|
diagnostics.push(Diagnostic::new(
|
||||||
MissingTypeCls {
|
MissingTypeCls {
|
||||||
name: arg.arg.to_string(),
|
name: def.arg.to_string(),
|
||||||
},
|
},
|
||||||
arg.range(),
|
def.range(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if checker.enabled(Rule::MissingTypeSelf) {
|
if checker.enabled(Rule::MissingTypeSelf) {
|
||||||
diagnostics.push(Diagnostic::new(
|
diagnostics.push(Diagnostic::new(
|
||||||
MissingTypeSelf {
|
MissingTypeSelf {
|
||||||
name: arg.arg.to_string(),
|
name: def.arg.to_string(),
|
||||||
},
|
},
|
||||||
arg.range(),
|
def.range(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{Arg, Arguments, Expr, Ranged};
|
use rustpython_parser::ast::{Arg, ArgWithDefault, Arguments, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -39,29 +39,21 @@ fn check_password_kwarg(arg: &Arg, default: &Expr) -> Option<Diagnostic> {
|
||||||
pub(crate) fn hardcoded_password_default(arguments: &Arguments) -> Vec<Diagnostic> {
|
pub(crate) fn hardcoded_password_default(arguments: &Arguments) -> Vec<Diagnostic> {
|
||||||
let mut diagnostics: Vec<Diagnostic> = Vec::new();
|
let mut diagnostics: Vec<Diagnostic> = Vec::new();
|
||||||
|
|
||||||
let defaults_start =
|
for ArgWithDefault {
|
||||||
arguments.posonlyargs.len() + arguments.args.len() - arguments.defaults.len();
|
def,
|
||||||
for (i, arg) in arguments
|
default,
|
||||||
|
range: _,
|
||||||
|
} in arguments
|
||||||
.posonlyargs
|
.posonlyargs
|
||||||
.iter()
|
.iter()
|
||||||
.chain(&arguments.args)
|
.chain(&arguments.args)
|
||||||
.enumerate()
|
.chain(&arguments.kwonlyargs)
|
||||||
{
|
{
|
||||||
if let Some(i) = i.checked_sub(defaults_start) {
|
let Some(default) = default else {
|
||||||
let default = &arguments.defaults[i];
|
continue;
|
||||||
if let Some(diagnostic) = check_password_kwarg(arg, default) {
|
};
|
||||||
diagnostics.push(diagnostic);
|
if let Some(diagnostic) = check_password_kwarg(def, default) {
|
||||||
}
|
diagnostics.push(diagnostic);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let defaults_start = arguments.kwonlyargs.len() - arguments.kw_defaults.len();
|
|
||||||
for (i, kwarg) in arguments.kwonlyargs.iter().enumerate() {
|
|
||||||
if let Some(i) = i.checked_sub(defaults_start) {
|
|
||||||
let default = &arguments.kw_defaults[i];
|
|
||||||
if let Some(diagnostic) = check_password_kwarg(kwarg, default) {
|
|
||||||
diagnostics.push(diagnostic);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{Excepthandler, Expr, Ranged, Stmt};
|
use rustpython_parser::ast::{ExceptHandler, Expr, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -19,7 +19,7 @@ impl Violation for TryExceptContinue {
|
||||||
/// S112
|
/// S112
|
||||||
pub(crate) fn try_except_continue(
|
pub(crate) fn try_except_continue(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
excepthandler: &Excepthandler,
|
except_handler: &ExceptHandler,
|
||||||
type_: Option<&Expr>,
|
type_: Option<&Expr>,
|
||||||
_name: Option<&str>,
|
_name: Option<&str>,
|
||||||
body: &[Stmt],
|
body: &[Stmt],
|
||||||
|
@ -31,6 +31,6 @@ pub(crate) fn try_except_continue(
|
||||||
{
|
{
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(TryExceptContinue, excepthandler.range()));
|
.push(Diagnostic::new(TryExceptContinue, except_handler.range()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{Excepthandler, Expr, Ranged, Stmt};
|
use rustpython_parser::ast::{ExceptHandler, Expr, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -19,7 +19,7 @@ impl Violation for TryExceptPass {
|
||||||
/// S110
|
/// S110
|
||||||
pub(crate) fn try_except_pass(
|
pub(crate) fn try_except_pass(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
excepthandler: &Excepthandler,
|
except_handler: &ExceptHandler,
|
||||||
type_: Option<&Expr>,
|
type_: Option<&Expr>,
|
||||||
_name: Option<&str>,
|
_name: Option<&str>,
|
||||||
body: &[Stmt],
|
body: &[Stmt],
|
||||||
|
@ -31,6 +31,6 @@ pub(crate) fn try_except_pass(
|
||||||
{
|
{
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(TryExceptPass, excepthandler.range()));
|
.push(Diagnostic::new(TryExceptPass, except_handler.range()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{Arguments, Decorator};
|
use rustpython_parser::ast::{ArgWithDefault, Arguments, Decorator};
|
||||||
|
|
||||||
use ruff_diagnostics::Violation;
|
use ruff_diagnostics::Violation;
|
||||||
|
|
||||||
|
@ -75,7 +75,19 @@ pub(crate) fn check_boolean_default_value_in_function_definition(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for arg in &arguments.defaults {
|
for ArgWithDefault {
|
||||||
add_if_boolean(checker, arg, BooleanDefaultValueInFunctionDefinition.into());
|
def: _,
|
||||||
|
default,
|
||||||
|
range: _,
|
||||||
|
} in arguments.args.iter().chain(&arguments.posonlyargs)
|
||||||
|
{
|
||||||
|
let Some(default) = default else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
add_if_boolean(
|
||||||
|
checker,
|
||||||
|
default,
|
||||||
|
BooleanDefaultValueInFunctionDefinition.into(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Arguments, Constant, Decorator, Expr, Ranged};
|
use rustpython_parser::ast::{self, ArgWithDefault, Arguments, Constant, Decorator, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::Diagnostic;
|
use ruff_diagnostics::Diagnostic;
|
||||||
use ruff_diagnostics::Violation;
|
use ruff_diagnostics::Violation;
|
||||||
|
@ -93,11 +93,16 @@ pub(crate) fn check_positional_boolean_in_def(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for arg in arguments.posonlyargs.iter().chain(arguments.args.iter()) {
|
for ArgWithDefault {
|
||||||
if arg.annotation.is_none() {
|
def,
|
||||||
|
default: _,
|
||||||
|
range: _,
|
||||||
|
} in arguments.posonlyargs.iter().chain(&arguments.args)
|
||||||
|
{
|
||||||
|
if def.annotation.is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let Some(expr) = &arg.annotation else {
|
let Some(expr) = &def.annotation else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,7 +120,7 @@ pub(crate) fn check_positional_boolean_in_def(
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
BooleanPositionalArgInFunctionDefinition,
|
BooleanPositionalArgInFunctionDefinition,
|
||||||
arg.range(),
|
def.range(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Expr, Ranged, Stmt, Withitem};
|
use rustpython_parser::ast::{self, Expr, Ranged, Stmt, WithItem};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -50,7 +50,7 @@ impl Violation for AssertRaisesException {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// B017
|
/// B017
|
||||||
pub(crate) fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items: &[Withitem]) {
|
pub(crate) fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items: &[WithItem]) {
|
||||||
let Some(item) = items.first() else {
|
let Some(item) = items.first() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Expr, ExprContext, Ranged};
|
use rustpython_parser::ast::{self, ExceptHandler, Expr, ExprContext, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Violation};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Violation};
|
||||||
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
||||||
|
@ -105,11 +105,11 @@ fn duplicate_handler_exceptions<'a>(
|
||||||
seen
|
seen
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn duplicate_exceptions(checker: &mut Checker, handlers: &[Excepthandler]) {
|
pub(crate) fn duplicate_exceptions(checker: &mut Checker, handlers: &[ExceptHandler]) {
|
||||||
let mut seen: FxHashSet<CallPath> = FxHashSet::default();
|
let mut seen: FxHashSet<CallPath> = FxHashSet::default();
|
||||||
let mut duplicates: FxHashMap<CallPath, Vec<&Expr>> = FxHashMap::default();
|
let mut duplicates: FxHashMap<CallPath, Vec<&Expr>> = FxHashMap::default();
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_: Some(type_), .. }) = handler else {
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_: Some(type_), .. }) = handler else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
match type_.as_ref() {
|
match type_.as_ref() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use rustpython_parser::ast::{self, Ranged};
|
use rustpython_parser::ast::{self, Ranged};
|
||||||
use rustpython_parser::ast::{Excepthandler, Expr};
|
use rustpython_parser::ast::{ExceptHandler, Expr};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -17,8 +17,9 @@ impl Violation for ExceptWithEmptyTuple {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// B029
|
/// B029
|
||||||
pub(crate) fn except_with_empty_tuple(checker: &mut Checker, excepthandler: &Excepthandler) {
|
pub(crate) fn except_with_empty_tuple(checker: &mut Checker, except_handler: &ExceptHandler) {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = excepthandler;
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, .. }) =
|
||||||
|
except_handler;
|
||||||
let Some(type_) = type_ else {
|
let Some(type_) = type_ else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -26,8 +27,9 @@ pub(crate) fn except_with_empty_tuple(checker: &mut Checker, excepthandler: &Exc
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if elts.is_empty() {
|
if elts.is_empty() {
|
||||||
checker
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
.diagnostics
|
ExceptWithEmptyTuple,
|
||||||
.push(Diagnostic::new(ExceptWithEmptyTuple, excepthandler.range()));
|
except_handler.range(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Expr, Ranged};
|
use rustpython_parser::ast::{self, ExceptHandler, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -44,9 +44,10 @@ fn flatten_starred_iterables(expr: &Expr) -> Vec<&Expr> {
|
||||||
/// B030
|
/// B030
|
||||||
pub(crate) fn except_with_non_exception_classes(
|
pub(crate) fn except_with_non_exception_classes(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
excepthandler: &Excepthandler,
|
except_handler: &ExceptHandler,
|
||||||
) {
|
) {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = excepthandler;
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, .. }) =
|
||||||
|
except_handler;
|
||||||
let Some(type_) = type_ else {
|
let Some(type_) = type_ else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustpython_parser::ast::{self, Arguments, Expr, Ranged};
|
use rustpython_parser::ast::{self, ArgWithDefault, Arguments, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::Violation;
|
use ruff_diagnostics::Violation;
|
||||||
use ruff_diagnostics::{Diagnostic, DiagnosticKind};
|
use ruff_diagnostics::{Diagnostic, DiagnosticKind};
|
||||||
|
@ -114,12 +114,19 @@ pub(crate) fn function_call_argument_default(checker: &mut Checker, arguments: &
|
||||||
.collect();
|
.collect();
|
||||||
let diagnostics = {
|
let diagnostics = {
|
||||||
let mut visitor = ArgumentDefaultVisitor::new(checker.semantic(), extend_immutable_calls);
|
let mut visitor = ArgumentDefaultVisitor::new(checker.semantic(), extend_immutable_calls);
|
||||||
for expr in arguments
|
for ArgWithDefault {
|
||||||
.defaults
|
default,
|
||||||
|
def: _,
|
||||||
|
range: _,
|
||||||
|
} in arguments
|
||||||
|
.posonlyargs
|
||||||
.iter()
|
.iter()
|
||||||
.chain(arguments.kw_defaults.iter())
|
.chain(&arguments.args)
|
||||||
|
.chain(&arguments.kwonlyargs)
|
||||||
{
|
{
|
||||||
visitor.visit_expr(expr);
|
if let Some(expr) = &default {
|
||||||
|
visitor.visit_expr(expr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
visitor.diagnostics
|
visitor.diagnostics
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use rustpython_parser::ast::{self, Expr, Ranged};
|
use rustpython_parser::ast::{self, ArgWithDefault, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -49,8 +49,17 @@ where
|
||||||
range: _,
|
range: _,
|
||||||
}) => {
|
}) => {
|
||||||
visitor::walk_expr(self, body);
|
visitor::walk_expr(self, body);
|
||||||
for arg in &args.args {
|
for ArgWithDefault {
|
||||||
self.names.remove(arg.arg.as_str());
|
def,
|
||||||
|
default: _,
|
||||||
|
range: _,
|
||||||
|
} in args
|
||||||
|
.posonlyargs
|
||||||
|
.iter()
|
||||||
|
.chain(&args.args)
|
||||||
|
.chain(&args.kwonlyargs)
|
||||||
|
{
|
||||||
|
self.names.remove(def.arg.as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => visitor::walk_expr(self, expr),
|
_ => visitor::walk_expr(self, expr),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{Arguments, Ranged};
|
use rustpython_parser::ast::{ArgWithDefault, Arguments, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -19,22 +19,22 @@ impl Violation for MutableArgumentDefault {
|
||||||
/// B006
|
/// B006
|
||||||
pub(crate) fn mutable_argument_default(checker: &mut Checker, arguments: &Arguments) {
|
pub(crate) fn mutable_argument_default(checker: &mut Checker, arguments: &Arguments) {
|
||||||
// Scan in reverse order to right-align zip().
|
// Scan in reverse order to right-align zip().
|
||||||
for (arg, default) in arguments
|
for ArgWithDefault {
|
||||||
.kwonlyargs
|
def,
|
||||||
|
default,
|
||||||
|
range: _,
|
||||||
|
} in arguments
|
||||||
|
.posonlyargs
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.chain(&arguments.args)
|
||||||
.zip(arguments.kw_defaults.iter().rev())
|
.chain(&arguments.kwonlyargs)
|
||||||
.chain(
|
|
||||||
arguments
|
|
||||||
.args
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.chain(arguments.posonlyargs.iter().rev())
|
|
||||||
.zip(arguments.defaults.iter().rev()),
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
let Some(default)= default else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
if is_mutable_expr(default, checker.semantic())
|
if is_mutable_expr(default, checker.semantic())
|
||||||
&& !arg.annotation.as_ref().map_or(false, |expr| {
|
&& !def.annotation.as_ref().map_or(false, |expr| {
|
||||||
is_immutable_annotation(expr, checker.semantic())
|
is_immutable_annotation(expr, checker.semantic())
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Expr, Ranged};
|
use rustpython_parser::ast::{self, ExceptHandler, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -30,10 +30,10 @@ impl AlwaysAutofixableViolation for RedundantTupleInExceptionHandler {
|
||||||
/// B013
|
/// B013
|
||||||
pub(crate) fn redundant_tuple_in_exception_handler(
|
pub(crate) fn redundant_tuple_in_exception_handler(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
handlers: &[Excepthandler],
|
handlers: &[ExceptHandler],
|
||||||
) {
|
) {
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_: Some(type_), .. }) = handler else {
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_: Some(type_), .. }) = handler else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let Expr::Tuple(ast::ExprTuple { elts, .. }) = type_.as_ref() else {
|
let Expr::Tuple(ast::ExprTuple { elts, .. }) = type_.as_ref() else {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
//! n += 1
|
//! n += 1
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use rustpython_parser::ast::{self, Expr, Ranged, Unaryop};
|
use rustpython_parser::ast::{self, Expr, Ranged, UnaryOp};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -38,16 +38,16 @@ impl Violation for UnaryPrefixIncrement {
|
||||||
pub(crate) fn unary_prefix_increment(
|
pub(crate) fn unary_prefix_increment(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
op: Unaryop,
|
op: UnaryOp,
|
||||||
operand: &Expr,
|
operand: &Expr,
|
||||||
) {
|
) {
|
||||||
if !matches!(op, Unaryop::UAdd) {
|
if !matches!(op, UnaryOp::UAdd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Expr::UnaryOp(ast::ExprUnaryOp { op, .. })= operand else {
|
let Expr::UnaryOp(ast::ExprUnaryOp { op, .. })= operand else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !matches!(op, Unaryop::UAdd) {
|
if !matches!(op, UnaryOp::UAdd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
checker
|
checker
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustpython_parser::ast::{Excepthandler, Expr, Ranged, Stmt};
|
use rustpython_parser::ast::{ExceptHandler, Expr, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_python_ast::identifier::Identifier;
|
use ruff_python_ast::identifier::Identifier;
|
||||||
use ruff_python_ast::source_code::Locator;
|
use ruff_python_ast::source_code::Locator;
|
||||||
|
@ -13,7 +13,7 @@ pub(super) fn shadows_builtin(name: &str, ignorelist: &[String]) -> bool {
|
||||||
pub(crate) enum AnyShadowing<'a> {
|
pub(crate) enum AnyShadowing<'a> {
|
||||||
Expression(&'a Expr),
|
Expression(&'a Expr),
|
||||||
Statement(&'a Stmt),
|
Statement(&'a Stmt),
|
||||||
ExceptHandler(&'a Excepthandler),
|
ExceptHandler(&'a ExceptHandler),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnyShadowing<'_> {
|
impl AnyShadowing<'_> {
|
||||||
|
@ -38,8 +38,8 @@ impl<'a> From<&'a Expr> for AnyShadowing<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a Excepthandler> for AnyShadowing<'a> {
|
impl<'a> From<&'a ExceptHandler> for AnyShadowing<'a> {
|
||||||
fn from(value: &'a Excepthandler) -> Self {
|
fn from(value: &'a ExceptHandler) -> Self {
|
||||||
AnyShadowing::ExceptHandler(value)
|
AnyShadowing::ExceptHandler(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use rustpython_parser::ast::{self, Constant, Expr, Ranged, Unaryop};
|
use rustpython_parser::ast::{self, Constant, Expr, Ranged, UnaryOp};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -74,7 +74,7 @@ pub(crate) fn unnecessary_subscript_reversal(
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Expr::UnaryOp(ast::ExprUnaryOp {
|
let Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::USub,
|
op: UnaryOp::USub,
|
||||||
operand,
|
operand,
|
||||||
range: _,
|
range: _,
|
||||||
}) = step.as_ref() else {
|
}) = step.as_ref() else {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use itertools::Either::{Left, Right};
|
||||||
|
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
|
|
||||||
use rustpython_parser::ast::{self, Boolop, Expr, ExprContext, Ranged};
|
use rustpython_parser::ast::{self, BoolOp, Expr, ExprContext, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::AlwaysAutofixableViolation;
|
use ruff_diagnostics::AlwaysAutofixableViolation;
|
||||||
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
||||||
|
@ -60,7 +60,7 @@ impl AlwaysAutofixableViolation for MultipleStartsEndsWith {
|
||||||
|
|
||||||
/// PIE810
|
/// PIE810
|
||||||
pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
||||||
let Expr::BoolOp(ast::ExprBoolOp { op: Boolop::Or, values, range: _ }) = expr else {
|
let Expr::BoolOp(ast::ExprBoolOp { op: BoolOp::Or, values, range: _ }) = expr else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
||||||
// Generate the combined `BoolOp`.
|
// Generate the combined `BoolOp`.
|
||||||
let mut call = Some(call);
|
let mut call = Some(call);
|
||||||
let node = Expr::BoolOp(ast::ExprBoolOp {
|
let node = Expr::BoolOp(ast::ExprBoolOp {
|
||||||
op: Boolop::Or,
|
op: BoolOp::Or,
|
||||||
values: values
|
values: values
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
|
|
@ -62,7 +62,7 @@ pub(crate) fn any_eq_ne_annotation(checker: &mut Checker, name: &str, args: &Arg
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(annotation) = &args.args[1].annotation else {
|
let Some(annotation) = &args.args[1].def.annotation else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{Cmpop, Expr, Ranged};
|
use rustpython_parser::ast::{CmpOp, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -61,7 +61,7 @@ pub(crate) fn bad_version_info_comparison(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
left: &Expr,
|
left: &Expr,
|
||||||
ops: &[Cmpop],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
) {
|
) {
|
||||||
let ([op], [_right]) = (ops, comparators) else {
|
let ([op], [_right]) = (ops, comparators) else {
|
||||||
|
@ -78,7 +78,7 @@ pub(crate) fn bad_version_info_comparison(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !matches!(op, Cmpop::Lt | Cmpop::GtE) {
|
if !matches!(op, CmpOp::Lt | CmpOp::GtE) {
|
||||||
let diagnostic = Diagnostic::new(BadVersionInfoComparison, expr.range());
|
let diagnostic = Diagnostic::new(BadVersionInfoComparison, expr.range());
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use itertools::chain;
|
|
||||||
use rustpython_parser::ast::Ranged;
|
use rustpython_parser::ast::Ranged;
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
|
@ -49,12 +48,12 @@ impl Violation for NoReturnArgumentAnnotationInStub {
|
||||||
|
|
||||||
/// PYI050
|
/// PYI050
|
||||||
pub(crate) fn no_return_argument_annotation(checker: &mut Checker, args: &Arguments) {
|
pub(crate) fn no_return_argument_annotation(checker: &mut Checker, args: &Arguments) {
|
||||||
for annotation in chain!(
|
for annotation in args
|
||||||
args.args.iter(),
|
.posonlyargs
|
||||||
args.posonlyargs.iter(),
|
.iter()
|
||||||
args.kwonlyargs.iter()
|
.chain(&args.args)
|
||||||
)
|
.chain(&args.kwonlyargs)
|
||||||
.filter_map(|arg| arg.annotation.as_ref())
|
.filter_map(|arg| arg.def.annotation.as_ref())
|
||||||
{
|
{
|
||||||
if checker.semantic().match_typing_expr(annotation, "NoReturn") {
|
if checker.semantic().match_typing_expr(annotation, "NoReturn") {
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use rustpython_parser::ast::{self, Arguments, Constant, Expr, Operator, Ranged, Stmt, Unaryop};
|
use rustpython_parser::ast::{
|
||||||
|
self, ArgWithDefault, Arguments, Constant, Expr, Operator, Ranged, Stmt, UnaryOp,
|
||||||
|
};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix, Violation};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -156,7 +158,7 @@ fn is_valid_default_value_with_annotation(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::USub,
|
op: UnaryOp::USub,
|
||||||
operand,
|
operand,
|
||||||
range: _,
|
range: _,
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -199,7 +201,7 @@ fn is_valid_default_value_with_annotation(
|
||||||
{
|
{
|
||||||
return locator.slice(left.range()).len() <= 10;
|
return locator.slice(left.range()).len() <= 10;
|
||||||
} else if let Expr::UnaryOp(ast::ExprUnaryOp {
|
} else if let Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::USub,
|
op: UnaryOp::USub,
|
||||||
operand,
|
operand,
|
||||||
range: _,
|
range: _,
|
||||||
}) = left.as_ref()
|
}) = left.as_ref()
|
||||||
|
@ -312,130 +314,74 @@ fn is_enum(bases: &[Expr], semantic: &SemanticModel) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PYI011
|
/// PYI011
|
||||||
pub(crate) fn typed_argument_simple_defaults(checker: &mut Checker, args: &Arguments) {
|
pub(crate) fn typed_argument_simple_defaults(checker: &mut Checker, arguments: &Arguments) {
|
||||||
if !args.defaults.is_empty() {
|
for ArgWithDefault {
|
||||||
let defaults_start = args.posonlyargs.len() + args.args.len() - args.defaults.len();
|
def,
|
||||||
for (i, arg) in args.posonlyargs.iter().chain(&args.args).enumerate() {
|
default,
|
||||||
if let Some(default) = i
|
range: _,
|
||||||
.checked_sub(defaults_start)
|
} in arguments
|
||||||
.and_then(|i| args.defaults.get(i))
|
.posonlyargs
|
||||||
{
|
.iter()
|
||||||
if arg.annotation.is_some() {
|
.chain(&arguments.args)
|
||||||
if !is_valid_default_value_with_annotation(
|
.chain(&arguments.kwonlyargs)
|
||||||
default,
|
{
|
||||||
true,
|
let Some(default) = default else {
|
||||||
checker.locator,
|
continue;
|
||||||
checker.semantic(),
|
};
|
||||||
) {
|
if def.annotation.is_some() {
|
||||||
let mut diagnostic =
|
if !is_valid_default_value_with_annotation(
|
||||||
Diagnostic::new(TypedArgumentDefaultInStub, default.range());
|
default,
|
||||||
|
true,
|
||||||
|
checker.locator,
|
||||||
|
checker.semantic(),
|
||||||
|
) {
|
||||||
|
let mut diagnostic = Diagnostic::new(TypedArgumentDefaultInStub, default.range());
|
||||||
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||||
"...".to_string(),
|
"...".to_string(),
|
||||||
default.range(),
|
default.range(),
|
||||||
)));
|
)));
|
||||||
}
|
|
||||||
|
|
||||||
checker.diagnostics.push(diagnostic);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !args.kw_defaults.is_empty() {
|
checker.diagnostics.push(diagnostic);
|
||||||
let defaults_start = args.kwonlyargs.len() - args.kw_defaults.len();
|
|
||||||
for (i, kwarg) in args.kwonlyargs.iter().enumerate() {
|
|
||||||
if let Some(default) = i
|
|
||||||
.checked_sub(defaults_start)
|
|
||||||
.and_then(|i| args.kw_defaults.get(i))
|
|
||||||
{
|
|
||||||
if kwarg.annotation.is_some() {
|
|
||||||
if !is_valid_default_value_with_annotation(
|
|
||||||
default,
|
|
||||||
true,
|
|
||||||
checker.locator,
|
|
||||||
checker.semantic(),
|
|
||||||
) {
|
|
||||||
let mut diagnostic =
|
|
||||||
Diagnostic::new(TypedArgumentDefaultInStub, default.range());
|
|
||||||
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
|
||||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
|
||||||
"...".to_string(),
|
|
||||||
default.range(),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
checker.diagnostics.push(diagnostic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PYI014
|
/// PYI014
|
||||||
pub(crate) fn argument_simple_defaults(checker: &mut Checker, args: &Arguments) {
|
pub(crate) fn argument_simple_defaults(checker: &mut Checker, arguments: &Arguments) {
|
||||||
if !args.defaults.is_empty() {
|
for ArgWithDefault {
|
||||||
let defaults_start = args.posonlyargs.len() + args.args.len() - args.defaults.len();
|
def,
|
||||||
for (i, arg) in args.posonlyargs.iter().chain(&args.args).enumerate() {
|
default,
|
||||||
if let Some(default) = i
|
range: _,
|
||||||
.checked_sub(defaults_start)
|
} in arguments
|
||||||
.and_then(|i| args.defaults.get(i))
|
.posonlyargs
|
||||||
{
|
.iter()
|
||||||
if arg.annotation.is_none() {
|
.chain(&arguments.args)
|
||||||
if !is_valid_default_value_with_annotation(
|
.chain(&arguments.kwonlyargs)
|
||||||
default,
|
{
|
||||||
true,
|
let Some(default) = default else {
|
||||||
checker.locator,
|
continue;
|
||||||
checker.semantic(),
|
};
|
||||||
) {
|
if def.annotation.is_none() {
|
||||||
let mut diagnostic =
|
if !is_valid_default_value_with_annotation(
|
||||||
Diagnostic::new(ArgumentDefaultInStub, default.range());
|
default,
|
||||||
|
true,
|
||||||
|
checker.locator,
|
||||||
|
checker.semantic(),
|
||||||
|
) {
|
||||||
|
let mut diagnostic = Diagnostic::new(ArgumentDefaultInStub, default.range());
|
||||||
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||||
"...".to_string(),
|
"...".to_string(),
|
||||||
default.range(),
|
default.range(),
|
||||||
)));
|
)));
|
||||||
}
|
|
||||||
|
|
||||||
checker.diagnostics.push(diagnostic);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !args.kw_defaults.is_empty() {
|
checker.diagnostics.push(diagnostic);
|
||||||
let defaults_start = args.kwonlyargs.len() - args.kw_defaults.len();
|
|
||||||
for (i, kwarg) in args.kwonlyargs.iter().enumerate() {
|
|
||||||
if let Some(default) = i
|
|
||||||
.checked_sub(defaults_start)
|
|
||||||
.and_then(|i| args.kw_defaults.get(i))
|
|
||||||
{
|
|
||||||
if kwarg.annotation.is_none() {
|
|
||||||
if !is_valid_default_value_with_annotation(
|
|
||||||
default,
|
|
||||||
true,
|
|
||||||
checker.locator,
|
|
||||||
checker.semantic(),
|
|
||||||
) {
|
|
||||||
let mut diagnostic =
|
|
||||||
Diagnostic::new(ArgumentDefaultInStub, default.range());
|
|
||||||
|
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
|
||||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
|
||||||
"...".to_string(),
|
|
||||||
default.range(),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
checker.diagnostics.push(diagnostic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Cmpop, Constant, Expr, Ranged};
|
use rustpython_parser::ast::{self, CmpOp, Constant, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -93,7 +93,7 @@ pub(crate) fn unrecognized_platform(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
left: &Expr,
|
left: &Expr,
|
||||||
ops: &[Cmpop],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
) {
|
) {
|
||||||
let ([op], [right]) = (ops, comparators) else {
|
let ([op], [right]) = (ops, comparators) else {
|
||||||
|
@ -113,7 +113,7 @@ pub(crate) fn unrecognized_platform(
|
||||||
}
|
}
|
||||||
|
|
||||||
// "in" might also make sense but we don't currently have one.
|
// "in" might also make sense but we don't currently have one.
|
||||||
if !matches!(op, Cmpop::Eq | Cmpop::NotEq) && checker.enabled(Rule::UnrecognizedPlatformCheck) {
|
if !matches!(op, CmpOp::Eq | CmpOp::NotEq) && checker.enabled(Rule::UnrecognizedPlatformCheck) {
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(diagnostic_unrecognized_platform_check);
|
.push(diagnostic_unrecognized_platform_check);
|
||||||
|
|
|
@ -3,11 +3,11 @@ use std::borrow::Cow;
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use libcst_native::{
|
use libcst_native::{
|
||||||
Assert, BooleanOp, CompoundStatement, Expression, ParenthesizableWhitespace, ParenthesizedNode,
|
self, Assert, BooleanOp, CompoundStatement, Expression, ParenthesizableWhitespace,
|
||||||
SimpleStatementLine, SimpleWhitespace, SmallStatement, Statement, TrailingWhitespace, UnaryOp,
|
ParenthesizedNode, SimpleStatementLine, SimpleWhitespace, SmallStatement, Statement,
|
||||||
UnaryOperation,
|
TrailingWhitespace, UnaryOperation,
|
||||||
};
|
};
|
||||||
use rustpython_parser::ast::{self, Boolop, Excepthandler, Expr, Keyword, Ranged, Stmt, Unaryop};
|
use rustpython_parser::ast::{self, BoolOp, ExceptHandler, Expr, Keyword, Ranged, Stmt, UnaryOp};
|
||||||
|
|
||||||
use crate::autofix::codemods::CodegenStylist;
|
use crate::autofix::codemods::CodegenStylist;
|
||||||
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||||
|
@ -227,11 +227,11 @@ pub(crate) fn assert_falsy(checker: &mut Checker, stmt: &Stmt, test: &Expr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PT017
|
/// PT017
|
||||||
pub(crate) fn assert_in_exception_handler(handlers: &[Excepthandler]) -> Vec<Diagnostic> {
|
pub(crate) fn assert_in_exception_handler(handlers: &[ExceptHandler]) -> Vec<Diagnostic> {
|
||||||
handlers
|
handlers
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|handler| match handler {
|
.flat_map(|handler| match handler {
|
||||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||||
name, body, ..
|
name, body, ..
|
||||||
}) => {
|
}) => {
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
|
@ -262,17 +262,17 @@ enum CompositionKind {
|
||||||
fn is_composite_condition(test: &Expr) -> CompositionKind {
|
fn is_composite_condition(test: &Expr) -> CompositionKind {
|
||||||
match test {
|
match test {
|
||||||
Expr::BoolOp(ast::ExprBoolOp {
|
Expr::BoolOp(ast::ExprBoolOp {
|
||||||
op: Boolop::And, ..
|
op: BoolOp::And, ..
|
||||||
}) => {
|
}) => {
|
||||||
return CompositionKind::Simple;
|
return CompositionKind::Simple;
|
||||||
}
|
}
|
||||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::Not,
|
op: UnaryOp::Not,
|
||||||
operand,
|
operand,
|
||||||
range: _,
|
range: _,
|
||||||
}) => {
|
}) => {
|
||||||
if let Expr::BoolOp(ast::ExprBoolOp {
|
if let Expr::BoolOp(ast::ExprBoolOp {
|
||||||
op: Boolop::Or,
|
op: BoolOp::Or,
|
||||||
values,
|
values,
|
||||||
range: _,
|
range: _,
|
||||||
}) = operand.as_ref()
|
}) = operand.as_ref()
|
||||||
|
@ -282,7 +282,7 @@ fn is_composite_condition(test: &Expr) -> CompositionKind {
|
||||||
!matches!(
|
!matches!(
|
||||||
expr,
|
expr,
|
||||||
Expr::BoolOp(ast::ExprBoolOp {
|
Expr::BoolOp(ast::ExprBoolOp {
|
||||||
op: Boolop::And,
|
op: BoolOp::And,
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -301,12 +301,12 @@ fn is_composite_condition(test: &Expr) -> CompositionKind {
|
||||||
/// Negate a condition, i.e., `a` => `not a` and `not a` => `a`.
|
/// Negate a condition, i.e., `a` => `not a` and `not a` => `a`.
|
||||||
fn negate<'a>(expression: &Expression<'a>) -> Expression<'a> {
|
fn negate<'a>(expression: &Expression<'a>) -> Expression<'a> {
|
||||||
if let Expression::UnaryOperation(ref expression) = expression {
|
if let Expression::UnaryOperation(ref expression) = expression {
|
||||||
if matches!(expression.operator, UnaryOp::Not { .. }) {
|
if matches!(expression.operator, libcst_native::UnaryOp::Not { .. }) {
|
||||||
return *expression.expression.clone();
|
return *expression.expression.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::UnaryOperation(Box::new(UnaryOperation {
|
Expression::UnaryOperation(Box::new(UnaryOperation {
|
||||||
operator: UnaryOp::Not {
|
operator: libcst_native::UnaryOp::Not {
|
||||||
whitespace_after: ParenthesizableWhitespace::SimpleWhitespace(SimpleWhitespace(" ")),
|
whitespace_after: ParenthesizableWhitespace::SimpleWhitespace(SimpleWhitespace(" ")),
|
||||||
},
|
},
|
||||||
expression: Box::new(expression.clone()),
|
expression: Box::new(expression.clone()),
|
||||||
|
@ -371,7 +371,7 @@ fn fix_composite_condition(stmt: &Stmt, locator: &Locator, stylist: &Stylist) ->
|
||||||
let mut conditions: Vec<Expression> = Vec::with_capacity(2);
|
let mut conditions: Vec<Expression> = Vec::with_capacity(2);
|
||||||
match &assert_statement.test {
|
match &assert_statement.test {
|
||||||
Expression::UnaryOperation(op) => {
|
Expression::UnaryOperation(op) => {
|
||||||
if matches!(op.operator, UnaryOp::Not { .. }) {
|
if matches!(op.operator, libcst_native::UnaryOp::Not { .. }) {
|
||||||
if let Expression::BooleanOperation(op) = &*op.expression {
|
if let Expression::BooleanOperation(op) = &*op.expression {
|
||||||
if matches!(op.operator, BooleanOp::Or { .. }) {
|
if matches!(op.operator, BooleanOp::Or { .. }) {
|
||||||
conditions.push(negate(&op.left));
|
conditions.push(negate(&op.left));
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::fmt;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||||
use rustpython_parser::ast::{self, Arguments, Expr, Keyword, Ranged, Stmt};
|
use rustpython_parser::ast::{self, ArgWithDefault, Arguments, Expr, Keyword, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Violation};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Violation};
|
||||||
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
||||||
|
@ -421,18 +421,29 @@ fn check_fixture_returns(checker: &mut Checker, stmt: &Stmt, name: &str, body: &
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PT019
|
/// PT019
|
||||||
fn check_test_function_args(checker: &mut Checker, args: &Arguments) {
|
fn check_test_function_args(checker: &mut Checker, arguments: &Arguments) {
|
||||||
args.args.iter().chain(&args.kwonlyargs).for_each(|arg| {
|
arguments
|
||||||
let name = &arg.arg;
|
.posonlyargs
|
||||||
if name.starts_with('_') {
|
.iter()
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
.chain(&arguments.args)
|
||||||
PytestFixtureParamWithoutValue {
|
.chain(&arguments.kwonlyargs)
|
||||||
name: name.to_string(),
|
.for_each(
|
||||||
},
|
|ArgWithDefault {
|
||||||
arg.range(),
|
def,
|
||||||
));
|
default: _,
|
||||||
}
|
range: _,
|
||||||
});
|
}| {
|
||||||
|
let name = &def.arg;
|
||||||
|
if name.starts_with('_') {
|
||||||
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
|
PytestFixtureParamWithoutValue {
|
||||||
|
name: name.to_string(),
|
||||||
|
},
|
||||||
|
def.range(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PT020
|
/// PT020
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Expr, Identifier, Keyword, Ranged, Stmt, Withitem};
|
use rustpython_parser::ast::{self, Expr, Identifier, Keyword, Ranged, Stmt, WithItem};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -94,7 +94,7 @@ pub(crate) fn raises_call(checker: &mut Checker, func: &Expr, args: &[Expr], key
|
||||||
pub(crate) fn complex_raises(
|
pub(crate) fn complex_raises(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
stmt: &Stmt,
|
stmt: &Stmt,
|
||||||
items: &[Withitem],
|
items: &[WithItem],
|
||||||
body: &[Stmt],
|
body: &[Stmt],
|
||||||
) {
|
) {
|
||||||
let mut is_too_complex = false;
|
let mut is_too_complex = false;
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::hash::BuildHasherDefault;
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use rustpython_parser::ast::{self, Cmpop, Constant, Expr, ExprContext, Keyword, Stmt, Unaryop};
|
use rustpython_parser::ast::{self, CmpOp, Constant, Expr, ExprContext, Keyword, Stmt, UnaryOp};
|
||||||
|
|
||||||
/// An enum to represent the different types of assertions present in the
|
/// An enum to represent the different types of assertions present in the
|
||||||
/// `unittest` module. Note: any variants that can't be replaced with plain
|
/// `unittest` module. Note: any variants that can't be replaced with plain
|
||||||
|
@ -149,10 +149,10 @@ fn assert(expr: &Expr, msg: Option<&Expr>) -> Stmt {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compare(left: &Expr, cmpop: Cmpop, right: &Expr) -> Expr {
|
fn compare(left: &Expr, cmp_op: CmpOp, right: &Expr) -> Expr {
|
||||||
Expr::Compare(ast::ExprCompare {
|
Expr::Compare(ast::ExprCompare {
|
||||||
left: Box::new(left.clone()),
|
left: Box::new(left.clone()),
|
||||||
ops: vec![cmpop],
|
ops: vec![cmp_op],
|
||||||
comparators: vec![right.clone()],
|
comparators: vec![right.clone()],
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
})
|
})
|
||||||
|
@ -263,7 +263,7 @@ impl UnittestAssert {
|
||||||
Ok(if matches!(self, UnittestAssert::False) {
|
Ok(if matches!(self, UnittestAssert::False) {
|
||||||
assert(
|
assert(
|
||||||
&Expr::UnaryOp(ast::ExprUnaryOp {
|
&Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::Not,
|
op: UnaryOp::Not,
|
||||||
operand: Box::new(expr.clone()),
|
operand: Box::new(expr.clone()),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
}),
|
}),
|
||||||
|
@ -290,18 +290,18 @@ impl UnittestAssert {
|
||||||
.get("second")
|
.get("second")
|
||||||
.ok_or_else(|| anyhow!("Missing argument `second`"))?;
|
.ok_or_else(|| anyhow!("Missing argument `second`"))?;
|
||||||
let msg = args.get("msg").copied();
|
let msg = args.get("msg").copied();
|
||||||
let cmpop = match self {
|
let cmp_op = match self {
|
||||||
UnittestAssert::Equal | UnittestAssert::Equals => Cmpop::Eq,
|
UnittestAssert::Equal | UnittestAssert::Equals => CmpOp::Eq,
|
||||||
UnittestAssert::NotEqual | UnittestAssert::NotEquals => Cmpop::NotEq,
|
UnittestAssert::NotEqual | UnittestAssert::NotEquals => CmpOp::NotEq,
|
||||||
UnittestAssert::Greater => Cmpop::Gt,
|
UnittestAssert::Greater => CmpOp::Gt,
|
||||||
UnittestAssert::GreaterEqual => Cmpop::GtE,
|
UnittestAssert::GreaterEqual => CmpOp::GtE,
|
||||||
UnittestAssert::Less => Cmpop::Lt,
|
UnittestAssert::Less => CmpOp::Lt,
|
||||||
UnittestAssert::LessEqual => Cmpop::LtE,
|
UnittestAssert::LessEqual => CmpOp::LtE,
|
||||||
UnittestAssert::Is => Cmpop::Is,
|
UnittestAssert::Is => CmpOp::Is,
|
||||||
UnittestAssert::IsNot => Cmpop::IsNot,
|
UnittestAssert::IsNot => CmpOp::IsNot,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let expr = compare(first, cmpop, second);
|
let expr = compare(first, cmp_op, second);
|
||||||
Ok(assert(&expr, msg))
|
Ok(assert(&expr, msg))
|
||||||
}
|
}
|
||||||
UnittestAssert::In | UnittestAssert::NotIn => {
|
UnittestAssert::In | UnittestAssert::NotIn => {
|
||||||
|
@ -312,12 +312,12 @@ impl UnittestAssert {
|
||||||
.get("container")
|
.get("container")
|
||||||
.ok_or_else(|| anyhow!("Missing argument `container`"))?;
|
.ok_or_else(|| anyhow!("Missing argument `container`"))?;
|
||||||
let msg = args.get("msg").copied();
|
let msg = args.get("msg").copied();
|
||||||
let cmpop = if matches!(self, UnittestAssert::In) {
|
let cmp_op = if matches!(self, UnittestAssert::In) {
|
||||||
Cmpop::In
|
CmpOp::In
|
||||||
} else {
|
} else {
|
||||||
Cmpop::NotIn
|
CmpOp::NotIn
|
||||||
};
|
};
|
||||||
let expr = compare(member, cmpop, container);
|
let expr = compare(member, cmp_op, container);
|
||||||
Ok(assert(&expr, msg))
|
Ok(assert(&expr, msg))
|
||||||
}
|
}
|
||||||
UnittestAssert::IsNone | UnittestAssert::IsNotNone => {
|
UnittestAssert::IsNone | UnittestAssert::IsNotNone => {
|
||||||
|
@ -325,17 +325,17 @@ impl UnittestAssert {
|
||||||
.get("expr")
|
.get("expr")
|
||||||
.ok_or_else(|| anyhow!("Missing argument `expr`"))?;
|
.ok_or_else(|| anyhow!("Missing argument `expr`"))?;
|
||||||
let msg = args.get("msg").copied();
|
let msg = args.get("msg").copied();
|
||||||
let cmpop = if matches!(self, UnittestAssert::IsNone) {
|
let cmp_op = if matches!(self, UnittestAssert::IsNone) {
|
||||||
Cmpop::Is
|
CmpOp::Is
|
||||||
} else {
|
} else {
|
||||||
Cmpop::IsNot
|
CmpOp::IsNot
|
||||||
};
|
};
|
||||||
let node = Expr::Constant(ast::ExprConstant {
|
let node = Expr::Constant(ast::ExprConstant {
|
||||||
value: Constant::None,
|
value: Constant::None,
|
||||||
kind: None,
|
kind: None,
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
});
|
});
|
||||||
let expr = compare(expr, cmpop, &node);
|
let expr = compare(expr, cmp_op, &node);
|
||||||
Ok(assert(&expr, msg))
|
Ok(assert(&expr, msg))
|
||||||
}
|
}
|
||||||
UnittestAssert::IsInstance | UnittestAssert::NotIsInstance => {
|
UnittestAssert::IsInstance | UnittestAssert::NotIsInstance => {
|
||||||
|
@ -362,7 +362,7 @@ impl UnittestAssert {
|
||||||
Ok(assert(&isinstance, msg))
|
Ok(assert(&isinstance, msg))
|
||||||
} else {
|
} else {
|
||||||
let node = ast::ExprUnaryOp {
|
let node = ast::ExprUnaryOp {
|
||||||
op: Unaryop::Not,
|
op: UnaryOp::Not,
|
||||||
operand: Box::new(isinstance),
|
operand: Box::new(isinstance),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
|
@ -403,7 +403,7 @@ impl UnittestAssert {
|
||||||
Ok(assert(&re_search, msg))
|
Ok(assert(&re_search, msg))
|
||||||
} else {
|
} else {
|
||||||
let node = ast::ExprUnaryOp {
|
let node = ast::ExprUnaryOp {
|
||||||
op: Unaryop::Not,
|
op: UnaryOp::Not,
|
||||||
operand: Box::new(re_search),
|
operand: Box::new(re_search),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,7 @@ use itertools::Either::{Left, Right};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use rustpython_parser::ast::{self, Boolop, Cmpop, Expr, ExprContext, Ranged, Unaryop};
|
use rustpython_parser::ast::{self, BoolOp, CmpOp, Expr, ExprContext, Ranged, UnaryOp};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Edit, Fix, Violation};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -299,7 +299,7 @@ fn is_same_expr<'a>(a: &'a Expr, b: &'a Expr) -> Option<&'a str> {
|
||||||
|
|
||||||
/// SIM101
|
/// SIM101
|
||||||
pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
|
||||||
let Expr::BoolOp(ast::ExprBoolOp { op: Boolop::Or, values, range: _ } )= expr else {
|
let Expr::BoolOp(ast::ExprBoolOp { op: BoolOp::Or, values, range: _ } )= expr else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -402,7 +402,7 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
|
||||||
|
|
||||||
// Generate the combined `BoolOp`.
|
// Generate the combined `BoolOp`.
|
||||||
let node = ast::ExprBoolOp {
|
let node = ast::ExprBoolOp {
|
||||||
op: Boolop::Or,
|
op: BoolOp::Or,
|
||||||
values: iter::once(call)
|
values: iter::once(call)
|
||||||
.chain(
|
.chain(
|
||||||
values
|
values
|
||||||
|
@ -437,7 +437,7 @@ fn match_eq_target(expr: &Expr) -> Option<(&str, &Expr)> {
|
||||||
if ops.len() != 1 || comparators.len() != 1 {
|
if ops.len() != 1 || comparators.len() != 1 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if !matches!(&ops[0], Cmpop::Eq) {
|
if !matches!(&ops[0], CmpOp::Eq) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() else {
|
let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() else {
|
||||||
|
@ -452,7 +452,7 @@ fn match_eq_target(expr: &Expr) -> Option<(&str, &Expr)> {
|
||||||
|
|
||||||
/// SIM109
|
/// SIM109
|
||||||
pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) {
|
||||||
let Expr::BoolOp(ast::ExprBoolOp { op: Boolop::Or, values, range: _ }) = expr else {
|
let Expr::BoolOp(ast::ExprBoolOp { op: BoolOp::Or, values, range: _ }) = expr else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) {
|
||||||
};
|
};
|
||||||
let node2 = ast::ExprCompare {
|
let node2 = ast::ExprCompare {
|
||||||
left: Box::new(node1.into()),
|
left: Box::new(node1.into()),
|
||||||
ops: vec![Cmpop::In],
|
ops: vec![CmpOp::In],
|
||||||
comparators: vec![node.into()],
|
comparators: vec![node.into()],
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
|
@ -524,7 +524,7 @@ pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) {
|
||||||
} else {
|
} else {
|
||||||
// Wrap in a `x in (a, b) or ...` boolean operation.
|
// Wrap in a `x in (a, b) or ...` boolean operation.
|
||||||
let node = ast::ExprBoolOp {
|
let node = ast::ExprBoolOp {
|
||||||
op: Boolop::Or,
|
op: BoolOp::Or,
|
||||||
values: iter::once(in_expr).chain(unmatched).collect(),
|
values: iter::once(in_expr).chain(unmatched).collect(),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
|
@ -542,7 +542,7 @@ pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) {
|
||||||
|
|
||||||
/// SIM220
|
/// SIM220
|
||||||
pub(crate) fn expr_and_not_expr(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn expr_and_not_expr(checker: &mut Checker, expr: &Expr) {
|
||||||
let Expr::BoolOp(ast::ExprBoolOp { op: Boolop::And, values, range: _, }) = expr else {
|
let Expr::BoolOp(ast::ExprBoolOp { op: BoolOp::And, values, range: _, }) = expr else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if values.len() < 2 {
|
if values.len() < 2 {
|
||||||
|
@ -554,7 +554,7 @@ pub(crate) fn expr_and_not_expr(checker: &mut Checker, expr: &Expr) {
|
||||||
let mut non_negated_expr = vec![];
|
let mut non_negated_expr = vec![];
|
||||||
for expr in values {
|
for expr in values {
|
||||||
if let Expr::UnaryOp(ast::ExprUnaryOp {
|
if let Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::Not,
|
op: UnaryOp::Not,
|
||||||
operand,
|
operand,
|
||||||
range: _,
|
range: _,
|
||||||
}) = expr
|
}) = expr
|
||||||
|
@ -597,7 +597,7 @@ pub(crate) fn expr_and_not_expr(checker: &mut Checker, expr: &Expr) {
|
||||||
|
|
||||||
/// SIM221
|
/// SIM221
|
||||||
pub(crate) fn expr_or_not_expr(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn expr_or_not_expr(checker: &mut Checker, expr: &Expr) {
|
||||||
let Expr::BoolOp(ast::ExprBoolOp { op: Boolop::Or, values, range: _, }) = expr else {
|
let Expr::BoolOp(ast::ExprBoolOp { op: BoolOp::Or, values, range: _, }) = expr else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if values.len() < 2 {
|
if values.len() < 2 {
|
||||||
|
@ -609,7 +609,7 @@ pub(crate) fn expr_or_not_expr(checker: &mut Checker, expr: &Expr) {
|
||||||
let mut non_negated_expr = vec![];
|
let mut non_negated_expr = vec![];
|
||||||
for expr in values {
|
for expr in values {
|
||||||
if let Expr::UnaryOp(ast::ExprUnaryOp {
|
if let Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::Not,
|
op: UnaryOp::Not,
|
||||||
operand,
|
operand,
|
||||||
range: _,
|
range: _,
|
||||||
}) = expr
|
}) = expr
|
||||||
|
@ -673,7 +673,7 @@ pub(crate) fn get_short_circuit_edit(
|
||||||
|
|
||||||
fn is_short_circuit(
|
fn is_short_circuit(
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
expected_op: Boolop,
|
expected_op: BoolOp,
|
||||||
checker: &Checker,
|
checker: &Checker,
|
||||||
) -> Option<(Edit, ContentAround)> {
|
) -> Option<(Edit, ContentAround)> {
|
||||||
let Expr::BoolOp(ast::ExprBoolOp { op, values, range: _, }) = expr else {
|
let Expr::BoolOp(ast::ExprBoolOp { op, values, range: _, }) = expr else {
|
||||||
|
@ -683,8 +683,8 @@ fn is_short_circuit(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let short_circuit_truthiness = match op {
|
let short_circuit_truthiness = match op {
|
||||||
Boolop::And => Truthiness::Falsey,
|
BoolOp::And => Truthiness::Falsey,
|
||||||
Boolop::Or => Truthiness::Truthy,
|
BoolOp::Or => Truthiness::Truthy,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut location = expr.start();
|
let mut location = expr.start();
|
||||||
|
@ -753,7 +753,7 @@ fn is_short_circuit(
|
||||||
|
|
||||||
/// SIM222
|
/// SIM222
|
||||||
pub(crate) fn expr_or_true(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn expr_or_true(checker: &mut Checker, expr: &Expr) {
|
||||||
if let Some((edit, remove)) = is_short_circuit(expr, Boolop::Or, checker) {
|
if let Some((edit, remove)) = is_short_circuit(expr, BoolOp::Or, checker) {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
ExprOrTrue {
|
ExprOrTrue {
|
||||||
expr: edit.content().unwrap_or_default().to_string(),
|
expr: edit.content().unwrap_or_default().to_string(),
|
||||||
|
@ -771,7 +771,7 @@ pub(crate) fn expr_or_true(checker: &mut Checker, expr: &Expr) {
|
||||||
|
|
||||||
/// SIM223
|
/// SIM223
|
||||||
pub(crate) fn expr_and_false(checker: &mut Checker, expr: &Expr) {
|
pub(crate) fn expr_and_false(checker: &mut Checker, expr: &Expr) {
|
||||||
if let Some((edit, remove)) = is_short_circuit(expr, Boolop::And, checker) {
|
if let Some((edit, remove)) = is_short_circuit(expr, BoolOp::And, checker) {
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
ExprAndFalse {
|
ExprAndFalse {
|
||||||
expr: edit.content().unwrap_or_default().to_string(),
|
expr: edit.content().unwrap_or_default().to_string(),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use log::error;
|
use log::error;
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use rustpython_parser::ast::{self, Cmpop, Constant, Expr, ExprContext, Ranged, Stmt};
|
use rustpython_parser::ast::{self, CmpOp, Constant, Expr, ExprContext, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -734,7 +734,7 @@ pub(crate) fn manual_dict_lookup(
|
||||||
if orelse.len() != 1 {
|
if orelse.len() != 1 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !(ops.len() == 1 && ops[0] == Cmpop::Eq) {
|
if !(ops.len() == 1 && ops[0] == CmpOp::Eq) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if comparators.len() != 1 {
|
if comparators.len() != 1 {
|
||||||
|
@ -807,7 +807,7 @@ pub(crate) fn manual_dict_lookup(
|
||||||
let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() else {
|
let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !(id == target && ops.len() == 1 && ops[0] == Cmpop::Eq) {
|
if !(id == target && ops.len() == 1 && ops[0] == CmpOp::Eq) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if comparators.len() != 1 {
|
if comparators.len() != 1 {
|
||||||
|
@ -882,8 +882,8 @@ pub(crate) fn use_dict_get_with_default(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (expected_var, expected_value, default_var, default_value) = match ops[..] {
|
let (expected_var, expected_value, default_var, default_value) = match ops[..] {
|
||||||
[Cmpop::In] => (&body_var[0], body_value, &orelse_var[0], orelse_value),
|
[CmpOp::In] => (&body_var[0], body_value, &orelse_var[0], orelse_value),
|
||||||
[Cmpop::NotIn] => (&orelse_var[0], orelse_value, &body_var[0], body_value),
|
[CmpOp::NotIn] => (&orelse_var[0], orelse_value, &body_var[0], body_value),
|
||||||
_ => {
|
_ => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustpython_parser::ast::{self, Constant, Expr, ExprContext, Ranged, Unaryop};
|
use rustpython_parser::ast::{self, Constant, Expr, ExprContext, Ranged, UnaryOp};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Edit, Fix, Violation};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -219,7 +219,7 @@ pub(crate) fn explicit_false_true_in_ifexpr(
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
let node = test.clone();
|
let node = test.clone();
|
||||||
let node1 = ast::ExprUnaryOp {
|
let node1 = ast::ExprUnaryOp {
|
||||||
op: Unaryop::Not,
|
op: UnaryOp::Not,
|
||||||
operand: Box::new(node),
|
operand: Box::new(node),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustpython_parser::ast::{self, Cmpop, Expr, ExprContext, Ranged, Stmt, Unaryop};
|
use rustpython_parser::ast::{self, CmpOp, Expr, ExprContext, Ranged, Stmt, UnaryOp};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -138,16 +138,16 @@ fn is_exception_check(stmt: &Stmt) -> bool {
|
||||||
pub(crate) fn negation_with_equal_op(
|
pub(crate) fn negation_with_equal_op(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
op: Unaryop,
|
op: UnaryOp,
|
||||||
operand: &Expr,
|
operand: &Expr,
|
||||||
) {
|
) {
|
||||||
if !matches!(op, Unaryop::Not) {
|
if !matches!(op, UnaryOp::Not) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Expr::Compare(ast::ExprCompare { left, ops, comparators, range: _}) = operand else {
|
let Expr::Compare(ast::ExprCompare { left, ops, comparators, range: _}) = operand else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !matches!(&ops[..], [Cmpop::Eq]) {
|
if !matches!(&ops[..], [CmpOp::Eq]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_exception_check(checker.semantic().stmt()) {
|
if is_exception_check(checker.semantic().stmt()) {
|
||||||
|
@ -174,7 +174,7 @@ pub(crate) fn negation_with_equal_op(
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
let node = ast::ExprCompare {
|
let node = ast::ExprCompare {
|
||||||
left: left.clone(),
|
left: left.clone(),
|
||||||
ops: vec![Cmpop::NotEq],
|
ops: vec![CmpOp::NotEq],
|
||||||
comparators: comparators.clone(),
|
comparators: comparators.clone(),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
|
@ -191,16 +191,16 @@ pub(crate) fn negation_with_equal_op(
|
||||||
pub(crate) fn negation_with_not_equal_op(
|
pub(crate) fn negation_with_not_equal_op(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
op: Unaryop,
|
op: UnaryOp,
|
||||||
operand: &Expr,
|
operand: &Expr,
|
||||||
) {
|
) {
|
||||||
if !matches!(op, Unaryop::Not) {
|
if !matches!(op, UnaryOp::Not) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Expr::Compare(ast::ExprCompare { left, ops, comparators, range: _}) = operand else {
|
let Expr::Compare(ast::ExprCompare { left, ops, comparators, range: _}) = operand else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !matches!(&ops[..], [Cmpop::NotEq]) {
|
if !matches!(&ops[..], [CmpOp::NotEq]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if is_exception_check(checker.semantic().stmt()) {
|
if is_exception_check(checker.semantic().stmt()) {
|
||||||
|
@ -227,7 +227,7 @@ pub(crate) fn negation_with_not_equal_op(
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
let node = ast::ExprCompare {
|
let node = ast::ExprCompare {
|
||||||
left: left.clone(),
|
left: left.clone(),
|
||||||
ops: vec![Cmpop::Eq],
|
ops: vec![CmpOp::Eq],
|
||||||
comparators: comparators.clone(),
|
comparators: comparators.clone(),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
|
@ -241,14 +241,14 @@ pub(crate) fn negation_with_not_equal_op(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SIM208
|
/// SIM208
|
||||||
pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: Unaryop, operand: &Expr) {
|
pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: UnaryOp, operand: &Expr) {
|
||||||
if !matches!(op, Unaryop::Not) {
|
if !matches!(op, UnaryOp::Not) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Expr::UnaryOp(ast::ExprUnaryOp { op: operand_op, operand, range: _ }) = operand else {
|
let Expr::UnaryOp(ast::ExprUnaryOp { op: operand_op, operand, range: _ }) = operand else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if !matches!(operand_op, Unaryop::Not) {
|
if !matches!(operand_op, UnaryOp::Not) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use log::error;
|
use log::error;
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustpython_parser::ast::{self, Ranged, Stmt, Withitem};
|
use rustpython_parser::ast::{self, Ranged, Stmt, WithItem};
|
||||||
|
|
||||||
use ruff_diagnostics::{AutofixKind, Violation};
|
use ruff_diagnostics::{AutofixKind, Violation};
|
||||||
use ruff_diagnostics::{Diagnostic, Fix};
|
use ruff_diagnostics::{Diagnostic, Fix};
|
||||||
|
@ -62,7 +62,7 @@ impl Violation for MultipleWithStatements {
|
||||||
|
|
||||||
/// Returns a boolean indicating whether it's an async with statement, the items
|
/// Returns a boolean indicating whether it's an async with statement, the items
|
||||||
/// and body.
|
/// and body.
|
||||||
fn next_with(body: &[Stmt]) -> Option<(bool, &[Withitem], &[Stmt])> {
|
fn next_with(body: &[Stmt]) -> Option<(bool, &[WithItem], &[Stmt])> {
|
||||||
match body {
|
match body {
|
||||||
[Stmt::With(ast::StmtWith { items, body, .. })] => Some((false, items, body)),
|
[Stmt::With(ast::StmtWith { items, body, .. })] => Some((false, items, body)),
|
||||||
[Stmt::AsyncWith(ast::StmtAsyncWith { items, body, .. })] => Some((true, items, body)),
|
[Stmt::AsyncWith(ast::StmtAsyncWith { items, body, .. })] => Some((true, items, body)),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use log::error;
|
use log::error;
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustpython_parser::ast::{self, Cmpop, Expr, Ranged};
|
use rustpython_parser::ast::{self, CmpOp, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::Edit;
|
use ruff_diagnostics::Edit;
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix};
|
||||||
|
@ -128,10 +128,10 @@ pub(crate) fn key_in_dict_compare(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
left: &Expr,
|
left: &Expr,
|
||||||
ops: &[Cmpop],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
) {
|
) {
|
||||||
if !matches!(ops[..], [Cmpop::In]) {
|
if !matches!(ops[..], [CmpOp::In]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use ruff_text_size::{TextRange, TextSize};
|
use ruff_text_size::{TextRange, TextSize};
|
||||||
use rustpython_parser::ast::{
|
use rustpython_parser::ast::{
|
||||||
self, Cmpop, Comprehension, Constant, Expr, ExprContext, Ranged, Stmt, Unaryop,
|
self, CmpOp, Comprehension, Constant, Expr, ExprContext, Ranged, Stmt, UnaryOp,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||||
|
@ -117,7 +117,7 @@ pub(crate) fn convert_for_loop_to_any_all(
|
||||||
// Invert the condition.
|
// Invert the condition.
|
||||||
let test = {
|
let test = {
|
||||||
if let Expr::UnaryOp(ast::ExprUnaryOp {
|
if let Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::Not,
|
op: UnaryOp::Not,
|
||||||
operand,
|
operand,
|
||||||
range: _,
|
range: _,
|
||||||
}) = &loop_info.test
|
}) = &loop_info.test
|
||||||
|
@ -132,16 +132,16 @@ pub(crate) fn convert_for_loop_to_any_all(
|
||||||
{
|
{
|
||||||
if let ([op], [comparator]) = (ops.as_slice(), comparators.as_slice()) {
|
if let ([op], [comparator]) = (ops.as_slice(), comparators.as_slice()) {
|
||||||
let op = match op {
|
let op = match op {
|
||||||
Cmpop::Eq => Cmpop::NotEq,
|
CmpOp::Eq => CmpOp::NotEq,
|
||||||
Cmpop::NotEq => Cmpop::Eq,
|
CmpOp::NotEq => CmpOp::Eq,
|
||||||
Cmpop::Lt => Cmpop::GtE,
|
CmpOp::Lt => CmpOp::GtE,
|
||||||
Cmpop::LtE => Cmpop::Gt,
|
CmpOp::LtE => CmpOp::Gt,
|
||||||
Cmpop::Gt => Cmpop::LtE,
|
CmpOp::Gt => CmpOp::LtE,
|
||||||
Cmpop::GtE => Cmpop::Lt,
|
CmpOp::GtE => CmpOp::Lt,
|
||||||
Cmpop::Is => Cmpop::IsNot,
|
CmpOp::Is => CmpOp::IsNot,
|
||||||
Cmpop::IsNot => Cmpop::Is,
|
CmpOp::IsNot => CmpOp::Is,
|
||||||
Cmpop::In => Cmpop::NotIn,
|
CmpOp::In => CmpOp::NotIn,
|
||||||
Cmpop::NotIn => Cmpop::In,
|
CmpOp::NotIn => CmpOp::In,
|
||||||
};
|
};
|
||||||
let node = ast::ExprCompare {
|
let node = ast::ExprCompare {
|
||||||
left: left.clone(),
|
left: left.clone(),
|
||||||
|
@ -152,7 +152,7 @@ pub(crate) fn convert_for_loop_to_any_all(
|
||||||
node.into()
|
node.into()
|
||||||
} else {
|
} else {
|
||||||
let node = ast::ExprUnaryOp {
|
let node = ast::ExprUnaryOp {
|
||||||
op: Unaryop::Not,
|
op: UnaryOp::Not,
|
||||||
operand: Box::new(loop_info.test.clone()),
|
operand: Box::new(loop_info.test.clone()),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
|
@ -160,7 +160,7 @@ pub(crate) fn convert_for_loop_to_any_all(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let node = ast::ExprUnaryOp {
|
let node = ast::ExprUnaryOp {
|
||||||
op: Unaryop::Not,
|
op: UnaryOp::Not,
|
||||||
operand: Box::new(loop_info.test.clone()),
|
operand: Box::new(loop_info.test.clone()),
|
||||||
range: TextRange::default(),
|
range: TextRange::default(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Ranged, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -57,12 +57,12 @@ fn find_return(stmts: &[Stmt]) -> Option<&Stmt> {
|
||||||
pub(crate) fn return_in_try_except_finally(
|
pub(crate) fn return_in_try_except_finally(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
body: &[Stmt],
|
body: &[Stmt],
|
||||||
handlers: &[Excepthandler],
|
handlers: &[ExceptHandler],
|
||||||
finalbody: &[Stmt],
|
finalbody: &[Stmt],
|
||||||
) {
|
) {
|
||||||
let try_has_return = find_return(body).is_some();
|
let try_has_return = find_return(body).is_some();
|
||||||
let except_has_return = handlers.iter().any(|handler| {
|
let except_has_return = handlers.iter().any(|handler| {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = handler;
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { body, .. }) = handler;
|
||||||
find_return(body).is_some()
|
find_return(body).is_some()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_text_size::{TextLen, TextRange};
|
use ruff_text_size::{TextLen, TextRange};
|
||||||
use rustpython_parser::ast::{self, Constant, Excepthandler, Expr, Ranged, Stmt};
|
use rustpython_parser::ast::{self, Constant, ExceptHandler, Expr, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -68,7 +68,7 @@ pub(crate) fn suppressible_exception(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
stmt: &Stmt,
|
stmt: &Stmt,
|
||||||
try_body: &[Stmt],
|
try_body: &[Stmt],
|
||||||
handlers: &[Excepthandler],
|
handlers: &[ExceptHandler],
|
||||||
orelse: &[Stmt],
|
orelse: &[Stmt],
|
||||||
finalbody: &[Stmt],
|
finalbody: &[Stmt],
|
||||||
) {
|
) {
|
||||||
|
@ -90,7 +90,7 @@ pub(crate) fn suppressible_exception(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let handler = &handlers[0];
|
let handler = &handlers[0];
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = handler;
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { body, .. }) = handler;
|
||||||
if body.len() == 1 {
|
if body.len() == 1 {
|
||||||
let node = &body[0];
|
let node = &body[0];
|
||||||
if node.is_pass_stmt()
|
if node.is_pass_stmt()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use libcst_native::CompOp;
|
use libcst_native::CompOp;
|
||||||
use rustpython_parser::ast::{self, Cmpop, Expr, Ranged, Unaryop};
|
use rustpython_parser::ast::{self, CmpOp, Expr, Ranged, UnaryOp};
|
||||||
|
|
||||||
use crate::autofix::codemods::CodegenStylist;
|
use crate::autofix::codemods::CodegenStylist;
|
||||||
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||||
|
@ -76,7 +76,7 @@ fn is_constant_like(expr: &Expr) -> bool {
|
||||||
Expr::Tuple(ast::ExprTuple { elts, .. }) => elts.iter().all(is_constant_like),
|
Expr::Tuple(ast::ExprTuple { elts, .. }) => elts.iter().all(is_constant_like),
|
||||||
Expr::Name(ast::ExprName { id, .. }) => str::is_cased_uppercase(id),
|
Expr::Name(ast::ExprName { id, .. }) => str::is_cased_uppercase(id),
|
||||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::UAdd | Unaryop::USub | Unaryop::Invert,
|
op: UnaryOp::UAdd | UnaryOp::USub | UnaryOp::Invert,
|
||||||
operand,
|
operand,
|
||||||
range: _,
|
range: _,
|
||||||
}) => operand.is_constant_expr(),
|
}) => operand.is_constant_expr(),
|
||||||
|
@ -156,7 +156,7 @@ pub(crate) fn yoda_conditions(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
left: &Expr,
|
left: &Expr,
|
||||||
ops: &[Cmpop],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
) {
|
) {
|
||||||
let ([op], [right]) = (ops, comparators) else {
|
let ([op], [right]) = (ops, comparators) else {
|
||||||
|
@ -165,7 +165,7 @@ pub(crate) fn yoda_conditions(
|
||||||
|
|
||||||
if !matches!(
|
if !matches!(
|
||||||
op,
|
op,
|
||||||
Cmpop::Eq | Cmpop::NotEq | Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE,
|
CmpOp::Eq | CmpOp::NotEq | CmpOp::Lt | CmpOp::LtE | CmpOp::Gt | CmpOp::GtE,
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,8 +225,9 @@ fn function(
|
||||||
let args = args
|
let args = args
|
||||||
.posonlyargs
|
.posonlyargs
|
||||||
.iter()
|
.iter()
|
||||||
.chain(args.args.iter())
|
.chain(&args.args)
|
||||||
.chain(args.kwonlyargs.iter())
|
.chain(&args.kwonlyargs)
|
||||||
|
.map(|arg_with_default| &arg_with_default.def)
|
||||||
.chain(
|
.chain(
|
||||||
iter::once::<Option<&Arg>>(args.vararg.as_deref())
|
iter::once::<Option<&Arg>>(args.vararg.as_deref())
|
||||||
.flatten()
|
.flatten()
|
||||||
|
@ -252,9 +253,10 @@ fn method(
|
||||||
let args = args
|
let args = args
|
||||||
.posonlyargs
|
.posonlyargs
|
||||||
.iter()
|
.iter()
|
||||||
.chain(args.args.iter())
|
.chain(&args.args)
|
||||||
|
.chain(&args.kwonlyargs)
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.chain(args.kwonlyargs.iter())
|
.map(|arg_with_default| &arg_with_default.def)
|
||||||
.chain(
|
.chain(
|
||||||
iter::once::<Option<&Arg>>(args.vararg.as_deref())
|
iter::once::<Option<&Arg>>(args.vararg.as_deref())
|
||||||
.flatten()
|
.flatten()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_text_size::{TextRange, TextSize};
|
use ruff_text_size::{TextRange, TextSize};
|
||||||
use rustpython_parser::ast::{self, Excepthandler, MatchCase, Ranged, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, MatchCase, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_python_ast::source_code::Locator;
|
use ruff_python_ast::source_code::Locator;
|
||||||
use ruff_python_ast::statement_visitor::StatementVisitor;
|
use ruff_python_ast::statement_visitor::StatementVisitor;
|
||||||
|
@ -267,8 +267,8 @@ where
|
||||||
finalbody,
|
finalbody,
|
||||||
range: _,
|
range: _,
|
||||||
}) => {
|
}) => {
|
||||||
for excepthandler in handlers {
|
for except_handler in handlers {
|
||||||
self.visit_excepthandler(excepthandler);
|
self.visit_except_handler(except_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
for stmt in body {
|
for stmt in body {
|
||||||
|
@ -291,12 +291,12 @@ where
|
||||||
self.nested = prev_nested;
|
self.nested = prev_nested;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_excepthandler(&mut self, excepthandler: &'b Excepthandler) {
|
fn visit_except_handler(&mut self, except_handler: &'b ExceptHandler) {
|
||||||
let prev_nested = self.nested;
|
let prev_nested = self.nested;
|
||||||
self.nested = true;
|
self.nested = true;
|
||||||
|
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) =
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { body, .. }) =
|
||||||
excepthandler;
|
except_handler;
|
||||||
for stmt in body {
|
for stmt in body {
|
||||||
self.visit_stmt(stmt);
|
self.visit_stmt(stmt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -117,7 +117,7 @@ fn get_complexity_number(stmts: &[Stmt]) -> usize {
|
||||||
complexity += get_complexity_number(finalbody);
|
complexity += get_complexity_number(finalbody);
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
complexity += 1;
|
complexity += 1;
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||||
body, ..
|
body, ..
|
||||||
}) = handler;
|
}) = handler;
|
||||||
complexity += get_complexity_number(body);
|
complexity += get_complexity_number(body);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{Arguments, Decorator, Ranged};
|
use rustpython_parser::ast::{ArgWithDefault, Arguments, Decorator, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -74,8 +74,13 @@ pub(crate) fn invalid_first_argument_name_for_class_method(
|
||||||
) {
|
) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if let Some(arg) = args.posonlyargs.first().or_else(|| args.args.first()) {
|
if let Some(ArgWithDefault {
|
||||||
if &arg.arg != "cls" {
|
def,
|
||||||
|
default: _,
|
||||||
|
range: _,
|
||||||
|
}) = args.posonlyargs.first().or_else(|| args.args.first())
|
||||||
|
{
|
||||||
|
if &def.arg != "cls" {
|
||||||
if checker
|
if checker
|
||||||
.settings
|
.settings
|
||||||
.pep8_naming
|
.pep8_naming
|
||||||
|
@ -87,7 +92,7 @@ pub(crate) fn invalid_first_argument_name_for_class_method(
|
||||||
}
|
}
|
||||||
return Some(Diagnostic::new(
|
return Some(Diagnostic::new(
|
||||||
InvalidFirstArgumentNameForClassMethod,
|
InvalidFirstArgumentNameForClassMethod,
|
||||||
arg.range(),
|
def.range(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ pub(crate) fn invalid_first_argument_name_for_method(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let arg = args.posonlyargs.first().or_else(|| args.args.first())?;
|
let arg = args.posonlyargs.first().or_else(|| args.args.first())?;
|
||||||
if &arg.arg == "self" {
|
if &arg.def.arg == "self" {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if checker
|
if checker
|
||||||
|
@ -87,6 +87,6 @@ pub(crate) fn invalid_first_argument_name_for_method(
|
||||||
}
|
}
|
||||||
Some(Diagnostic::new(
|
Some(Diagnostic::new(
|
||||||
InvalidFirstArgumentNameForMethod,
|
InvalidFirstArgumentNameForMethod,
|
||||||
arg.range(),
|
arg.def.range(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_text_size::{TextLen, TextRange};
|
use ruff_text_size::{TextLen, TextRange};
|
||||||
use rustpython_parser::ast::{self, Cmpop, Expr};
|
use rustpython_parser::ast::{self, CmpOp, Expr};
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use ruff_python_ast::source_code::Generator;
|
use ruff_python_ast::source_code::Generator;
|
||||||
|
@ -13,7 +13,7 @@ pub(crate) fn is_ambiguous_name(name: &str) -> bool {
|
||||||
|
|
||||||
pub(crate) fn compare(
|
pub(crate) fn compare(
|
||||||
left: &Expr,
|
left: &Expr,
|
||||||
ops: &[Cmpop],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
generator: Generator,
|
generator: Generator,
|
||||||
) -> String {
|
) -> String {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Expr, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, Expr, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -58,7 +58,7 @@ impl Violation for BareExcept {
|
||||||
pub(crate) fn bare_except(
|
pub(crate) fn bare_except(
|
||||||
type_: Option<&Expr>,
|
type_: Option<&Expr>,
|
||||||
body: &[Stmt],
|
body: &[Stmt],
|
||||||
handler: &Excepthandler,
|
handler: &ExceptHandler,
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
) -> Option<Diagnostic> {
|
) -> Option<Diagnostic> {
|
||||||
if type_.is_none()
|
if type_.is_none()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustpython_parser::ast::{self, Arg, Arguments, Constant, Expr, Ranged, Stmt};
|
use rustpython_parser::ast::{self, Arg, ArgWithDefault, Arguments, Constant, Expr, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -176,22 +176,28 @@ fn function(
|
||||||
.posonlyargs
|
.posonlyargs
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(idx, arg)| Arg {
|
.map(|(idx, arg_with_default)| ArgWithDefault {
|
||||||
annotation: arg_types
|
def: Arg {
|
||||||
.get(idx)
|
annotation: arg_types
|
||||||
.map(|arg_type| Box::new(arg_type.clone())),
|
.get(idx)
|
||||||
..arg.clone()
|
.map(|arg_type| Box::new(arg_type.clone())),
|
||||||
|
..arg_with_default.def.clone()
|
||||||
|
},
|
||||||
|
..arg_with_default.clone()
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let new_args = args
|
let new_args = args
|
||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(idx, arg)| Arg {
|
.map(|(idx, arg_with_default)| ArgWithDefault {
|
||||||
annotation: arg_types
|
def: Arg {
|
||||||
.get(idx + new_posonlyargs.len())
|
annotation: arg_types
|
||||||
.map(|arg_type| Box::new(arg_type.clone())),
|
.get(idx + new_posonlyargs.len())
|
||||||
..arg.clone()
|
.map(|arg_type| Box::new(arg_type.clone())),
|
||||||
|
..arg_with_default.def.clone()
|
||||||
|
},
|
||||||
|
..arg_with_default.clone()
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let func = Stmt::FunctionDef(ast::StmtFunctionDef {
|
let func = Stmt::FunctionDef(ast::StmtFunctionDef {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use itertools::izip;
|
use itertools::izip;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use rustpython_parser::ast::{self, Cmpop, Constant, Expr, Ranged};
|
use rustpython_parser::ast::{self, CmpOp, Constant, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -12,16 +12,16 @@ use crate::registry::AsRule;
|
||||||
use crate::rules::pycodestyle::helpers::compare;
|
use crate::rules::pycodestyle::helpers::compare;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
enum EqCmpop {
|
enum EqCmpOp {
|
||||||
Eq,
|
Eq,
|
||||||
NotEq,
|
NotEq,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EqCmpop {
|
impl EqCmpOp {
|
||||||
fn try_from(value: Cmpop) -> Option<EqCmpop> {
|
fn try_from(value: CmpOp) -> Option<EqCmpOp> {
|
||||||
match value {
|
match value {
|
||||||
Cmpop::Eq => Some(EqCmpop::Eq),
|
CmpOp::Eq => Some(EqCmpOp::Eq),
|
||||||
Cmpop::NotEq => Some(EqCmpop::NotEq),
|
CmpOp::NotEq => Some(EqCmpOp::NotEq),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,23 +50,23 @@ impl EqCmpop {
|
||||||
///
|
///
|
||||||
/// [PEP 8]: https://peps.python.org/pep-0008/#programming-recommendations
|
/// [PEP 8]: https://peps.python.org/pep-0008/#programming-recommendations
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct NoneComparison(EqCmpop);
|
pub struct NoneComparison(EqCmpOp);
|
||||||
|
|
||||||
impl AlwaysAutofixableViolation for NoneComparison {
|
impl AlwaysAutofixableViolation for NoneComparison {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
let NoneComparison(op) = self;
|
let NoneComparison(op) = self;
|
||||||
match op {
|
match op {
|
||||||
EqCmpop::Eq => format!("Comparison to `None` should be `cond is None`"),
|
EqCmpOp::Eq => format!("Comparison to `None` should be `cond is None`"),
|
||||||
EqCmpop::NotEq => format!("Comparison to `None` should be `cond is not None`"),
|
EqCmpOp::NotEq => format!("Comparison to `None` should be `cond is not None`"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
fn autofix_title(&self) -> String {
|
||||||
let NoneComparison(op) = self;
|
let NoneComparison(op) = self;
|
||||||
match op {
|
match op {
|
||||||
EqCmpop::Eq => "Replace with `cond is None`".to_string(),
|
EqCmpOp::Eq => "Replace with `cond is None`".to_string(),
|
||||||
EqCmpop::NotEq => "Replace with `cond is not None`".to_string(),
|
EqCmpOp::NotEq => "Replace with `cond is not None`".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,23 +96,23 @@ impl AlwaysAutofixableViolation for NoneComparison {
|
||||||
///
|
///
|
||||||
/// [PEP 8]: https://peps.python.org/pep-0008/#programming-recommendations
|
/// [PEP 8]: https://peps.python.org/pep-0008/#programming-recommendations
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct TrueFalseComparison(bool, EqCmpop);
|
pub struct TrueFalseComparison(bool, EqCmpOp);
|
||||||
|
|
||||||
impl AlwaysAutofixableViolation for TrueFalseComparison {
|
impl AlwaysAutofixableViolation for TrueFalseComparison {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
let TrueFalseComparison(value, op) = self;
|
let TrueFalseComparison(value, op) = self;
|
||||||
match (value, op) {
|
match (value, op) {
|
||||||
(true, EqCmpop::Eq) => {
|
(true, EqCmpOp::Eq) => {
|
||||||
format!("Comparison to `True` should be `cond is True` or `if cond:`")
|
format!("Comparison to `True` should be `cond is True` or `if cond:`")
|
||||||
}
|
}
|
||||||
(true, EqCmpop::NotEq) => {
|
(true, EqCmpOp::NotEq) => {
|
||||||
format!("Comparison to `True` should be `cond is not True` or `if not cond:`")
|
format!("Comparison to `True` should be `cond is not True` or `if not cond:`")
|
||||||
}
|
}
|
||||||
(false, EqCmpop::Eq) => {
|
(false, EqCmpOp::Eq) => {
|
||||||
format!("Comparison to `False` should be `cond is False` or `if not cond:`")
|
format!("Comparison to `False` should be `cond is False` or `if not cond:`")
|
||||||
}
|
}
|
||||||
(false, EqCmpop::NotEq) => {
|
(false, EqCmpOp::NotEq) => {
|
||||||
format!("Comparison to `False` should be `cond is not False` or `if cond:`")
|
format!("Comparison to `False` should be `cond is not False` or `if cond:`")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,10 +121,10 @@ impl AlwaysAutofixableViolation for TrueFalseComparison {
|
||||||
fn autofix_title(&self) -> String {
|
fn autofix_title(&self) -> String {
|
||||||
let TrueFalseComparison(value, op) = self;
|
let TrueFalseComparison(value, op) = self;
|
||||||
match (value, op) {
|
match (value, op) {
|
||||||
(true, EqCmpop::Eq) => "Replace with `cond is True`".to_string(),
|
(true, EqCmpOp::Eq) => "Replace with `cond is True`".to_string(),
|
||||||
(true, EqCmpop::NotEq) => "Replace with `cond is not True`".to_string(),
|
(true, EqCmpOp::NotEq) => "Replace with `cond is not True`".to_string(),
|
||||||
(false, EqCmpop::Eq) => "Replace with `cond is False`".to_string(),
|
(false, EqCmpOp::Eq) => "Replace with `cond is False`".to_string(),
|
||||||
(false, EqCmpop::NotEq) => "Replace with `cond is not False`".to_string(),
|
(false, EqCmpOp::NotEq) => "Replace with `cond is not False`".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ pub(crate) fn literal_comparisons(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
left: &Expr,
|
left: &Expr,
|
||||||
ops: &[Cmpop],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
check_none_comparisons: bool,
|
check_none_comparisons: bool,
|
||||||
check_true_false_comparisons: bool,
|
check_true_false_comparisons: bool,
|
||||||
|
@ -143,7 +143,7 @@ pub(crate) fn literal_comparisons(
|
||||||
// through the list of operators, we apply "dummy" fixes for each error,
|
// through the list of operators, we apply "dummy" fixes for each error,
|
||||||
// then replace the entire expression at the end with one "real" fix, to
|
// then replace the entire expression at the end with one "real" fix, to
|
||||||
// avoid conflicts.
|
// avoid conflicts.
|
||||||
let mut bad_ops: FxHashMap<usize, Cmpop> = FxHashMap::default();
|
let mut bad_ops: FxHashMap<usize, CmpOp> = FxHashMap::default();
|
||||||
let mut diagnostics: Vec<Diagnostic> = vec![];
|
let mut diagnostics: Vec<Diagnostic> = vec![];
|
||||||
|
|
||||||
let op = ops.first().unwrap();
|
let op = ops.first().unwrap();
|
||||||
|
@ -153,20 +153,20 @@ pub(crate) fn literal_comparisons(
|
||||||
let next = &comparators[0];
|
let next = &comparators[0];
|
||||||
|
|
||||||
if !helpers::is_constant_non_singleton(next) {
|
if !helpers::is_constant_non_singleton(next) {
|
||||||
if let Some(op) = EqCmpop::try_from(*op) {
|
if let Some(op) = EqCmpOp::try_from(*op) {
|
||||||
if check_none_comparisons && is_const_none(comparator) {
|
if check_none_comparisons && is_const_none(comparator) {
|
||||||
match op {
|
match op {
|
||||||
EqCmpop::Eq => {
|
EqCmpOp::Eq => {
|
||||||
let diagnostic = Diagnostic::new(NoneComparison(op), comparator.range());
|
let diagnostic = Diagnostic::new(NoneComparison(op), comparator.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
bad_ops.insert(0, Cmpop::Is);
|
bad_ops.insert(0, CmpOp::Is);
|
||||||
}
|
}
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
EqCmpop::NotEq => {
|
EqCmpOp::NotEq => {
|
||||||
let diagnostic = Diagnostic::new(NoneComparison(op), comparator.range());
|
let diagnostic = Diagnostic::new(NoneComparison(op), comparator.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
bad_ops.insert(0, Cmpop::IsNot);
|
bad_ops.insert(0, CmpOp::IsNot);
|
||||||
}
|
}
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
@ -181,23 +181,23 @@ pub(crate) fn literal_comparisons(
|
||||||
}) = comparator
|
}) = comparator
|
||||||
{
|
{
|
||||||
match op {
|
match op {
|
||||||
EqCmpop::Eq => {
|
EqCmpOp::Eq => {
|
||||||
let diagnostic = Diagnostic::new(
|
let diagnostic = Diagnostic::new(
|
||||||
TrueFalseComparison(*value, op),
|
TrueFalseComparison(*value, op),
|
||||||
comparator.range(),
|
comparator.range(),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
bad_ops.insert(0, Cmpop::Is);
|
bad_ops.insert(0, CmpOp::Is);
|
||||||
}
|
}
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
EqCmpop::NotEq => {
|
EqCmpOp::NotEq => {
|
||||||
let diagnostic = Diagnostic::new(
|
let diagnostic = Diagnostic::new(
|
||||||
TrueFalseComparison(*value, op),
|
TrueFalseComparison(*value, op),
|
||||||
comparator.range(),
|
comparator.range(),
|
||||||
);
|
);
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
bad_ops.insert(0, Cmpop::IsNot);
|
bad_ops.insert(0, CmpOp::IsNot);
|
||||||
}
|
}
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
@ -214,20 +214,20 @@ pub(crate) fn literal_comparisons(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(op) = EqCmpop::try_from(*op) {
|
if let Some(op) = EqCmpOp::try_from(*op) {
|
||||||
if check_none_comparisons && is_const_none(next) {
|
if check_none_comparisons && is_const_none(next) {
|
||||||
match op {
|
match op {
|
||||||
EqCmpop::Eq => {
|
EqCmpOp::Eq => {
|
||||||
let diagnostic = Diagnostic::new(NoneComparison(op), next.range());
|
let diagnostic = Diagnostic::new(NoneComparison(op), next.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
bad_ops.insert(idx, Cmpop::Is);
|
bad_ops.insert(idx, CmpOp::Is);
|
||||||
}
|
}
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
EqCmpop::NotEq => {
|
EqCmpOp::NotEq => {
|
||||||
let diagnostic = Diagnostic::new(NoneComparison(op), next.range());
|
let diagnostic = Diagnostic::new(NoneComparison(op), next.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
bad_ops.insert(idx, Cmpop::IsNot);
|
bad_ops.insert(idx, CmpOp::IsNot);
|
||||||
}
|
}
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
@ -242,19 +242,19 @@ pub(crate) fn literal_comparisons(
|
||||||
}) = next
|
}) = next
|
||||||
{
|
{
|
||||||
match op {
|
match op {
|
||||||
EqCmpop::Eq => {
|
EqCmpOp::Eq => {
|
||||||
let diagnostic =
|
let diagnostic =
|
||||||
Diagnostic::new(TrueFalseComparison(*value, op), next.range());
|
Diagnostic::new(TrueFalseComparison(*value, op), next.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
bad_ops.insert(idx, Cmpop::Is);
|
bad_ops.insert(idx, CmpOp::Is);
|
||||||
}
|
}
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
EqCmpop::NotEq => {
|
EqCmpOp::NotEq => {
|
||||||
let diagnostic =
|
let diagnostic =
|
||||||
Diagnostic::new(TrueFalseComparison(*value, op), next.range());
|
Diagnostic::new(TrueFalseComparison(*value, op), next.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
bad_ops.insert(idx, Cmpop::IsNot);
|
bad_ops.insert(idx, CmpOp::IsNot);
|
||||||
}
|
}
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Cmpop, Expr, Ranged, Unaryop};
|
use rustpython_parser::ast::{self, CmpOp, Expr, Ranged, UnaryOp};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -77,12 +77,12 @@ impl AlwaysAutofixableViolation for NotIsTest {
|
||||||
pub(crate) fn not_tests(
|
pub(crate) fn not_tests(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
op: Unaryop,
|
op: UnaryOp,
|
||||||
operand: &Expr,
|
operand: &Expr,
|
||||||
check_not_in: bool,
|
check_not_in: bool,
|
||||||
check_not_is: bool,
|
check_not_is: bool,
|
||||||
) {
|
) {
|
||||||
if matches!(op, Unaryop::Not) {
|
if matches!(op, UnaryOp::Not) {
|
||||||
if let Expr::Compare(ast::ExprCompare {
|
if let Expr::Compare(ast::ExprCompare {
|
||||||
left,
|
left,
|
||||||
ops,
|
ops,
|
||||||
|
@ -90,19 +90,19 @@ pub(crate) fn not_tests(
|
||||||
range: _,
|
range: _,
|
||||||
}) = operand
|
}) = operand
|
||||||
{
|
{
|
||||||
if !matches!(&ops[..], [Cmpop::In | Cmpop::Is]) {
|
if !matches!(&ops[..], [CmpOp::In | CmpOp::Is]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for op in ops.iter() {
|
for op in ops.iter() {
|
||||||
match op {
|
match op {
|
||||||
Cmpop::In => {
|
CmpOp::In => {
|
||||||
if check_not_in {
|
if check_not_in {
|
||||||
let mut diagnostic = Diagnostic::new(NotInTest, operand.range());
|
let mut diagnostic = Diagnostic::new(NotInTest, operand.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.set_fix(Fix::automatic(Edit::range_replacement(
|
diagnostic.set_fix(Fix::automatic(Edit::range_replacement(
|
||||||
compare(
|
compare(
|
||||||
left,
|
left,
|
||||||
&[Cmpop::NotIn],
|
&[CmpOp::NotIn],
|
||||||
comparators,
|
comparators,
|
||||||
checker.generator(),
|
checker.generator(),
|
||||||
),
|
),
|
||||||
|
@ -112,14 +112,14 @@ pub(crate) fn not_tests(
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Cmpop::Is => {
|
CmpOp::Is => {
|
||||||
if check_not_is {
|
if check_not_is {
|
||||||
let mut diagnostic = Diagnostic::new(NotIsTest, operand.range());
|
let mut diagnostic = Diagnostic::new(NotIsTest, operand.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
diagnostic.set_fix(Fix::automatic(Edit::range_replacement(
|
diagnostic.set_fix(Fix::automatic(Edit::range_replacement(
|
||||||
compare(
|
compare(
|
||||||
left,
|
left,
|
||||||
&[Cmpop::IsNot],
|
&[CmpOp::IsNot],
|
||||||
comparators,
|
comparators,
|
||||||
checker.generator(),
|
checker.generator(),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use itertools::izip;
|
use itertools::izip;
|
||||||
use rustpython_parser::ast::{self, Cmpop, Constant, Expr, Ranged};
|
use rustpython_parser::ast::{self, CmpOp, Constant, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -41,11 +41,11 @@ impl Violation for TypeComparison {
|
||||||
pub(crate) fn type_comparison(
|
pub(crate) fn type_comparison(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
ops: &[Cmpop],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
) {
|
) {
|
||||||
for (op, right) in izip!(ops, comparators) {
|
for (op, right) in izip!(ops, comparators) {
|
||||||
if !matches!(op, Cmpop::Is | Cmpop::IsNot | Cmpop::Eq | Cmpop::NotEq) {
|
if !matches!(op, CmpOp::Is | CmpOp::IsNot | CmpOp::Eq | CmpOp::NotEq) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
match right {
|
match right {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use rustpython_parser::ast::{self, Stmt};
|
use rustpython_parser::ast::{self, ArgWithDefault, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Violation};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Violation};
|
||||||
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
||||||
|
@ -713,11 +713,15 @@ fn missing_args(checker: &mut Checker, docstring: &Docstring, docstrings_args: &
|
||||||
|
|
||||||
// Look for arguments that weren't included in the docstring.
|
// Look for arguments that weren't included in the docstring.
|
||||||
let mut missing_arg_names: FxHashSet<String> = FxHashSet::default();
|
let mut missing_arg_names: FxHashSet<String> = FxHashSet::default();
|
||||||
for arg in arguments
|
for ArgWithDefault {
|
||||||
|
def,
|
||||||
|
default: _,
|
||||||
|
range: _,
|
||||||
|
} in arguments
|
||||||
.posonlyargs
|
.posonlyargs
|
||||||
.iter()
|
.iter()
|
||||||
.chain(arguments.args.iter())
|
.chain(&arguments.args)
|
||||||
.chain(arguments.kwonlyargs.iter())
|
.chain(&arguments.kwonlyargs)
|
||||||
.skip(
|
.skip(
|
||||||
// If this is a non-static method, skip `cls` or `self`.
|
// If this is a non-static method, skip `cls` or `self`.
|
||||||
usize::from(
|
usize::from(
|
||||||
|
@ -726,7 +730,7 @@ fn missing_args(checker: &mut Checker, docstring: &Docstring, docstrings_args: &
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
let arg_name = arg.arg.as_str();
|
let arg_name = def.arg.as_str();
|
||||||
if !arg_name.starts_with('_') && !docstrings_args.contains(arg_name) {
|
if !arg_name.starts_with('_') && !docstrings_args.contains(arg_name) {
|
||||||
missing_arg_names.insert(arg_name.to_string());
|
missing_arg_names.insert(arg_name.to_string());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use anyhow::{bail, Ok, Result};
|
use anyhow::{bail, Ok, Result};
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustpython_parser::ast::{Excepthandler, Expr, Ranged};
|
use rustpython_parser::ast::{ExceptHandler, Expr, Ranged};
|
||||||
use rustpython_parser::{lexer, Mode, Tok};
|
use rustpython_parser::{lexer, Mode, Tok};
|
||||||
|
|
||||||
use ruff_diagnostics::Edit;
|
use ruff_diagnostics::Edit;
|
||||||
|
@ -90,17 +90,17 @@ pub(crate) fn remove_unused_positional_arguments_from_format_call(
|
||||||
|
|
||||||
/// Generate a [`Edit`] to remove the binding from an exception handler.
|
/// Generate a [`Edit`] to remove the binding from an exception handler.
|
||||||
pub(crate) fn remove_exception_handler_assignment(
|
pub(crate) fn remove_exception_handler_assignment(
|
||||||
excepthandler: &Excepthandler,
|
except_handler: &ExceptHandler,
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
) -> Result<Edit> {
|
) -> Result<Edit> {
|
||||||
let contents = locator.slice(excepthandler.range());
|
let contents = locator.slice(except_handler.range());
|
||||||
let mut fix_start = None;
|
let mut fix_start = None;
|
||||||
let mut fix_end = None;
|
let mut fix_end = None;
|
||||||
|
|
||||||
// End of the token just before the `as` to the semicolon.
|
// End of the token just before the `as` to the semicolon.
|
||||||
let mut prev = None;
|
let mut prev = None;
|
||||||
for (tok, range) in
|
for (tok, range) in
|
||||||
lexer::lex_starts_at(contents, Mode::Module, excepthandler.start()).flatten()
|
lexer::lex_starts_at(contents, Mode::Module, except_handler.start()).flatten()
|
||||||
{
|
{
|
||||||
if matches!(tok, Tok::As) {
|
if matches!(tok, Tok::As) {
|
||||||
fix_start = prev;
|
fix_start = prev;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler};
|
use rustpython_parser::ast::{self, ExceptHandler};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -55,11 +55,11 @@ impl Violation for DefaultExceptNotLast {
|
||||||
|
|
||||||
/// F707
|
/// F707
|
||||||
pub(crate) fn default_except_not_last(
|
pub(crate) fn default_except_not_last(
|
||||||
handlers: &[Excepthandler],
|
handlers: &[ExceptHandler],
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
) -> Option<Diagnostic> {
|
) -> Option<Diagnostic> {
|
||||||
for (idx, handler) in handlers.iter().enumerate() {
|
for (idx, handler) in handlers.iter().enumerate() {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = handler;
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, .. }) = handler;
|
||||||
if type_.is_none() && idx < handlers.len() - 1 {
|
if type_.is_none() && idx < handlers.len() - 1 {
|
||||||
return Some(Diagnostic::new(
|
return Some(Diagnostic::new(
|
||||||
DefaultExceptNotLast,
|
DefaultExceptNotLast,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use itertools::izip;
|
use itertools::izip;
|
||||||
use log::error;
|
use log::error;
|
||||||
use once_cell::unsync::Lazy;
|
use once_cell::unsync::Lazy;
|
||||||
use rustpython_parser::ast::{Cmpop, Expr, Ranged};
|
use rustpython_parser::ast::{CmpOp, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -47,24 +47,24 @@ use crate::registry::AsRule;
|
||||||
/// - [_Why does Python log a SyntaxWarning for ‘is’ with literals?_ by Adam Johnson](https://adamj.eu/tech/2020/01/21/why-does-python-3-8-syntaxwarning-for-is-literal/)
|
/// - [_Why does Python log a SyntaxWarning for ‘is’ with literals?_ by Adam Johnson](https://adamj.eu/tech/2020/01/21/why-does-python-3-8-syntaxwarning-for-is-literal/)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct IsLiteral {
|
pub struct IsLiteral {
|
||||||
cmpop: IsCmpop,
|
cmp_op: IsCmpOp,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AlwaysAutofixableViolation for IsLiteral {
|
impl AlwaysAutofixableViolation for IsLiteral {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
let IsLiteral { cmpop } = self;
|
let IsLiteral { cmp_op } = self;
|
||||||
match cmpop {
|
match cmp_op {
|
||||||
IsCmpop::Is => format!("Use `==` to compare constant literals"),
|
IsCmpOp::Is => format!("Use `==` to compare constant literals"),
|
||||||
IsCmpop::IsNot => format!("Use `!=` to compare constant literals"),
|
IsCmpOp::IsNot => format!("Use `!=` to compare constant literals"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
fn autofix_title(&self) -> String {
|
||||||
let IsLiteral { cmpop } = self;
|
let IsLiteral { cmp_op } = self;
|
||||||
match cmpop {
|
match cmp_op {
|
||||||
IsCmpop::Is => "Replace `is` with `==`".to_string(),
|
IsCmpOp::Is => "Replace `is` with `==`".to_string(),
|
||||||
IsCmpop::IsNot => "Replace `is not` with `!=`".to_string(),
|
IsCmpOp::IsNot => "Replace `is not` with `!=`".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,24 +73,24 @@ impl AlwaysAutofixableViolation for IsLiteral {
|
||||||
pub(crate) fn invalid_literal_comparison(
|
pub(crate) fn invalid_literal_comparison(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
left: &Expr,
|
left: &Expr,
|
||||||
ops: &[Cmpop],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
) {
|
) {
|
||||||
let located = Lazy::new(|| helpers::locate_cmpops(expr, checker.locator));
|
let located = Lazy::new(|| helpers::locate_cmp_ops(expr, checker.locator));
|
||||||
let mut left = left;
|
let mut left = left;
|
||||||
for (index, (op, right)) in izip!(ops, comparators).enumerate() {
|
for (index, (op, right)) in izip!(ops, comparators).enumerate() {
|
||||||
if matches!(op, Cmpop::Is | Cmpop::IsNot)
|
if matches!(op, CmpOp::Is | CmpOp::IsNot)
|
||||||
&& (helpers::is_constant_non_singleton(left)
|
&& (helpers::is_constant_non_singleton(left)
|
||||||
|| helpers::is_constant_non_singleton(right))
|
|| helpers::is_constant_non_singleton(right))
|
||||||
{
|
{
|
||||||
let mut diagnostic = Diagnostic::new(IsLiteral { cmpop: op.into() }, expr.range());
|
let mut diagnostic = Diagnostic::new(IsLiteral { cmp_op: op.into() }, expr.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if let Some(located_op) = &located.get(index) {
|
if let Some(located_op) = &located.get(index) {
|
||||||
assert_eq!(located_op.op, *op);
|
assert_eq!(located_op.op, *op);
|
||||||
if let Some(content) = match located_op.op {
|
if let Some(content) = match located_op.op {
|
||||||
Cmpop::Is => Some("==".to_string()),
|
CmpOp::Is => Some("==".to_string()),
|
||||||
Cmpop::IsNot => Some("!=".to_string()),
|
CmpOp::IsNot => Some("!=".to_string()),
|
||||||
node => {
|
node => {
|
||||||
error!("Failed to fix invalid comparison: {node:?}");
|
error!("Failed to fix invalid comparison: {node:?}");
|
||||||
None
|
None
|
||||||
|
@ -112,17 +112,17 @@ pub(crate) fn invalid_literal_comparison(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
enum IsCmpop {
|
enum IsCmpOp {
|
||||||
Is,
|
Is,
|
||||||
IsNot,
|
IsNot,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Cmpop> for IsCmpop {
|
impl From<&CmpOp> for IsCmpOp {
|
||||||
fn from(cmpop: &Cmpop) -> Self {
|
fn from(cmp_op: &CmpOp) -> Self {
|
||||||
match cmpop {
|
match cmp_op {
|
||||||
Cmpop::Is => IsCmpop::Is,
|
CmpOp::Is => IsCmpOp::Is,
|
||||||
Cmpop::IsNot => IsCmpop::IsNot,
|
CmpOp::IsNot => IsCmpOp::IsNot,
|
||||||
_ => panic!("Expected Cmpop::Is | Cmpop::IsNot"),
|
_ => panic!("Expected CmpOp::Is | CmpOp::IsNot"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,10 +253,10 @@ fn remove_unused_variable(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Third case: withitem (`with foo() as x:`)
|
// Third case: with_item (`with foo() as x:`)
|
||||||
if let Stmt::With(ast::StmtWith { items, .. }) = stmt {
|
if let Stmt::With(ast::StmtWith { items, .. }) = stmt {
|
||||||
// Find the binding that matches the given `Range`.
|
// Find the binding that matches the given `Range`.
|
||||||
// TODO(charlie): Store the `Withitem` in the `Binding`.
|
// TODO(charlie): Store the `WithItem` in the `Binding`.
|
||||||
for item in items {
|
for item in items {
|
||||||
if let Some(optional_vars) = &item.optional_vars {
|
if let Some(optional_vars) = &item.optional_vars {
|
||||||
if optional_vars.range() == range {
|
if optional_vars.range() == range {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use rustpython_parser::ast;
|
use rustpython_parser::ast;
|
||||||
use rustpython_parser::ast::Cmpop;
|
use rustpython_parser::ast::CmpOp;
|
||||||
|
|
||||||
use ruff_python_semantic::analyze::function_type;
|
use ruff_python_semantic::analyze::function_type;
|
||||||
use ruff_python_semantic::{ScopeKind, SemanticModel};
|
use ruff_python_semantic::{ScopeKind, SemanticModel};
|
||||||
|
@ -47,29 +47,29 @@ pub(super) fn in_dunder_init(semantic: &SemanticModel, settings: &Settings) -> b
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper around [`Cmpop`] that implements `Display`.
|
/// A wrapper around [`CmpOp`] that implements `Display`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct CmpopExt(Cmpop);
|
pub(super) struct CmpOpExt(CmpOp);
|
||||||
|
|
||||||
impl From<&Cmpop> for CmpopExt {
|
impl From<&CmpOp> for CmpOpExt {
|
||||||
fn from(cmpop: &Cmpop) -> Self {
|
fn from(cmp_op: &CmpOp) -> Self {
|
||||||
CmpopExt(*cmpop)
|
CmpOpExt(*cmp_op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CmpopExt {
|
impl fmt::Display for CmpOpExt {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let representation = match self.0 {
|
let representation = match self.0 {
|
||||||
Cmpop::Eq => "==",
|
CmpOp::Eq => "==",
|
||||||
Cmpop::NotEq => "!=",
|
CmpOp::NotEq => "!=",
|
||||||
Cmpop::Lt => "<",
|
CmpOp::Lt => "<",
|
||||||
Cmpop::LtE => "<=",
|
CmpOp::LtE => "<=",
|
||||||
Cmpop::Gt => ">",
|
CmpOp::Gt => ">",
|
||||||
Cmpop::GtE => ">=",
|
CmpOp::GtE => ">=",
|
||||||
Cmpop::Is => "is",
|
CmpOp::Is => "is",
|
||||||
Cmpop::IsNot => "is not",
|
CmpOp::IsNot => "is not",
|
||||||
Cmpop::In => "in",
|
CmpOp::In => "in",
|
||||||
Cmpop::NotIn => "not in",
|
CmpOp::NotIn => "not in",
|
||||||
};
|
};
|
||||||
write!(f, "{representation}")
|
write!(f, "{representation}")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Expr, Ranged};
|
use rustpython_parser::ast::{self, ExceptHandler, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -6,16 +6,16 @@ use ruff_macros::{derive_message_formats, violation};
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
enum Boolop {
|
enum BoolOp {
|
||||||
And,
|
And,
|
||||||
Or,
|
Or,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&ast::Boolop> for Boolop {
|
impl From<&ast::BoolOp> for BoolOp {
|
||||||
fn from(op: &ast::Boolop) -> Self {
|
fn from(op: &ast::BoolOp) -> Self {
|
||||||
match op {
|
match op {
|
||||||
ast::Boolop::And => Boolop::And,
|
ast::BoolOp::And => BoolOp::And,
|
||||||
ast::Boolop::Or => Boolop::Or,
|
ast::BoolOp::Or => BoolOp::Or,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ impl From<&ast::Boolop> for Boolop {
|
||||||
/// ```
|
/// ```
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct BinaryOpException {
|
pub struct BinaryOpException {
|
||||||
op: Boolop,
|
op: BoolOp,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Violation for BinaryOpException {
|
impl Violation for BinaryOpException {
|
||||||
|
@ -55,15 +55,16 @@ impl Violation for BinaryOpException {
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
let BinaryOpException { op } = self;
|
let BinaryOpException { op } = self;
|
||||||
match op {
|
match op {
|
||||||
Boolop::And => format!("Exception to catch is the result of a binary `and` operation"),
|
BoolOp::And => format!("Exception to catch is the result of a binary `and` operation"),
|
||||||
Boolop::Or => format!("Exception to catch is the result of a binary `or` operation"),
|
BoolOp::Or => format!("Exception to catch is the result of a binary `or` operation"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PLW0711
|
/// PLW0711
|
||||||
pub(crate) fn binary_op_exception(checker: &mut Checker, excepthandler: &Excepthandler) {
|
pub(crate) fn binary_op_exception(checker: &mut Checker, except_handler: &ExceptHandler) {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = excepthandler;
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, .. }) =
|
||||||
|
except_handler;
|
||||||
|
|
||||||
let Some(type_) = type_ else {
|
let Some(type_) = type_ else {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustpython_parser::ast::{self, Cmpop, Constant, Expr, Ranged};
|
use rustpython_parser::ast::{self, CmpOp, Constant, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -8,28 +8,28 @@ use ruff_macros::{derive_message_formats, violation};
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
pub(crate) enum EmptyStringCmpop {
|
pub(crate) enum EmptyStringCmpOp {
|
||||||
Is,
|
Is,
|
||||||
IsNot,
|
IsNot,
|
||||||
Eq,
|
Eq,
|
||||||
NotEq,
|
NotEq,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&Cmpop> for EmptyStringCmpop {
|
impl TryFrom<&CmpOp> for EmptyStringCmpOp {
|
||||||
type Error = anyhow::Error;
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
fn try_from(value: &Cmpop) -> Result<Self, Self::Error> {
|
fn try_from(value: &CmpOp) -> Result<Self, Self::Error> {
|
||||||
match value {
|
match value {
|
||||||
Cmpop::Is => Ok(Self::Is),
|
CmpOp::Is => Ok(Self::Is),
|
||||||
Cmpop::IsNot => Ok(Self::IsNot),
|
CmpOp::IsNot => Ok(Self::IsNot),
|
||||||
Cmpop::Eq => Ok(Self::Eq),
|
CmpOp::Eq => Ok(Self::Eq),
|
||||||
Cmpop::NotEq => Ok(Self::NotEq),
|
CmpOp::NotEq => Ok(Self::NotEq),
|
||||||
_ => bail!("{value:?} cannot be converted to EmptyStringCmpop"),
|
_ => bail!("{value:?} cannot be converted to EmptyStringCmpOp"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EmptyStringCmpop {
|
impl EmptyStringCmpOp {
|
||||||
pub(crate) fn into_unary(self) -> &'static str {
|
pub(crate) fn into_unary(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Self::Is | Self::Eq => "not ",
|
Self::Is | Self::Eq => "not ",
|
||||||
|
@ -38,7 +38,7 @@ impl EmptyStringCmpop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for EmptyStringCmpop {
|
impl std::fmt::Display for EmptyStringCmpOp {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let repr = match self {
|
let repr = match self {
|
||||||
Self::Is => "is",
|
Self::Is => "is",
|
||||||
|
@ -93,7 +93,7 @@ impl Violation for CompareToEmptyString {
|
||||||
pub(crate) fn compare_to_empty_string(
|
pub(crate) fn compare_to_empty_string(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
left: &Expr,
|
left: &Expr,
|
||||||
ops: &[Cmpop],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
) {
|
) {
|
||||||
// Omit string comparison rules within subscripts. This is mostly commonly used within
|
// Omit string comparison rules within subscripts. This is mostly commonly used within
|
||||||
|
@ -110,7 +110,7 @@ pub(crate) fn compare_to_empty_string(
|
||||||
.tuple_windows::<(&Expr<_>, &Expr<_>)>()
|
.tuple_windows::<(&Expr<_>, &Expr<_>)>()
|
||||||
.zip(ops)
|
.zip(ops)
|
||||||
{
|
{
|
||||||
if let Ok(op) = EmptyStringCmpop::try_from(op) {
|
if let Ok(op) = EmptyStringCmpOp::try_from(op) {
|
||||||
if std::mem::take(&mut first) {
|
if std::mem::take(&mut first) {
|
||||||
// Check the left-most expression.
|
// Check the left-most expression.
|
||||||
if let Expr::Constant(ast::ExprConstant { value, .. }) = &lhs {
|
if let Expr::Constant(ast::ExprConstant { value, .. }) = &lhs {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustpython_parser::ast::{self, Cmpop, Expr, Ranged};
|
use rustpython_parser::ast::{self, CmpOp, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::rules::pylint::helpers::CmpopExt;
|
use crate::rules::pylint::helpers::CmpOpExt;
|
||||||
|
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for comparisons between constants.
|
/// Checks for comparisons between constants.
|
||||||
|
@ -30,7 +30,7 @@ use crate::rules::pylint::helpers::CmpopExt;
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct ComparisonOfConstant {
|
pub struct ComparisonOfConstant {
|
||||||
left_constant: String,
|
left_constant: String,
|
||||||
op: Cmpop,
|
op: CmpOp,
|
||||||
right_constant: String,
|
right_constant: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ impl Violation for ComparisonOfConstant {
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
"Two constants compared in a comparison, consider replacing `{left_constant} {} {right_constant}`",
|
"Two constants compared in a comparison, consider replacing `{left_constant} {} {right_constant}`",
|
||||||
CmpopExt::from(op)
|
CmpOpExt::from(op)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ impl Violation for ComparisonOfConstant {
|
||||||
pub(crate) fn comparison_of_constant(
|
pub(crate) fn comparison_of_constant(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
left: &Expr,
|
left: &Expr,
|
||||||
ops: &[Cmpop],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
) {
|
) {
|
||||||
for ((left, right), op) in std::iter::once(left)
|
for ((left, right), op) in std::iter::once(left)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustpython_parser::ast::{Cmpop, Expr, Ranged};
|
use rustpython_parser::ast::{CmpOp, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::rules::pylint::helpers::CmpopExt;
|
use crate::rules::pylint::helpers::CmpOpExt;
|
||||||
|
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for operations that compare a name to itself.
|
/// Checks for operations that compare a name to itself.
|
||||||
|
@ -24,7 +24,7 @@ use crate::rules::pylint::helpers::CmpopExt;
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct ComparisonWithItself {
|
pub struct ComparisonWithItself {
|
||||||
left: String,
|
left: String,
|
||||||
op: Cmpop,
|
op: CmpOp,
|
||||||
right: String,
|
right: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ impl Violation for ComparisonWithItself {
|
||||||
let ComparisonWithItself { left, op, right } = self;
|
let ComparisonWithItself { left, op, right } = self;
|
||||||
format!(
|
format!(
|
||||||
"Name compared with itself, consider replacing `{left} {} {right}`",
|
"Name compared with itself, consider replacing `{left} {} {right}`",
|
||||||
CmpopExt::from(op)
|
CmpOpExt::from(op)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ impl Violation for ComparisonWithItself {
|
||||||
pub(crate) fn comparison_with_itself(
|
pub(crate) fn comparison_with_itself(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
left: &Expr,
|
left: &Expr,
|
||||||
ops: &[Cmpop],
|
ops: &[CmpOp],
|
||||||
comparators: &[Expr],
|
comparators: &[Expr],
|
||||||
) {
|
) {
|
||||||
for ((left, right), op) in std::iter::once(left)
|
for ((left, right), op) in std::iter::once(left)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustpython_parser::ast::{self, Constant, Expr, Ranged, Unaryop};
|
use rustpython_parser::ast::{self, Constant, Expr, Ranged, UnaryOp};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -55,7 +55,7 @@ fn as_constant(expr: &Expr) -> Option<&Constant> {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Constant(ast::ExprConstant { value, .. }) => Some(value),
|
Expr::Constant(ast::ExprConstant { value, .. }) => Some(value),
|
||||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::UAdd | Unaryop::USub | Unaryop::Invert,
|
op: UnaryOp::UAdd | UnaryOp::USub | UnaryOp::Invert,
|
||||||
operand,
|
operand,
|
||||||
range: _,
|
range: _,
|
||||||
}) => match operand.as_ref() {
|
}) => match operand.as_ref() {
|
||||||
|
|
|
@ -59,14 +59,14 @@ pub(crate) fn property_with_parameters(
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if checker.semantic().is_builtin("property")
|
if args
|
||||||
&& args
|
.posonlyargs
|
||||||
.args
|
.iter()
|
||||||
.iter()
|
.chain(&args.args)
|
||||||
.chain(args.posonlyargs.iter())
|
.chain(&args.kwonlyargs)
|
||||||
.chain(args.kwonlyargs.iter())
|
.count()
|
||||||
.count()
|
> 1
|
||||||
> 1
|
&& checker.semantic().is_builtin("property")
|
||||||
{
|
{
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
PropertyWithParameters,
|
PropertyWithParameters,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{fmt, iter};
|
use std::{fmt, iter};
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rustpython_parser::ast::{self, Expr, ExprContext, Ranged, Stmt, Withitem};
|
use rustpython_parser::ast::{self, Expr, ExprContext, Ranged, Stmt, WithItem};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -308,7 +308,7 @@ fn assignment_targets_from_expr<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assignment_targets_from_with_items<'a>(
|
fn assignment_targets_from_with_items<'a>(
|
||||||
items: &'a [Withitem],
|
items: &'a [WithItem],
|
||||||
dummy_variable_rgx: &'a Regex,
|
dummy_variable_rgx: &'a Regex,
|
||||||
) -> impl Iterator<Item = &'a Expr> + 'a {
|
) -> impl Iterator<Item = &'a Expr> + 'a {
|
||||||
items
|
items
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use rustpython_parser::ast::{self, Boolop, Expr, Ranged};
|
use rustpython_parser::ast::{self, BoolOp, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -63,7 +63,7 @@ impl AlwaysAutofixableViolation for RepeatedIsinstanceCalls {
|
||||||
pub(crate) fn repeated_isinstance_calls(
|
pub(crate) fn repeated_isinstance_calls(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
expr: &Expr,
|
expr: &Expr,
|
||||||
op: Boolop,
|
op: BoolOp,
|
||||||
values: &[Expr],
|
values: &[Expr],
|
||||||
) {
|
) {
|
||||||
if !op.is_or() {
|
if !op.is_or() {
|
||||||
|
|
|
@ -58,18 +58,18 @@ impl Violation for TooManyArguments {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PLR0913
|
/// PLR0913
|
||||||
pub(crate) fn too_many_arguments(checker: &mut Checker, args: &Arguments, stmt: &Stmt) {
|
pub(crate) fn too_many_arguments(checker: &mut Checker, arguments: &Arguments, stmt: &Stmt) {
|
||||||
let num_args = args
|
let num_arguments = arguments
|
||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.chain(args.kwonlyargs.iter())
|
.chain(&arguments.kwonlyargs)
|
||||||
.chain(args.posonlyargs.iter())
|
.chain(&arguments.posonlyargs)
|
||||||
.filter(|arg| !checker.settings.dummy_variable_rgx.is_match(&arg.arg))
|
.filter(|arg| !checker.settings.dummy_variable_rgx.is_match(&arg.def.arg))
|
||||||
.count();
|
.count();
|
||||||
if num_args > checker.settings.pylint.max_args {
|
if num_arguments > checker.settings.pylint.max_args {
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
TooManyArguments {
|
TooManyArguments {
|
||||||
c_args: num_args,
|
c_args: num_arguments,
|
||||||
max_args: checker.settings.pylint.max_args,
|
max_args: checker.settings.pylint.max_args,
|
||||||
},
|
},
|
||||||
stmt.identifier(checker.locator),
|
stmt.identifier(checker.locator),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -147,8 +147,8 @@ fn num_branches(stmts: &[Stmt]) -> usize {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|handler| {
|
.map(|handler| {
|
||||||
1 + {
|
1 + {
|
||||||
let Excepthandler::ExceptHandler(
|
let ExceptHandler::ExceptHandler(
|
||||||
ast::ExcepthandlerExceptHandler { body, .. },
|
ast::ExceptHandlerExceptHandler { body, .. },
|
||||||
) = handler;
|
) = handler;
|
||||||
num_branches(body)
|
num_branches(body)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -123,7 +123,7 @@ fn num_statements(stmts: &[Stmt]) -> usize {
|
||||||
}
|
}
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
count += 1;
|
count += 1;
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||||
body, ..
|
body, ..
|
||||||
}) = handler;
|
}) = handler;
|
||||||
count += num_statements(body);
|
count += num_statements(body);
|
||||||
|
|
|
@ -160,8 +160,7 @@ pub(crate) fn unexpected_special_method_signature(
|
||||||
}
|
}
|
||||||
|
|
||||||
let actual_params = args.args.len();
|
let actual_params = args.args.len();
|
||||||
let optional_params = args.defaults.len();
|
let mandatory_params = args.args.iter().filter(|arg| arg.default.is_none()).count();
|
||||||
let mandatory_params = actual_params - optional_params;
|
|
||||||
|
|
||||||
let Some(expected_params) = ExpectedParams::from_method(name, is_staticmethod(decorator_list, checker.semantic())) else {
|
let Some(expected_params) = ExpectedParams::from_method(name, is_staticmethod(decorator_list, checker.semantic())) else {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, MatchCase, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, MatchCase, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -79,7 +79,7 @@ fn loop_exits_early(body: &[Stmt]) -> bool {
|
||||||
|| loop_exits_early(orelse)
|
|| loop_exits_early(orelse)
|
||||||
|| loop_exits_early(finalbody)
|
|| loop_exits_early(finalbody)
|
||||||
|| handlers.iter().any(|handler| match handler {
|
|| handlers.iter().any(|handler| match handler {
|
||||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||||
body, ..
|
body, ..
|
||||||
}) => loop_exits_early(body),
|
}) => loop_exits_early(body),
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Expr, ExprContext, Ranged};
|
use rustpython_parser::ast::{self, ExceptHandler, Expr, ExprContext, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -151,9 +151,9 @@ fn tuple_diagnostic(checker: &mut Checker, target: &Expr, aliases: &[&Expr]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// UP024
|
/// UP024
|
||||||
pub(crate) fn os_error_alias_handlers(checker: &mut Checker, handlers: &[Excepthandler]) {
|
pub(crate) fn os_error_alias_handlers(checker: &mut Checker, handlers: &[ExceptHandler]) {
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = handler;
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, .. }) = handler;
|
||||||
let Some(expr) = type_.as_ref() else {
|
let Some(expr) = type_.as_ref() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::cmp::Ordering;
|
||||||
|
|
||||||
use num_bigint::{BigInt, Sign};
|
use num_bigint::{BigInt, Sign};
|
||||||
use ruff_text_size::{TextRange, TextSize};
|
use ruff_text_size::{TextRange, TextSize};
|
||||||
use rustpython_parser::ast::{self, Cmpop, Constant, Expr, Ranged, Stmt};
|
use rustpython_parser::ast::{self, CmpOp, Constant, Expr, Ranged, Stmt};
|
||||||
use rustpython_parser::{lexer, Mode, Tok};
|
use rustpython_parser::{lexer, Mode, Tok};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
|
@ -370,8 +370,8 @@ pub(crate) fn outdated_version_block(
|
||||||
Expr::Tuple(ast::ExprTuple { elts, .. }) => {
|
Expr::Tuple(ast::ExprTuple { elts, .. }) => {
|
||||||
let version = extract_version(elts);
|
let version = extract_version(elts);
|
||||||
let target = checker.settings.target_version;
|
let target = checker.settings.target_version;
|
||||||
if op == &Cmpop::Lt || op == &Cmpop::LtE {
|
if op == &CmpOp::Lt || op == &CmpOp::LtE {
|
||||||
if compare_version(&version, target, op == &Cmpop::LtE) {
|
if compare_version(&version, target, op == &CmpOp::LtE) {
|
||||||
let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range());
|
let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if let Some(block) = metadata(checker.locator, stmt, body) {
|
if let Some(block) = metadata(checker.locator, stmt, body) {
|
||||||
|
@ -382,8 +382,8 @@ pub(crate) fn outdated_version_block(
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
} else if op == &Cmpop::Gt || op == &Cmpop::GtE {
|
} else if op == &CmpOp::Gt || op == &CmpOp::GtE {
|
||||||
if compare_version(&version, target, op == &Cmpop::GtE) {
|
if compare_version(&version, target, op == &CmpOp::GtE) {
|
||||||
let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range());
|
let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if let Some(block) = metadata(checker.locator, stmt, body) {
|
if let Some(block) = metadata(checker.locator, stmt, body) {
|
||||||
|
@ -402,7 +402,7 @@ pub(crate) fn outdated_version_block(
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let version_number = bigint_to_u32(number);
|
let version_number = bigint_to_u32(number);
|
||||||
if version_number == 2 && op == &Cmpop::Eq {
|
if version_number == 2 && op == &CmpOp::Eq {
|
||||||
let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range());
|
let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if let Some(block) = metadata(checker.locator, stmt, body) {
|
if let Some(block) = metadata(checker.locator, stmt, body) {
|
||||||
|
@ -412,7 +412,7 @@ pub(crate) fn outdated_version_block(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
} else if version_number == 3 && op == &Cmpop::Eq {
|
} else if version_number == 3 && op == &CmpOp::Eq {
|
||||||
let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range());
|
let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if let Some(block) = metadata(checker.locator, stmt, body) {
|
if let Some(block) = metadata(checker.locator, stmt, body) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Arg, Expr, Ranged, Stmt};
|
use rustpython_parser::ast::{self, Arg, ArgWithDefault, Expr, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -104,8 +104,9 @@ pub(crate) fn super_call_with_parameters(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extract the name of the first argument to the enclosing function.
|
// Extract the name of the first argument to the enclosing function.
|
||||||
let Some(Arg {
|
let Some(ArgWithDefault {
|
||||||
arg: parent_arg, ..
|
def: Arg { arg: parent_arg, .. },
|
||||||
|
..
|
||||||
}) = parent_args.args.first() else {
|
}) = parent_args.args.first() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use rustpython_parser::ast::{self, Arguments, Constant, Expr, Operator, Ranged};
|
use ruff_text_size::TextRange;
|
||||||
|
use rustpython_parser::ast::{self, ArgWithDefault, Arguments, Constant, Expr, Operator, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::helpers::is_const_none;
|
use ruff_python_ast::helpers::is_const_none;
|
||||||
use ruff_python_semantic::SemanticModel;
|
use ruff_python_semantic::SemanticModel;
|
||||||
use ruff_text_size::TextRange;
|
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::importer::ImportRequest;
|
use crate::importer::ImportRequest;
|
||||||
|
@ -307,24 +307,23 @@ fn generate_fix(checker: &Checker, conversion_type: ConversionType, expr: &Expr)
|
||||||
|
|
||||||
/// RUF011
|
/// RUF011
|
||||||
pub(crate) fn implicit_optional(checker: &mut Checker, arguments: &Arguments) {
|
pub(crate) fn implicit_optional(checker: &mut Checker, arguments: &Arguments) {
|
||||||
let arguments_with_defaults = arguments
|
for ArgWithDefault {
|
||||||
.kwonlyargs
|
def,
|
||||||
|
default,
|
||||||
|
range: _,
|
||||||
|
} in arguments
|
||||||
|
.posonlyargs
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.chain(&arguments.args)
|
||||||
.zip(arguments.kw_defaults.iter().rev())
|
.chain(&arguments.kwonlyargs)
|
||||||
.chain(
|
{
|
||||||
arguments
|
let Some(default) = default else {
|
||||||
.args
|
continue
|
||||||
.iter()
|
};
|
||||||
.rev()
|
|
||||||
.chain(arguments.posonlyargs.iter().rev())
|
|
||||||
.zip(arguments.defaults.iter().rev()),
|
|
||||||
);
|
|
||||||
for (arg, default) in arguments_with_defaults {
|
|
||||||
if !is_const_none(default) {
|
if !is_const_none(default) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let Some(annotation) = &arg.annotation else {
|
let Some(annotation) = &def.annotation else {
|
||||||
continue
|
continue
|
||||||
};
|
};
|
||||||
let Some(expr) = type_hint_explicitly_allows_none(annotation, checker.semantic()) else {
|
let Some(expr) = type_hint_explicitly_allows_none(annotation, checker.semantic()) else {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use num_traits::ToPrimitive;
|
use num_traits::ToPrimitive;
|
||||||
use rustpython_parser::ast::{self, Constant, Expr, Ranged, Unaryop};
|
use rustpython_parser::ast::{self, Constant, Expr, Ranged, UnaryOp};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -69,7 +69,7 @@ fn to_bound(expr: &Expr) -> Option<i64> {
|
||||||
..
|
..
|
||||||
}) => value.to_i64(),
|
}) => value.to_i64(),
|
||||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: Unaryop::USub | Unaryop::Invert,
|
op: UnaryOp::USub | UnaryOp::Invert,
|
||||||
operand,
|
operand,
|
||||||
range: _,
|
range: _,
|
||||||
}) => {
|
}) => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Expr, Ranged};
|
use rustpython_parser::ast::{self, ExceptHandler, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -54,9 +54,9 @@ impl Violation for ErrorInsteadOfException {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TRY400
|
/// TRY400
|
||||||
pub(crate) fn error_instead_of_exception(checker: &mut Checker, handlers: &[Excepthandler]) {
|
pub(crate) fn error_instead_of_exception(checker: &mut Checker, handlers: &[ExceptHandler]) {
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = handler;
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { body, .. }) = handler;
|
||||||
let calls = {
|
let calls = {
|
||||||
let mut visitor = LoggerCandidateVisitor::new(checker.semantic());
|
let mut visitor = LoggerCandidateVisitor::new(checker.semantic());
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(body);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{Excepthandler, Ranged, Stmt};
|
use rustpython_parser::ast::{ExceptHandler, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -72,7 +72,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TRY301
|
/// TRY301
|
||||||
pub(crate) fn raise_within_try(checker: &mut Checker, body: &[Stmt], handlers: &[Excepthandler]) {
|
pub(crate) fn raise_within_try(checker: &mut Checker, body: &[Stmt], handlers: &[ExceptHandler]) {
|
||||||
if handlers.is_empty() {
|
if handlers.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Ranged, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -60,7 +60,7 @@ pub(crate) fn try_consider_else(
|
||||||
checker: &mut Checker,
|
checker: &mut Checker,
|
||||||
body: &[Stmt],
|
body: &[Stmt],
|
||||||
orelse: &[Stmt],
|
orelse: &[Stmt],
|
||||||
handler: &[Excepthandler],
|
handler: &[ExceptHandler],
|
||||||
) {
|
) {
|
||||||
if body.len() > 1 && orelse.is_empty() && !handler.is_empty() {
|
if body.len() > 1 && orelse.is_empty() && !handler.is_empty() {
|
||||||
if let Some(stmt) = body.last() {
|
if let Some(stmt) = body.last() {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use rustpython_parser::ast::Excepthandler::ExceptHandler;
|
use rustpython_parser::ast::{self, ExceptHandler, ExceptHandlerExceptHandler, Expr, Ranged, Stmt};
|
||||||
use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerExceptHandler, Expr, Ranged, Stmt};
|
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -39,11 +38,12 @@ impl Violation for UselessTryExcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TRY302
|
/// TRY302
|
||||||
pub(crate) fn useless_try_except(checker: &mut Checker, handlers: &[Excepthandler]) {
|
pub(crate) fn useless_try_except(checker: &mut Checker, handlers: &[ExceptHandler]) {
|
||||||
if let Some(diagnostics) = handlers
|
if let Some(diagnostics) = handlers
|
||||||
.iter()
|
.iter()
|
||||||
.map(|handler| {
|
.map(|handler| {
|
||||||
let ExceptHandler(ExcepthandlerExceptHandler { name, body, .. }) = handler;
|
let ExceptHandler::ExceptHandler(ExceptHandlerExceptHandler { name, body, .. }) =
|
||||||
|
handler;
|
||||||
let Some(Stmt::Raise(ast::StmtRaise { exc, cause: None, .. })) = &body.first() else {
|
let Some(Stmt::Raise(ast::StmtRaise { exc, cause: None, .. })) = &body.first() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Expr, Ranged};
|
use rustpython_parser::ast::{self, ExceptHandler, Expr, Ranged};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -57,9 +57,9 @@ impl<'a> Visitor<'a> for NameVisitor<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TRY401
|
/// TRY401
|
||||||
pub(crate) fn verbose_log_message(checker: &mut Checker, handlers: &[Excepthandler]) {
|
pub(crate) fn verbose_log_message(checker: &mut Checker, handlers: &[ExceptHandler]) {
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { name, body, .. }) =
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { name, body, .. }) =
|
||||||
handler;
|
handler;
|
||||||
let Some(target) = name else {
|
let Some(target) = name else {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Expr, Ranged, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, Expr, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
@ -74,10 +74,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TRY201
|
/// TRY201
|
||||||
pub(crate) fn verbose_raise(checker: &mut Checker, handlers: &[Excepthandler]) {
|
pub(crate) fn verbose_raise(checker: &mut Checker, handlers: &[ExceptHandler]) {
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
// If the handler assigned a name to the exception...
|
// If the handler assigned a name to the exception...
|
||||||
if let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
if let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||||
name: Some(exception_name),
|
name: Some(exception_name),
|
||||||
body,
|
body,
|
||||||
..
|
..
|
||||||
|
|
|
@ -22,16 +22,16 @@ impl From<&ast::ExprContext> for ComparableExprContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||||
pub enum ComparableBoolop {
|
pub enum ComparableBoolOp {
|
||||||
And,
|
And,
|
||||||
Or,
|
Or,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ast::Boolop> for ComparableBoolop {
|
impl From<ast::BoolOp> for ComparableBoolOp {
|
||||||
fn from(op: ast::Boolop) -> Self {
|
fn from(op: ast::BoolOp) -> Self {
|
||||||
match op {
|
match op {
|
||||||
ast::Boolop::And => Self::And,
|
ast::BoolOp::And => Self::And,
|
||||||
ast::Boolop::Or => Self::Or,
|
ast::BoolOp::Or => Self::Or,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,26 +74,26 @@ impl From<ast::Operator> for ComparableOperator {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||||
pub enum ComparableUnaryop {
|
pub enum ComparableUnaryOp {
|
||||||
Invert,
|
Invert,
|
||||||
Not,
|
Not,
|
||||||
UAdd,
|
UAdd,
|
||||||
USub,
|
USub,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ast::Unaryop> for ComparableUnaryop {
|
impl From<ast::UnaryOp> for ComparableUnaryOp {
|
||||||
fn from(op: ast::Unaryop) -> Self {
|
fn from(op: ast::UnaryOp) -> Self {
|
||||||
match op {
|
match op {
|
||||||
ast::Unaryop::Invert => Self::Invert,
|
ast::UnaryOp::Invert => Self::Invert,
|
||||||
ast::Unaryop::Not => Self::Not,
|
ast::UnaryOp::Not => Self::Not,
|
||||||
ast::Unaryop::UAdd => Self::UAdd,
|
ast::UnaryOp::UAdd => Self::UAdd,
|
||||||
ast::Unaryop::USub => Self::USub,
|
ast::UnaryOp::USub => Self::USub,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||||
pub enum ComparableCmpop {
|
pub enum ComparableCmpOp {
|
||||||
Eq,
|
Eq,
|
||||||
NotEq,
|
NotEq,
|
||||||
Lt,
|
Lt,
|
||||||
|
@ -106,19 +106,19 @@ pub enum ComparableCmpop {
|
||||||
NotIn,
|
NotIn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ast::Cmpop> for ComparableCmpop {
|
impl From<ast::CmpOp> for ComparableCmpOp {
|
||||||
fn from(op: ast::Cmpop) -> Self {
|
fn from(op: ast::CmpOp) -> Self {
|
||||||
match op {
|
match op {
|
||||||
ast::Cmpop::Eq => Self::Eq,
|
ast::CmpOp::Eq => Self::Eq,
|
||||||
ast::Cmpop::NotEq => Self::NotEq,
|
ast::CmpOp::NotEq => Self::NotEq,
|
||||||
ast::Cmpop::Lt => Self::Lt,
|
ast::CmpOp::Lt => Self::Lt,
|
||||||
ast::Cmpop::LtE => Self::LtE,
|
ast::CmpOp::LtE => Self::LtE,
|
||||||
ast::Cmpop::Gt => Self::Gt,
|
ast::CmpOp::Gt => Self::Gt,
|
||||||
ast::Cmpop::GtE => Self::GtE,
|
ast::CmpOp::GtE => Self::GtE,
|
||||||
ast::Cmpop::Is => Self::Is,
|
ast::CmpOp::Is => Self::Is,
|
||||||
ast::Cmpop::IsNot => Self::IsNot,
|
ast::CmpOp::IsNot => Self::IsNot,
|
||||||
ast::Cmpop::In => Self::In,
|
ast::CmpOp::In => Self::In,
|
||||||
ast::Cmpop::NotIn => Self::NotIn,
|
ast::CmpOp::NotIn => Self::NotIn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,16 +139,16 @@ impl<'a> From<&'a ast::Alias> for ComparableAlias<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct ComparableWithitem<'a> {
|
pub struct ComparableWithItem<'a> {
|
||||||
context_expr: ComparableExpr<'a>,
|
context_expr: ComparableExpr<'a>,
|
||||||
optional_vars: Option<ComparableExpr<'a>>,
|
optional_vars: Option<ComparableExpr<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a ast::Withitem> for ComparableWithitem<'a> {
|
impl<'a> From<&'a ast::WithItem> for ComparableWithItem<'a> {
|
||||||
fn from(withitem: &'a ast::Withitem) -> Self {
|
fn from(with_item: &'a ast::WithItem) -> Self {
|
||||||
Self {
|
Self {
|
||||||
context_expr: (&withitem.context_expr).into(),
|
context_expr: (&with_item.context_expr).into(),
|
||||||
optional_vars: withitem.optional_vars.as_ref().map(Into::into),
|
optional_vars: with_item.optional_vars.as_ref().map(Into::into),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,13 +342,11 @@ impl<'a> From<&'a ast::Constant> for ComparableConstant<'a> {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct ComparableArguments<'a> {
|
pub struct ComparableArguments<'a> {
|
||||||
posonlyargs: Vec<ComparableArg<'a>>,
|
posonlyargs: Vec<ComparableArgWithDefault<'a>>,
|
||||||
args: Vec<ComparableArg<'a>>,
|
args: Vec<ComparableArgWithDefault<'a>>,
|
||||||
vararg: Option<ComparableArg<'a>>,
|
vararg: Option<ComparableArg<'a>>,
|
||||||
kwonlyargs: Vec<ComparableArg<'a>>,
|
kwonlyargs: Vec<ComparableArgWithDefault<'a>>,
|
||||||
kw_defaults: Vec<ComparableExpr<'a>>,
|
|
||||||
kwarg: Option<ComparableArg<'a>>,
|
kwarg: Option<ComparableArg<'a>>,
|
||||||
defaults: Vec<ComparableExpr<'a>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a ast::Arguments> for ComparableArguments<'a> {
|
impl<'a> From<&'a ast::Arguments> for ComparableArguments<'a> {
|
||||||
|
@ -358,9 +356,7 @@ impl<'a> From<&'a ast::Arguments> for ComparableArguments<'a> {
|
||||||
args: arguments.args.iter().map(Into::into).collect(),
|
args: arguments.args.iter().map(Into::into).collect(),
|
||||||
vararg: arguments.vararg.as_ref().map(Into::into),
|
vararg: arguments.vararg.as_ref().map(Into::into),
|
||||||
kwonlyargs: arguments.kwonlyargs.iter().map(Into::into).collect(),
|
kwonlyargs: arguments.kwonlyargs.iter().map(Into::into).collect(),
|
||||||
kw_defaults: arguments.kw_defaults.iter().map(Into::into).collect(),
|
|
||||||
kwarg: arguments.kwarg.as_ref().map(Into::into),
|
kwarg: arguments.kwarg.as_ref().map(Into::into),
|
||||||
defaults: arguments.defaults.iter().map(Into::into).collect(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,6 +390,21 @@ impl<'a> From<&'a ast::Arg> for ComparableArg<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
|
pub struct ComparableArgWithDefault<'a> {
|
||||||
|
def: ComparableArg<'a>,
|
||||||
|
default: Option<ComparableExpr<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a ast::ArgWithDefault> for ComparableArgWithDefault<'a> {
|
||||||
|
fn from(arg: &'a ast::ArgWithDefault) -> Self {
|
||||||
|
Self {
|
||||||
|
def: (&arg.def).into(),
|
||||||
|
default: arg.default.as_ref().map(Into::into),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct ComparableKeyword<'a> {
|
pub struct ComparableKeyword<'a> {
|
||||||
arg: Option<&'a str>,
|
arg: Option<&'a str>,
|
||||||
|
@ -429,26 +440,26 @@ impl<'a> From<&'a ast::Comprehension> for ComparableComprehension<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct ExcepthandlerExceptHandler<'a> {
|
pub struct ExceptHandlerExceptHandler<'a> {
|
||||||
type_: Option<Box<ComparableExpr<'a>>>,
|
type_: Option<Box<ComparableExpr<'a>>>,
|
||||||
name: Option<&'a str>,
|
name: Option<&'a str>,
|
||||||
body: Vec<ComparableStmt<'a>>,
|
body: Vec<ComparableStmt<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum ComparableExcepthandler<'a> {
|
pub enum ComparableExceptHandler<'a> {
|
||||||
ExceptHandler(ExcepthandlerExceptHandler<'a>),
|
ExceptHandler(ExceptHandlerExceptHandler<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a ast::Excepthandler> for ComparableExcepthandler<'a> {
|
impl<'a> From<&'a ast::ExceptHandler> for ComparableExceptHandler<'a> {
|
||||||
fn from(excepthandler: &'a ast::Excepthandler) -> Self {
|
fn from(except_handler: &'a ast::ExceptHandler) -> Self {
|
||||||
let ast::Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
let ast::ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||||
type_,
|
type_,
|
||||||
name,
|
name,
|
||||||
body,
|
body,
|
||||||
..
|
..
|
||||||
}) = excepthandler;
|
}) = except_handler;
|
||||||
Self::ExceptHandler(ExcepthandlerExceptHandler {
|
Self::ExceptHandler(ExceptHandlerExceptHandler {
|
||||||
type_: type_.as_ref().map(Into::into),
|
type_: type_.as_ref().map(Into::into),
|
||||||
name: name.as_deref(),
|
name: name.as_deref(),
|
||||||
body: body.iter().map(Into::into).collect(),
|
body: body.iter().map(Into::into).collect(),
|
||||||
|
@ -458,7 +469,7 @@ impl<'a> From<&'a ast::Excepthandler> for ComparableExcepthandler<'a> {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct ExprBoolOp<'a> {
|
pub struct ExprBoolOp<'a> {
|
||||||
op: ComparableBoolop,
|
op: ComparableBoolOp,
|
||||||
values: Vec<ComparableExpr<'a>>,
|
values: Vec<ComparableExpr<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,7 +488,7 @@ pub struct ExprBinOp<'a> {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct ExprUnaryOp<'a> {
|
pub struct ExprUnaryOp<'a> {
|
||||||
op: ComparableUnaryop,
|
op: ComparableUnaryOp,
|
||||||
operand: Box<ComparableExpr<'a>>,
|
operand: Box<ComparableExpr<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,7 +559,7 @@ pub struct ExprYieldFrom<'a> {
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct ExprCompare<'a> {
|
pub struct ExprCompare<'a> {
|
||||||
left: Box<ComparableExpr<'a>>,
|
left: Box<ComparableExpr<'a>>,
|
||||||
ops: Vec<ComparableCmpop>,
|
ops: Vec<ComparableCmpOp>,
|
||||||
comparators: Vec<ComparableExpr<'a>>,
|
comparators: Vec<ComparableExpr<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -994,14 +1005,14 @@ pub struct StmtIf<'a> {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct StmtWith<'a> {
|
pub struct StmtWith<'a> {
|
||||||
items: Vec<ComparableWithitem<'a>>,
|
items: Vec<ComparableWithItem<'a>>,
|
||||||
body: Vec<ComparableStmt<'a>>,
|
body: Vec<ComparableStmt<'a>>,
|
||||||
type_comment: Option<&'a str>,
|
type_comment: Option<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct StmtAsyncWith<'a> {
|
pub struct StmtAsyncWith<'a> {
|
||||||
items: Vec<ComparableWithitem<'a>>,
|
items: Vec<ComparableWithItem<'a>>,
|
||||||
body: Vec<ComparableStmt<'a>>,
|
body: Vec<ComparableStmt<'a>>,
|
||||||
type_comment: Option<&'a str>,
|
type_comment: Option<&'a str>,
|
||||||
}
|
}
|
||||||
|
@ -1021,7 +1032,7 @@ pub struct StmtRaise<'a> {
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct StmtTry<'a> {
|
pub struct StmtTry<'a> {
|
||||||
body: Vec<ComparableStmt<'a>>,
|
body: Vec<ComparableStmt<'a>>,
|
||||||
handlers: Vec<ComparableExcepthandler<'a>>,
|
handlers: Vec<ComparableExceptHandler<'a>>,
|
||||||
orelse: Vec<ComparableStmt<'a>>,
|
orelse: Vec<ComparableStmt<'a>>,
|
||||||
finalbody: Vec<ComparableStmt<'a>>,
|
finalbody: Vec<ComparableStmt<'a>>,
|
||||||
}
|
}
|
||||||
|
@ -1029,7 +1040,7 @@ pub struct StmtTry<'a> {
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct StmtTryStar<'a> {
|
pub struct StmtTryStar<'a> {
|
||||||
body: Vec<ComparableStmt<'a>>,
|
body: Vec<ComparableStmt<'a>>,
|
||||||
handlers: Vec<ComparableExcepthandler<'a>>,
|
handlers: Vec<ComparableExceptHandler<'a>>,
|
||||||
orelse: Vec<ComparableStmt<'a>>,
|
orelse: Vec<ComparableStmt<'a>>,
|
||||||
finalbody: Vec<ComparableStmt<'a>>,
|
finalbody: Vec<ComparableStmt<'a>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ use std::path::Path;
|
||||||
use num_traits::Zero;
|
use num_traits::Zero;
|
||||||
use ruff_text_size::{TextRange, TextSize};
|
use ruff_text_size::{TextRange, TextSize};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use rustpython_ast::Cmpop;
|
use rustpython_ast::CmpOp;
|
||||||
use rustpython_parser::ast::{
|
use rustpython_parser::ast::{
|
||||||
self, Arguments, Constant, Excepthandler, Expr, Keyword, MatchCase, Pattern, Ranged, Stmt,
|
self, Arguments, Constant, ExceptHandler, Expr, Keyword, MatchCase, Pattern, Ranged, Stmt,
|
||||||
};
|
};
|
||||||
use rustpython_parser::{lexer, Mode, Tok};
|
use rustpython_parser::{lexer, Mode, Tok};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -333,25 +333,19 @@ where
|
||||||
returns,
|
returns,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
args.defaults.iter().any(|expr| any_over_expr(expr, func))
|
args.posonlyargs
|
||||||
|| args
|
.iter()
|
||||||
.kw_defaults
|
.chain(args.args.iter().chain(args.kwonlyargs.iter()))
|
||||||
.iter()
|
.any(|arg_with_default| {
|
||||||
.any(|expr| any_over_expr(expr, func))
|
arg_with_default
|
||||||
|| args.args.iter().any(|arg| {
|
.default
|
||||||
arg.annotation
|
|
||||||
.as_ref()
|
|
||||||
.map_or(false, |expr| any_over_expr(expr, func))
|
|
||||||
})
|
|
||||||
|| args.kwonlyargs.iter().any(|arg| {
|
|
||||||
arg.annotation
|
|
||||||
.as_ref()
|
|
||||||
.map_or(false, |expr| any_over_expr(expr, func))
|
|
||||||
})
|
|
||||||
|| args.posonlyargs.iter().any(|arg| {
|
|
||||||
arg.annotation
|
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(false, |expr| any_over_expr(expr, func))
|
.map_or(false, |expr| any_over_expr(expr, func))
|
||||||
|
|| arg_with_default
|
||||||
|
.def
|
||||||
|
.annotation
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |expr| any_over_expr(expr, func))
|
||||||
})
|
})
|
||||||
|| args.vararg.as_ref().map_or(false, |arg| {
|
|| args.vararg.as_ref().map_or(false, |arg| {
|
||||||
arg.annotation
|
arg.annotation
|
||||||
|
@ -448,9 +442,9 @@ where
|
||||||
}) => any_over_expr(test, func) || any_over_body(body, func) || any_over_body(orelse, func),
|
}) => any_over_expr(test, func) || any_over_body(body, func) || any_over_body(orelse, func),
|
||||||
Stmt::With(ast::StmtWith { items, body, .. })
|
Stmt::With(ast::StmtWith { items, body, .. })
|
||||||
| Stmt::AsyncWith(ast::StmtAsyncWith { items, body, .. }) => {
|
| Stmt::AsyncWith(ast::StmtAsyncWith { items, body, .. }) => {
|
||||||
items.iter().any(|withitem| {
|
items.iter().any(|with_item| {
|
||||||
any_over_expr(&withitem.context_expr, func)
|
any_over_expr(&with_item.context_expr, func)
|
||||||
|| withitem
|
|| with_item
|
||||||
.optional_vars
|
.optional_vars
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(false, |expr| any_over_expr(expr, func))
|
.map_or(false, |expr| any_over_expr(expr, func))
|
||||||
|
@ -483,7 +477,7 @@ where
|
||||||
}) => {
|
}) => {
|
||||||
any_over_body(body, func)
|
any_over_body(body, func)
|
||||||
|| handlers.iter().any(|handler| {
|
|| handlers.iter().any(|handler| {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||||
type_,
|
type_,
|
||||||
body,
|
body,
|
||||||
..
|
..
|
||||||
|
@ -655,11 +649,11 @@ pub fn has_non_none_keyword(keywords: &[Keyword], keyword: &str) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the names of all handled exceptions.
|
/// Extract the names of all handled exceptions.
|
||||||
pub fn extract_handled_exceptions(handlers: &[Excepthandler]) -> Vec<&Expr> {
|
pub fn extract_handled_exceptions(handlers: &[ExceptHandler]) -> Vec<&Expr> {
|
||||||
let mut handled_exceptions = Vec::new();
|
let mut handled_exceptions = Vec::new();
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
match handler {
|
match handler {
|
||||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) => {
|
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, .. }) => {
|
||||||
if let Some(type_) = type_ {
|
if let Some(type_) = type_ {
|
||||||
if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &type_.as_ref() {
|
if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &type_.as_ref() {
|
||||||
for type_ in elts {
|
for type_ in elts {
|
||||||
|
@ -678,17 +672,17 @@ pub fn extract_handled_exceptions(handlers: &[Excepthandler]) -> Vec<&Expr> {
|
||||||
/// Return the set of all bound argument names.
|
/// Return the set of all bound argument names.
|
||||||
pub fn collect_arg_names<'a>(arguments: &'a Arguments) -> FxHashSet<&'a str> {
|
pub fn collect_arg_names<'a>(arguments: &'a Arguments) -> FxHashSet<&'a str> {
|
||||||
let mut arg_names: FxHashSet<&'a str> = FxHashSet::default();
|
let mut arg_names: FxHashSet<&'a str> = FxHashSet::default();
|
||||||
for arg in &arguments.posonlyargs {
|
for arg_with_default in &arguments.posonlyargs {
|
||||||
arg_names.insert(arg.arg.as_str());
|
arg_names.insert(arg_with_default.def.arg.as_str());
|
||||||
}
|
}
|
||||||
for arg in &arguments.args {
|
for arg_with_default in &arguments.args {
|
||||||
arg_names.insert(arg.arg.as_str());
|
arg_names.insert(arg_with_default.def.arg.as_str());
|
||||||
}
|
}
|
||||||
if let Some(arg) = &arguments.vararg {
|
if let Some(arg) = &arguments.vararg {
|
||||||
arg_names.insert(arg.arg.as_str());
|
arg_names.insert(arg.arg.as_str());
|
||||||
}
|
}
|
||||||
for arg in &arguments.kwonlyargs {
|
for arg_with_default in &arguments.kwonlyargs {
|
||||||
arg_names.insert(arg.arg.as_str());
|
arg_names.insert(arg_with_default.def.arg.as_str());
|
||||||
}
|
}
|
||||||
if let Some(arg) = &arguments.kwarg {
|
if let Some(arg) = &arguments.kwarg {
|
||||||
arg_names.insert(arg.arg.as_str());
|
arg_names.insert(arg.arg.as_str());
|
||||||
|
@ -1409,13 +1403,13 @@ impl Truthiness {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct LocatedCmpop {
|
pub struct LocatedCmpOp {
|
||||||
pub range: TextRange,
|
pub range: TextRange,
|
||||||
pub op: Cmpop,
|
pub op: CmpOp,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocatedCmpop {
|
impl LocatedCmpOp {
|
||||||
fn new<T: Into<TextRange>>(range: T, op: Cmpop) -> Self {
|
fn new<T: Into<TextRange>>(range: T, op: CmpOp) -> Self {
|
||||||
Self {
|
Self {
|
||||||
range: range.into(),
|
range: range.into(),
|
||||||
op,
|
op,
|
||||||
|
@ -1423,13 +1417,13 @@ impl LocatedCmpop {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract all [`Cmpop`] operators from an expression snippet, with appropriate
|
/// Extract all [`CmpOp`] operators from an expression snippet, with appropriate
|
||||||
/// ranges.
|
/// ranges.
|
||||||
///
|
///
|
||||||
/// `RustPython` doesn't include line and column information on [`Cmpop`] nodes.
|
/// `RustPython` doesn't include line and column information on [`CmpOp`] nodes.
|
||||||
/// `CPython` doesn't either. This method iterates over the token stream and
|
/// `CPython` doesn't either. This method iterates over the token stream and
|
||||||
/// re-identifies [`Cmpop`] nodes, annotating them with valid ranges.
|
/// re-identifies [`CmpOp`] nodes, annotating them with valid ranges.
|
||||||
pub fn locate_cmpops(expr: &Expr, locator: &Locator) -> Vec<LocatedCmpop> {
|
pub fn locate_cmp_ops(expr: &Expr, locator: &Locator) -> Vec<LocatedCmpOp> {
|
||||||
// If `Expr` is a multi-line expression, we need to parenthesize it to
|
// If `Expr` is a multi-line expression, we need to parenthesize it to
|
||||||
// ensure that it's lexed correctly.
|
// ensure that it's lexed correctly.
|
||||||
let contents = locator.slice(expr.range());
|
let contents = locator.slice(expr.range());
|
||||||
|
@ -1441,7 +1435,7 @@ pub fn locate_cmpops(expr: &Expr, locator: &Locator) -> Vec<LocatedCmpop> {
|
||||||
.filter(|(tok, _)| !matches!(tok, Tok::NonLogicalNewline | Tok::Comment(_)))
|
.filter(|(tok, _)| !matches!(tok, Tok::NonLogicalNewline | Tok::Comment(_)))
|
||||||
.peekable();
|
.peekable();
|
||||||
|
|
||||||
let mut ops: Vec<LocatedCmpop> = vec![];
|
let mut ops: Vec<LocatedCmpOp> = vec![];
|
||||||
let mut count = 0u32;
|
let mut count = 0u32;
|
||||||
loop {
|
loop {
|
||||||
let Some((tok, range)) = tok_iter.next() else {
|
let Some((tok, range)) = tok_iter.next() else {
|
||||||
|
@ -1460,45 +1454,45 @@ pub fn locate_cmpops(expr: &Expr, locator: &Locator) -> Vec<LocatedCmpop> {
|
||||||
if let Some((_, next_range)) =
|
if let Some((_, next_range)) =
|
||||||
tok_iter.next_if(|(tok, _)| matches!(tok, Tok::In))
|
tok_iter.next_if(|(tok, _)| matches!(tok, Tok::In))
|
||||||
{
|
{
|
||||||
ops.push(LocatedCmpop::new(
|
ops.push(LocatedCmpOp::new(
|
||||||
TextRange::new(range.start(), next_range.end()),
|
TextRange::new(range.start(), next_range.end()),
|
||||||
Cmpop::NotIn,
|
CmpOp::NotIn,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Tok::In => {
|
Tok::In => {
|
||||||
ops.push(LocatedCmpop::new(range, Cmpop::In));
|
ops.push(LocatedCmpOp::new(range, CmpOp::In));
|
||||||
}
|
}
|
||||||
Tok::Is => {
|
Tok::Is => {
|
||||||
let op = if let Some((_, next_range)) =
|
let op = if let Some((_, next_range)) =
|
||||||
tok_iter.next_if(|(tok, _)| matches!(tok, Tok::Not))
|
tok_iter.next_if(|(tok, _)| matches!(tok, Tok::Not))
|
||||||
{
|
{
|
||||||
LocatedCmpop::new(
|
LocatedCmpOp::new(
|
||||||
TextRange::new(range.start(), next_range.end()),
|
TextRange::new(range.start(), next_range.end()),
|
||||||
Cmpop::IsNot,
|
CmpOp::IsNot,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
LocatedCmpop::new(range, Cmpop::Is)
|
LocatedCmpOp::new(range, CmpOp::Is)
|
||||||
};
|
};
|
||||||
ops.push(op);
|
ops.push(op);
|
||||||
}
|
}
|
||||||
Tok::NotEqual => {
|
Tok::NotEqual => {
|
||||||
ops.push(LocatedCmpop::new(range, Cmpop::NotEq));
|
ops.push(LocatedCmpOp::new(range, CmpOp::NotEq));
|
||||||
}
|
}
|
||||||
Tok::EqEqual => {
|
Tok::EqEqual => {
|
||||||
ops.push(LocatedCmpop::new(range, Cmpop::Eq));
|
ops.push(LocatedCmpOp::new(range, CmpOp::Eq));
|
||||||
}
|
}
|
||||||
Tok::GreaterEqual => {
|
Tok::GreaterEqual => {
|
||||||
ops.push(LocatedCmpop::new(range, Cmpop::GtE));
|
ops.push(LocatedCmpOp::new(range, CmpOp::GtE));
|
||||||
}
|
}
|
||||||
Tok::Greater => {
|
Tok::Greater => {
|
||||||
ops.push(LocatedCmpop::new(range, Cmpop::Gt));
|
ops.push(LocatedCmpOp::new(range, CmpOp::Gt));
|
||||||
}
|
}
|
||||||
Tok::LessEqual => {
|
Tok::LessEqual => {
|
||||||
ops.push(LocatedCmpop::new(range, Cmpop::LtE));
|
ops.push(LocatedCmpOp::new(range, CmpOp::LtE));
|
||||||
}
|
}
|
||||||
Tok::Less => {
|
Tok::Less => {
|
||||||
ops.push(LocatedCmpop::new(range, Cmpop::Lt));
|
ops.push(LocatedCmpOp::new(range, CmpOp::Lt));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -1513,13 +1507,13 @@ mod tests {
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||||
use rustpython_ast::{Cmpop, Expr, Stmt};
|
use rustpython_ast::{CmpOp, Expr, Stmt};
|
||||||
use rustpython_parser::ast::Suite;
|
use rustpython_parser::ast::Suite;
|
||||||
use rustpython_parser::Parse;
|
use rustpython_parser::Parse;
|
||||||
|
|
||||||
use crate::helpers::{
|
use crate::helpers::{
|
||||||
elif_else_range, first_colon_range, has_trailing_content, locate_cmpops,
|
elif_else_range, first_colon_range, has_trailing_content, locate_cmp_ops,
|
||||||
resolve_imported_module_path, LocatedCmpop,
|
resolve_imported_module_path, LocatedCmpOp,
|
||||||
};
|
};
|
||||||
use crate::source_code::Locator;
|
use crate::source_code::Locator;
|
||||||
|
|
||||||
|
@ -1642,15 +1636,15 @@ else:
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extract_cmpop_location() -> Result<()> {
|
fn extract_cmp_op_location() -> Result<()> {
|
||||||
let contents = "x == 1";
|
let contents = "x == 1";
|
||||||
let expr = Expr::parse(contents, "<filename>")?;
|
let expr = Expr::parse(contents, "<filename>")?;
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
locate_cmpops(&expr, &locator),
|
locate_cmp_ops(&expr, &locator),
|
||||||
vec![LocatedCmpop::new(
|
vec![LocatedCmpOp::new(
|
||||||
TextSize::from(2)..TextSize::from(4),
|
TextSize::from(2)..TextSize::from(4),
|
||||||
Cmpop::Eq
|
CmpOp::Eq
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1658,10 +1652,10 @@ else:
|
||||||
let expr = Expr::parse(contents, "<filename>")?;
|
let expr = Expr::parse(contents, "<filename>")?;
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
locate_cmpops(&expr, &locator),
|
locate_cmp_ops(&expr, &locator),
|
||||||
vec![LocatedCmpop::new(
|
vec![LocatedCmpOp::new(
|
||||||
TextSize::from(2)..TextSize::from(4),
|
TextSize::from(2)..TextSize::from(4),
|
||||||
Cmpop::NotEq
|
CmpOp::NotEq
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1669,10 +1663,10 @@ else:
|
||||||
let expr = Expr::parse(contents, "<filename>")?;
|
let expr = Expr::parse(contents, "<filename>")?;
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
locate_cmpops(&expr, &locator),
|
locate_cmp_ops(&expr, &locator),
|
||||||
vec![LocatedCmpop::new(
|
vec![LocatedCmpOp::new(
|
||||||
TextSize::from(2)..TextSize::from(4),
|
TextSize::from(2)..TextSize::from(4),
|
||||||
Cmpop::Is
|
CmpOp::Is
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1680,10 +1674,10 @@ else:
|
||||||
let expr = Expr::parse(contents, "<filename>")?;
|
let expr = Expr::parse(contents, "<filename>")?;
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
locate_cmpops(&expr, &locator),
|
locate_cmp_ops(&expr, &locator),
|
||||||
vec![LocatedCmpop::new(
|
vec![LocatedCmpOp::new(
|
||||||
TextSize::from(2)..TextSize::from(8),
|
TextSize::from(2)..TextSize::from(8),
|
||||||
Cmpop::IsNot
|
CmpOp::IsNot
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1691,10 +1685,10 @@ else:
|
||||||
let expr = Expr::parse(contents, "<filename>")?;
|
let expr = Expr::parse(contents, "<filename>")?;
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
locate_cmpops(&expr, &locator),
|
locate_cmp_ops(&expr, &locator),
|
||||||
vec![LocatedCmpop::new(
|
vec![LocatedCmpOp::new(
|
||||||
TextSize::from(2)..TextSize::from(4),
|
TextSize::from(2)..TextSize::from(4),
|
||||||
Cmpop::In
|
CmpOp::In
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1702,10 +1696,10 @@ else:
|
||||||
let expr = Expr::parse(contents, "<filename>")?;
|
let expr = Expr::parse(contents, "<filename>")?;
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
locate_cmpops(&expr, &locator),
|
locate_cmp_ops(&expr, &locator),
|
||||||
vec![LocatedCmpop::new(
|
vec![LocatedCmpOp::new(
|
||||||
TextSize::from(2)..TextSize::from(8),
|
TextSize::from(2)..TextSize::from(8),
|
||||||
Cmpop::NotIn
|
CmpOp::NotIn
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1713,10 +1707,10 @@ else:
|
||||||
let expr = Expr::parse(contents, "<filename>")?;
|
let expr = Expr::parse(contents, "<filename>")?;
|
||||||
let locator = Locator::new(contents);
|
let locator = Locator::new(contents);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
locate_cmpops(&expr, &locator),
|
locate_cmp_ops(&expr, &locator),
|
||||||
vec![LocatedCmpop::new(
|
vec![LocatedCmpOp::new(
|
||||||
TextSize::from(2)..TextSize::from(4),
|
TextSize::from(2)..TextSize::from(4),
|
||||||
Cmpop::NotEq
|
CmpOp::NotEq
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ use std::ops::{Add, Sub};
|
||||||
use std::str::Chars;
|
use std::str::Chars;
|
||||||
|
|
||||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||||
use rustpython_ast::{Alias, Arg, Pattern};
|
use rustpython_ast::{Alias, Arg, ArgWithDefault, Pattern};
|
||||||
use rustpython_parser::ast::{self, Excepthandler, Ranged, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, Ranged, Stmt};
|
||||||
|
|
||||||
use ruff_python_whitespace::is_python_whitespace;
|
use ruff_python_whitespace::is_python_whitespace;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ impl Identifier for Arg {
|
||||||
///
|
///
|
||||||
/// For example, return the range of `x` in:
|
/// For example, return the range of `x` in:
|
||||||
/// ```python
|
/// ```python
|
||||||
/// def f(x: int = 0):
|
/// def f(x: int):
|
||||||
/// ...
|
/// ...
|
||||||
/// ```
|
/// ```
|
||||||
fn identifier(&self, locator: &Locator) -> TextRange {
|
fn identifier(&self, locator: &Locator) -> TextRange {
|
||||||
|
@ -104,6 +104,19 @@ impl Identifier for Arg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Identifier for ArgWithDefault {
|
||||||
|
/// Return the [`TextRange`] for the identifier defining an [`ArgWithDefault`].
|
||||||
|
///
|
||||||
|
/// For example, return the range of `x` in:
|
||||||
|
/// ```python
|
||||||
|
/// def f(x: int = 0):
|
||||||
|
/// ...
|
||||||
|
/// ```
|
||||||
|
fn identifier(&self, locator: &Locator) -> TextRange {
|
||||||
|
self.def.identifier(locator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Identifier for Alias {
|
impl Identifier for Alias {
|
||||||
/// Return the [`TextRange`] for the identifier defining an [`Alias`].
|
/// Return the [`TextRange`] for the identifier defining an [`Alias`].
|
||||||
///
|
///
|
||||||
|
@ -239,8 +252,8 @@ impl TryIdentifier for Pattern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryIdentifier for Excepthandler {
|
impl TryIdentifier for ExceptHandler {
|
||||||
/// Return the [`TextRange`] of a named exception in an [`Excepthandler`].
|
/// Return the [`TextRange`] of a named exception in an [`ExceptHandler`].
|
||||||
///
|
///
|
||||||
/// For example, return the range of `e` in:
|
/// For example, return the range of `e` in:
|
||||||
/// ```python
|
/// ```python
|
||||||
|
@ -250,7 +263,7 @@ impl TryIdentifier for Excepthandler {
|
||||||
/// ...
|
/// ...
|
||||||
/// ```
|
/// ```
|
||||||
fn try_identifier(&self, locator: &Locator) -> Option<TextRange> {
|
fn try_identifier(&self, locator: &Locator) -> Option<TextRange> {
|
||||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, name, .. }) =
|
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, name, .. }) =
|
||||||
self;
|
self;
|
||||||
|
|
||||||
if name.is_none() {
|
if name.is_none() {
|
||||||
|
@ -284,11 +297,11 @@ pub fn names<'a>(stmt: &Stmt, locator: &'a Locator<'a>) -> impl Iterator<Item =
|
||||||
IdentifierTokenizer::new(locator.contents(), stmt.range()).skip(1)
|
IdentifierTokenizer::new(locator.contents(), stmt.range()).skip(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the [`TextRange`] of the `except` token in an [`Excepthandler`].
|
/// Return the [`TextRange`] of the `except` token in an [`ExceptHandler`].
|
||||||
pub fn except(handler: &Excepthandler, locator: &Locator) -> TextRange {
|
pub fn except(handler: &ExceptHandler, locator: &Locator) -> TextRange {
|
||||||
IdentifierTokenizer::new(locator.contents(), handler.range())
|
IdentifierTokenizer::new(locator.contents(), handler.range())
|
||||||
.next()
|
.next()
|
||||||
.expect("Failed to find `except` token in `Excepthandler`")
|
.expect("Failed to find `except` token in `ExceptHandler`")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the [`TextRange`] of the `else` token in a `For`, `AsyncFor`, or `While` statement.
|
/// Return the [`TextRange`] of the `else` token in a `For`, `AsyncFor`, or `While` statement.
|
||||||
|
|
|
@ -75,7 +75,7 @@ pub enum AnyNode {
|
||||||
ExprList(ExprList<TextRange>),
|
ExprList(ExprList<TextRange>),
|
||||||
ExprTuple(ExprTuple<TextRange>),
|
ExprTuple(ExprTuple<TextRange>),
|
||||||
ExprSlice(ExprSlice<TextRange>),
|
ExprSlice(ExprSlice<TextRange>),
|
||||||
ExcepthandlerExceptHandler(ExcepthandlerExceptHandler<TextRange>),
|
ExceptHandlerExceptHandler(ExceptHandlerExceptHandler<TextRange>),
|
||||||
PatternMatchValue(PatternMatchValue<TextRange>),
|
PatternMatchValue(PatternMatchValue<TextRange>),
|
||||||
PatternMatchSingleton(PatternMatchSingleton<TextRange>),
|
PatternMatchSingleton(PatternMatchSingleton<TextRange>),
|
||||||
PatternMatchSequence(PatternMatchSequence<TextRange>),
|
PatternMatchSequence(PatternMatchSequence<TextRange>),
|
||||||
|
@ -88,9 +88,10 @@ pub enum AnyNode {
|
||||||
Comprehension(Comprehension<TextRange>),
|
Comprehension(Comprehension<TextRange>),
|
||||||
Arguments(Arguments<TextRange>),
|
Arguments(Arguments<TextRange>),
|
||||||
Arg(Arg<TextRange>),
|
Arg(Arg<TextRange>),
|
||||||
|
ArgWithDefault(ArgWithDefault<TextRange>),
|
||||||
Keyword(Keyword<TextRange>),
|
Keyword(Keyword<TextRange>),
|
||||||
Alias(Alias<TextRange>),
|
Alias(Alias<TextRange>),
|
||||||
Withitem(Withitem<TextRange>),
|
WithItem(WithItem<TextRange>),
|
||||||
MatchCase(MatchCase<TextRange>),
|
MatchCase(MatchCase<TextRange>),
|
||||||
Decorator(Decorator<TextRange>),
|
Decorator(Decorator<TextRange>),
|
||||||
}
|
}
|
||||||
|
@ -157,7 +158,7 @@ impl AnyNode {
|
||||||
| AnyNode::ExprList(_)
|
| AnyNode::ExprList(_)
|
||||||
| AnyNode::ExprTuple(_)
|
| AnyNode::ExprTuple(_)
|
||||||
| AnyNode::ExprSlice(_)
|
| AnyNode::ExprSlice(_)
|
||||||
| AnyNode::ExcepthandlerExceptHandler(_)
|
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||||
| AnyNode::PatternMatchValue(_)
|
| AnyNode::PatternMatchValue(_)
|
||||||
| AnyNode::PatternMatchSingleton(_)
|
| AnyNode::PatternMatchSingleton(_)
|
||||||
| AnyNode::PatternMatchSequence(_)
|
| AnyNode::PatternMatchSequence(_)
|
||||||
|
@ -170,9 +171,10 @@ impl AnyNode {
|
||||||
| AnyNode::Comprehension(_)
|
| AnyNode::Comprehension(_)
|
||||||
| AnyNode::Arguments(_)
|
| AnyNode::Arguments(_)
|
||||||
| AnyNode::Arg(_)
|
| AnyNode::Arg(_)
|
||||||
|
| AnyNode::ArgWithDefault(_)
|
||||||
| AnyNode::Keyword(_)
|
| AnyNode::Keyword(_)
|
||||||
| AnyNode::Alias(_)
|
| AnyNode::Alias(_)
|
||||||
| AnyNode::Withitem(_)
|
| AnyNode::WithItem(_)
|
||||||
| AnyNode::MatchCase(_)
|
| AnyNode::MatchCase(_)
|
||||||
| AnyNode::Decorator(_) => None,
|
| AnyNode::Decorator(_) => None,
|
||||||
}
|
}
|
||||||
|
@ -239,7 +241,7 @@ impl AnyNode {
|
||||||
| AnyNode::StmtPass(_)
|
| AnyNode::StmtPass(_)
|
||||||
| AnyNode::StmtBreak(_)
|
| AnyNode::StmtBreak(_)
|
||||||
| AnyNode::StmtContinue(_)
|
| AnyNode::StmtContinue(_)
|
||||||
| AnyNode::ExcepthandlerExceptHandler(_)
|
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||||
| AnyNode::PatternMatchValue(_)
|
| AnyNode::PatternMatchValue(_)
|
||||||
| AnyNode::PatternMatchSingleton(_)
|
| AnyNode::PatternMatchSingleton(_)
|
||||||
| AnyNode::PatternMatchSequence(_)
|
| AnyNode::PatternMatchSequence(_)
|
||||||
|
@ -252,9 +254,10 @@ impl AnyNode {
|
||||||
| AnyNode::Comprehension(_)
|
| AnyNode::Comprehension(_)
|
||||||
| AnyNode::Arguments(_)
|
| AnyNode::Arguments(_)
|
||||||
| AnyNode::Arg(_)
|
| AnyNode::Arg(_)
|
||||||
|
| AnyNode::ArgWithDefault(_)
|
||||||
| AnyNode::Keyword(_)
|
| AnyNode::Keyword(_)
|
||||||
| AnyNode::Alias(_)
|
| AnyNode::Alias(_)
|
||||||
| AnyNode::Withitem(_)
|
| AnyNode::WithItem(_)
|
||||||
| AnyNode::MatchCase(_)
|
| AnyNode::MatchCase(_)
|
||||||
| AnyNode::Decorator(_) => None,
|
| AnyNode::Decorator(_) => None,
|
||||||
}
|
}
|
||||||
|
@ -321,7 +324,7 @@ impl AnyNode {
|
||||||
| AnyNode::ExprList(_)
|
| AnyNode::ExprList(_)
|
||||||
| AnyNode::ExprTuple(_)
|
| AnyNode::ExprTuple(_)
|
||||||
| AnyNode::ExprSlice(_)
|
| AnyNode::ExprSlice(_)
|
||||||
| AnyNode::ExcepthandlerExceptHandler(_)
|
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||||
| AnyNode::PatternMatchValue(_)
|
| AnyNode::PatternMatchValue(_)
|
||||||
| AnyNode::PatternMatchSingleton(_)
|
| AnyNode::PatternMatchSingleton(_)
|
||||||
| AnyNode::PatternMatchSequence(_)
|
| AnyNode::PatternMatchSequence(_)
|
||||||
|
@ -334,9 +337,10 @@ impl AnyNode {
|
||||||
| AnyNode::Comprehension(_)
|
| AnyNode::Comprehension(_)
|
||||||
| AnyNode::Arguments(_)
|
| AnyNode::Arguments(_)
|
||||||
| AnyNode::Arg(_)
|
| AnyNode::Arg(_)
|
||||||
|
| AnyNode::ArgWithDefault(_)
|
||||||
| AnyNode::Keyword(_)
|
| AnyNode::Keyword(_)
|
||||||
| AnyNode::Alias(_)
|
| AnyNode::Alias(_)
|
||||||
| AnyNode::Withitem(_)
|
| AnyNode::WithItem(_)
|
||||||
| AnyNode::MatchCase(_)
|
| AnyNode::MatchCase(_)
|
||||||
| AnyNode::Decorator(_) => None,
|
| AnyNode::Decorator(_) => None,
|
||||||
}
|
}
|
||||||
|
@ -411,22 +415,23 @@ impl AnyNode {
|
||||||
| AnyNode::ExprList(_)
|
| AnyNode::ExprList(_)
|
||||||
| AnyNode::ExprTuple(_)
|
| AnyNode::ExprTuple(_)
|
||||||
| AnyNode::ExprSlice(_)
|
| AnyNode::ExprSlice(_)
|
||||||
| AnyNode::ExcepthandlerExceptHandler(_)
|
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||||
| AnyNode::TypeIgnoreTypeIgnore(_)
|
| AnyNode::TypeIgnoreTypeIgnore(_)
|
||||||
| AnyNode::Comprehension(_)
|
| AnyNode::Comprehension(_)
|
||||||
| AnyNode::Arguments(_)
|
| AnyNode::Arguments(_)
|
||||||
| AnyNode::Arg(_)
|
| AnyNode::Arg(_)
|
||||||
|
| AnyNode::ArgWithDefault(_)
|
||||||
| AnyNode::Keyword(_)
|
| AnyNode::Keyword(_)
|
||||||
| AnyNode::Alias(_)
|
| AnyNode::Alias(_)
|
||||||
| AnyNode::Withitem(_)
|
| AnyNode::WithItem(_)
|
||||||
| AnyNode::MatchCase(_)
|
| AnyNode::MatchCase(_)
|
||||||
| AnyNode::Decorator(_) => None,
|
| AnyNode::Decorator(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn except_handler(self) -> Option<Excepthandler> {
|
pub fn except_handler(self) -> Option<ExceptHandler> {
|
||||||
match self {
|
match self {
|
||||||
AnyNode::ExcepthandlerExceptHandler(node) => Some(Excepthandler::ExceptHandler(node)),
|
AnyNode::ExceptHandlerExceptHandler(node) => Some(ExceptHandler::ExceptHandler(node)),
|
||||||
|
|
||||||
AnyNode::ModModule(_)
|
AnyNode::ModModule(_)
|
||||||
| AnyNode::ModInteractive(_)
|
| AnyNode::ModInteractive(_)
|
||||||
|
@ -498,9 +503,10 @@ impl AnyNode {
|
||||||
| AnyNode::Comprehension(_)
|
| AnyNode::Comprehension(_)
|
||||||
| AnyNode::Arguments(_)
|
| AnyNode::Arguments(_)
|
||||||
| AnyNode::Arg(_)
|
| AnyNode::Arg(_)
|
||||||
|
| AnyNode::ArgWithDefault(_)
|
||||||
| AnyNode::Keyword(_)
|
| AnyNode::Keyword(_)
|
||||||
| AnyNode::Alias(_)
|
| AnyNode::Alias(_)
|
||||||
| AnyNode::Withitem(_)
|
| AnyNode::WithItem(_)
|
||||||
| AnyNode::MatchCase(_)
|
| AnyNode::MatchCase(_)
|
||||||
| AnyNode::Decorator(_) => None,
|
| AnyNode::Decorator(_) => None,
|
||||||
}
|
}
|
||||||
|
@ -576,13 +582,14 @@ impl AnyNode {
|
||||||
| AnyNode::PatternMatchStar(_)
|
| AnyNode::PatternMatchStar(_)
|
||||||
| AnyNode::PatternMatchAs(_)
|
| AnyNode::PatternMatchAs(_)
|
||||||
| AnyNode::PatternMatchOr(_)
|
| AnyNode::PatternMatchOr(_)
|
||||||
| AnyNode::ExcepthandlerExceptHandler(_)
|
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||||
| AnyNode::Comprehension(_)
|
| AnyNode::Comprehension(_)
|
||||||
| AnyNode::Arguments(_)
|
| AnyNode::Arguments(_)
|
||||||
| AnyNode::Arg(_)
|
| AnyNode::Arg(_)
|
||||||
|
| AnyNode::ArgWithDefault(_)
|
||||||
| AnyNode::Keyword(_)
|
| AnyNode::Keyword(_)
|
||||||
| AnyNode::Alias(_)
|
| AnyNode::Alias(_)
|
||||||
| AnyNode::Withitem(_)
|
| AnyNode::WithItem(_)
|
||||||
| AnyNode::MatchCase(_)
|
| AnyNode::MatchCase(_)
|
||||||
| AnyNode::Decorator(_) => None,
|
| AnyNode::Decorator(_) => None,
|
||||||
}
|
}
|
||||||
|
@ -672,7 +679,7 @@ impl AnyNode {
|
||||||
Self::ExprList(node) => AnyNodeRef::ExprList(node),
|
Self::ExprList(node) => AnyNodeRef::ExprList(node),
|
||||||
Self::ExprTuple(node) => AnyNodeRef::ExprTuple(node),
|
Self::ExprTuple(node) => AnyNodeRef::ExprTuple(node),
|
||||||
Self::ExprSlice(node) => AnyNodeRef::ExprSlice(node),
|
Self::ExprSlice(node) => AnyNodeRef::ExprSlice(node),
|
||||||
Self::ExcepthandlerExceptHandler(node) => AnyNodeRef::ExcepthandlerExceptHandler(node),
|
Self::ExceptHandlerExceptHandler(node) => AnyNodeRef::ExceptHandlerExceptHandler(node),
|
||||||
Self::PatternMatchValue(node) => AnyNodeRef::PatternMatchValue(node),
|
Self::PatternMatchValue(node) => AnyNodeRef::PatternMatchValue(node),
|
||||||
Self::PatternMatchSingleton(node) => AnyNodeRef::PatternMatchSingleton(node),
|
Self::PatternMatchSingleton(node) => AnyNodeRef::PatternMatchSingleton(node),
|
||||||
Self::PatternMatchSequence(node) => AnyNodeRef::PatternMatchSequence(node),
|
Self::PatternMatchSequence(node) => AnyNodeRef::PatternMatchSequence(node),
|
||||||
|
@ -685,9 +692,10 @@ impl AnyNode {
|
||||||
Self::Comprehension(node) => AnyNodeRef::Comprehension(node),
|
Self::Comprehension(node) => AnyNodeRef::Comprehension(node),
|
||||||
Self::Arguments(node) => AnyNodeRef::Arguments(node),
|
Self::Arguments(node) => AnyNodeRef::Arguments(node),
|
||||||
Self::Arg(node) => AnyNodeRef::Arg(node),
|
Self::Arg(node) => AnyNodeRef::Arg(node),
|
||||||
|
Self::ArgWithDefault(node) => AnyNodeRef::ArgWithDefault(node),
|
||||||
Self::Keyword(node) => AnyNodeRef::Keyword(node),
|
Self::Keyword(node) => AnyNodeRef::Keyword(node),
|
||||||
Self::Alias(node) => AnyNodeRef::Alias(node),
|
Self::Alias(node) => AnyNodeRef::Alias(node),
|
||||||
Self::Withitem(node) => AnyNodeRef::Withitem(node),
|
Self::WithItem(node) => AnyNodeRef::WithItem(node),
|
||||||
Self::MatchCase(node) => AnyNodeRef::MatchCase(node),
|
Self::MatchCase(node) => AnyNodeRef::MatchCase(node),
|
||||||
Self::Decorator(node) => AnyNodeRef::Decorator(node),
|
Self::Decorator(node) => AnyNodeRef::Decorator(node),
|
||||||
}
|
}
|
||||||
|
@ -2323,12 +2331,12 @@ impl AstNode for ExprSlice<TextRange> {
|
||||||
AnyNode::from(self)
|
AnyNode::from(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl AstNode for ExcepthandlerExceptHandler<TextRange> {
|
impl AstNode for ExceptHandlerExceptHandler<TextRange> {
|
||||||
fn cast(kind: AnyNode) -> Option<Self>
|
fn cast(kind: AnyNode) -> Option<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
if let AnyNode::ExcepthandlerExceptHandler(node) = kind {
|
if let AnyNode::ExceptHandlerExceptHandler(node) = kind {
|
||||||
Some(node)
|
Some(node)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -2336,7 +2344,7 @@ impl AstNode for ExcepthandlerExceptHandler<TextRange> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
|
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
|
||||||
if let AnyNodeRef::ExcepthandlerExceptHandler(node) = kind {
|
if let AnyNodeRef::ExceptHandlerExceptHandler(node) = kind {
|
||||||
Some(node)
|
Some(node)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -2688,6 +2696,34 @@ impl AstNode for Arg<TextRange> {
|
||||||
AnyNode::from(self)
|
AnyNode::from(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl AstNode for ArgWithDefault<TextRange> {
|
||||||
|
fn cast(kind: AnyNode) -> Option<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
if let AnyNode::ArgWithDefault(node) = kind {
|
||||||
|
Some(node)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
|
||||||
|
if let AnyNodeRef::ArgWithDefault(node) = kind {
|
||||||
|
Some(node)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any_node_ref(&self) -> AnyNodeRef {
|
||||||
|
AnyNodeRef::from(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_any_node(self) -> AnyNode {
|
||||||
|
AnyNode::from(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl AstNode for Keyword<TextRange> {
|
impl AstNode for Keyword<TextRange> {
|
||||||
fn cast(kind: AnyNode) -> Option<Self>
|
fn cast(kind: AnyNode) -> Option<Self>
|
||||||
where
|
where
|
||||||
|
@ -2744,12 +2780,12 @@ impl AstNode for Alias<TextRange> {
|
||||||
AnyNode::from(self)
|
AnyNode::from(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl AstNode for Withitem<TextRange> {
|
impl AstNode for WithItem<TextRange> {
|
||||||
fn cast(kind: AnyNode) -> Option<Self>
|
fn cast(kind: AnyNode) -> Option<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
if let AnyNode::Withitem(node) = kind {
|
if let AnyNode::WithItem(node) = kind {
|
||||||
Some(node)
|
Some(node)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -2757,7 +2793,7 @@ impl AstNode for Withitem<TextRange> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
|
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
|
||||||
if let AnyNodeRef::Withitem(node) = kind {
|
if let AnyNodeRef::WithItem(node) = kind {
|
||||||
Some(node)
|
Some(node)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -2924,10 +2960,10 @@ impl From<Pattern> for AnyNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Excepthandler> for AnyNode {
|
impl From<ExceptHandler> for AnyNode {
|
||||||
fn from(handler: Excepthandler) -> Self {
|
fn from(handler: ExceptHandler) -> Self {
|
||||||
match handler {
|
match handler {
|
||||||
Excepthandler::ExceptHandler(handler) => AnyNode::ExcepthandlerExceptHandler(handler),
|
ExceptHandler::ExceptHandler(handler) => AnyNode::ExceptHandlerExceptHandler(handler),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3288,9 +3324,9 @@ impl From<ExprSlice> for AnyNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ExcepthandlerExceptHandler> for AnyNode {
|
impl From<ExceptHandlerExceptHandler> for AnyNode {
|
||||||
fn from(node: ExcepthandlerExceptHandler) -> Self {
|
fn from(node: ExceptHandlerExceptHandler) -> Self {
|
||||||
AnyNode::ExcepthandlerExceptHandler(node)
|
AnyNode::ExceptHandlerExceptHandler(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3363,6 +3399,11 @@ impl From<Arg> for AnyNode {
|
||||||
AnyNode::Arg(node)
|
AnyNode::Arg(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl From<ArgWithDefault> for AnyNode {
|
||||||
|
fn from(node: ArgWithDefault) -> Self {
|
||||||
|
AnyNode::ArgWithDefault(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl From<Keyword> for AnyNode {
|
impl From<Keyword> for AnyNode {
|
||||||
fn from(node: Keyword) -> Self {
|
fn from(node: Keyword) -> Self {
|
||||||
AnyNode::Keyword(node)
|
AnyNode::Keyword(node)
|
||||||
|
@ -3373,9 +3414,9 @@ impl From<Alias> for AnyNode {
|
||||||
AnyNode::Alias(node)
|
AnyNode::Alias(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<Withitem> for AnyNode {
|
impl From<WithItem> for AnyNode {
|
||||||
fn from(node: Withitem) -> Self {
|
fn from(node: WithItem) -> Self {
|
||||||
AnyNode::Withitem(node)
|
AnyNode::WithItem(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<MatchCase> for AnyNode {
|
impl From<MatchCase> for AnyNode {
|
||||||
|
@ -3450,7 +3491,7 @@ impl Ranged for AnyNode {
|
||||||
AnyNode::ExprList(node) => node.range(),
|
AnyNode::ExprList(node) => node.range(),
|
||||||
AnyNode::ExprTuple(node) => node.range(),
|
AnyNode::ExprTuple(node) => node.range(),
|
||||||
AnyNode::ExprSlice(node) => node.range(),
|
AnyNode::ExprSlice(node) => node.range(),
|
||||||
AnyNode::ExcepthandlerExceptHandler(node) => node.range(),
|
AnyNode::ExceptHandlerExceptHandler(node) => node.range(),
|
||||||
AnyNode::PatternMatchValue(node) => node.range(),
|
AnyNode::PatternMatchValue(node) => node.range(),
|
||||||
AnyNode::PatternMatchSingleton(node) => node.range(),
|
AnyNode::PatternMatchSingleton(node) => node.range(),
|
||||||
AnyNode::PatternMatchSequence(node) => node.range(),
|
AnyNode::PatternMatchSequence(node) => node.range(),
|
||||||
|
@ -3463,9 +3504,10 @@ impl Ranged for AnyNode {
|
||||||
AnyNode::Comprehension(node) => node.range(),
|
AnyNode::Comprehension(node) => node.range(),
|
||||||
AnyNode::Arguments(node) => node.range(),
|
AnyNode::Arguments(node) => node.range(),
|
||||||
AnyNode::Arg(node) => node.range(),
|
AnyNode::Arg(node) => node.range(),
|
||||||
|
AnyNode::ArgWithDefault(node) => node.range(),
|
||||||
AnyNode::Keyword(node) => node.range(),
|
AnyNode::Keyword(node) => node.range(),
|
||||||
AnyNode::Alias(node) => node.range(),
|
AnyNode::Alias(node) => node.range(),
|
||||||
AnyNode::Withitem(node) => node.range(),
|
AnyNode::WithItem(node) => node.range(),
|
||||||
AnyNode::MatchCase(node) => node.range(),
|
AnyNode::MatchCase(node) => node.range(),
|
||||||
AnyNode::Decorator(node) => node.range(),
|
AnyNode::Decorator(node) => node.range(),
|
||||||
}
|
}
|
||||||
|
@ -3532,7 +3574,7 @@ pub enum AnyNodeRef<'a> {
|
||||||
ExprList(&'a ExprList<TextRange>),
|
ExprList(&'a ExprList<TextRange>),
|
||||||
ExprTuple(&'a ExprTuple<TextRange>),
|
ExprTuple(&'a ExprTuple<TextRange>),
|
||||||
ExprSlice(&'a ExprSlice<TextRange>),
|
ExprSlice(&'a ExprSlice<TextRange>),
|
||||||
ExcepthandlerExceptHandler(&'a ExcepthandlerExceptHandler<TextRange>),
|
ExceptHandlerExceptHandler(&'a ExceptHandlerExceptHandler<TextRange>),
|
||||||
PatternMatchValue(&'a PatternMatchValue<TextRange>),
|
PatternMatchValue(&'a PatternMatchValue<TextRange>),
|
||||||
PatternMatchSingleton(&'a PatternMatchSingleton<TextRange>),
|
PatternMatchSingleton(&'a PatternMatchSingleton<TextRange>),
|
||||||
PatternMatchSequence(&'a PatternMatchSequence<TextRange>),
|
PatternMatchSequence(&'a PatternMatchSequence<TextRange>),
|
||||||
|
@ -3545,9 +3587,10 @@ pub enum AnyNodeRef<'a> {
|
||||||
Comprehension(&'a Comprehension<TextRange>),
|
Comprehension(&'a Comprehension<TextRange>),
|
||||||
Arguments(&'a Arguments<TextRange>),
|
Arguments(&'a Arguments<TextRange>),
|
||||||
Arg(&'a Arg<TextRange>),
|
Arg(&'a Arg<TextRange>),
|
||||||
|
ArgWithDefault(&'a ArgWithDefault<TextRange>),
|
||||||
Keyword(&'a Keyword<TextRange>),
|
Keyword(&'a Keyword<TextRange>),
|
||||||
Alias(&'a Alias<TextRange>),
|
Alias(&'a Alias<TextRange>),
|
||||||
Withitem(&'a Withitem<TextRange>),
|
WithItem(&'a WithItem<TextRange>),
|
||||||
MatchCase(&'a MatchCase<TextRange>),
|
MatchCase(&'a MatchCase<TextRange>),
|
||||||
Decorator(&'a Decorator<TextRange>),
|
Decorator(&'a Decorator<TextRange>),
|
||||||
}
|
}
|
||||||
|
@ -3613,7 +3656,7 @@ impl AnyNodeRef<'_> {
|
||||||
AnyNodeRef::ExprList(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::ExprList(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::ExprTuple(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::ExprTuple(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::ExprSlice(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::ExprSlice(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::ExcepthandlerExceptHandler(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::ExceptHandlerExceptHandler(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::PatternMatchValue(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::PatternMatchValue(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::PatternMatchSingleton(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::PatternMatchSingleton(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::PatternMatchSequence(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::PatternMatchSequence(node) => NonNull::from(*node).cast(),
|
||||||
|
@ -3626,9 +3669,10 @@ impl AnyNodeRef<'_> {
|
||||||
AnyNodeRef::Comprehension(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::Comprehension(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::Arguments(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::Arguments(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::Arg(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::Arg(node) => NonNull::from(*node).cast(),
|
||||||
|
AnyNodeRef::ArgWithDefault(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::Keyword(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::Keyword(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::Alias(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::Alias(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::Withitem(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::WithItem(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::MatchCase(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::MatchCase(node) => NonNull::from(*node).cast(),
|
||||||
AnyNodeRef::Decorator(node) => NonNull::from(*node).cast(),
|
AnyNodeRef::Decorator(node) => NonNull::from(*node).cast(),
|
||||||
}
|
}
|
||||||
|
@ -3700,7 +3744,7 @@ impl AnyNodeRef<'_> {
|
||||||
AnyNodeRef::ExprList(_) => NodeKind::ExprList,
|
AnyNodeRef::ExprList(_) => NodeKind::ExprList,
|
||||||
AnyNodeRef::ExprTuple(_) => NodeKind::ExprTuple,
|
AnyNodeRef::ExprTuple(_) => NodeKind::ExprTuple,
|
||||||
AnyNodeRef::ExprSlice(_) => NodeKind::ExprSlice,
|
AnyNodeRef::ExprSlice(_) => NodeKind::ExprSlice,
|
||||||
AnyNodeRef::ExcepthandlerExceptHandler(_) => NodeKind::ExcepthandlerExceptHandler,
|
AnyNodeRef::ExceptHandlerExceptHandler(_) => NodeKind::ExceptHandlerExceptHandler,
|
||||||
AnyNodeRef::PatternMatchValue(_) => NodeKind::PatternMatchValue,
|
AnyNodeRef::PatternMatchValue(_) => NodeKind::PatternMatchValue,
|
||||||
AnyNodeRef::PatternMatchSingleton(_) => NodeKind::PatternMatchSingleton,
|
AnyNodeRef::PatternMatchSingleton(_) => NodeKind::PatternMatchSingleton,
|
||||||
AnyNodeRef::PatternMatchSequence(_) => NodeKind::PatternMatchSequence,
|
AnyNodeRef::PatternMatchSequence(_) => NodeKind::PatternMatchSequence,
|
||||||
|
@ -3713,9 +3757,10 @@ impl AnyNodeRef<'_> {
|
||||||
AnyNodeRef::Comprehension(_) => NodeKind::Comprehension,
|
AnyNodeRef::Comprehension(_) => NodeKind::Comprehension,
|
||||||
AnyNodeRef::Arguments(_) => NodeKind::Arguments,
|
AnyNodeRef::Arguments(_) => NodeKind::Arguments,
|
||||||
AnyNodeRef::Arg(_) => NodeKind::Arg,
|
AnyNodeRef::Arg(_) => NodeKind::Arg,
|
||||||
|
AnyNodeRef::ArgWithDefault(_) => NodeKind::ArgWithDefault,
|
||||||
AnyNodeRef::Keyword(_) => NodeKind::Keyword,
|
AnyNodeRef::Keyword(_) => NodeKind::Keyword,
|
||||||
AnyNodeRef::Alias(_) => NodeKind::Alias,
|
AnyNodeRef::Alias(_) => NodeKind::Alias,
|
||||||
AnyNodeRef::Withitem(_) => NodeKind::Withitem,
|
AnyNodeRef::WithItem(_) => NodeKind::WithItem,
|
||||||
AnyNodeRef::MatchCase(_) => NodeKind::MatchCase,
|
AnyNodeRef::MatchCase(_) => NodeKind::MatchCase,
|
||||||
AnyNodeRef::Decorator(_) => NodeKind::Decorator,
|
AnyNodeRef::Decorator(_) => NodeKind::Decorator,
|
||||||
}
|
}
|
||||||
|
@ -3782,7 +3827,7 @@ impl AnyNodeRef<'_> {
|
||||||
| AnyNodeRef::ExprList(_)
|
| AnyNodeRef::ExprList(_)
|
||||||
| AnyNodeRef::ExprTuple(_)
|
| AnyNodeRef::ExprTuple(_)
|
||||||
| AnyNodeRef::ExprSlice(_)
|
| AnyNodeRef::ExprSlice(_)
|
||||||
| AnyNodeRef::ExcepthandlerExceptHandler(_)
|
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||||
| AnyNodeRef::PatternMatchValue(_)
|
| AnyNodeRef::PatternMatchValue(_)
|
||||||
| AnyNodeRef::PatternMatchSingleton(_)
|
| AnyNodeRef::PatternMatchSingleton(_)
|
||||||
| AnyNodeRef::PatternMatchSequence(_)
|
| AnyNodeRef::PatternMatchSequence(_)
|
||||||
|
@ -3795,9 +3840,10 @@ impl AnyNodeRef<'_> {
|
||||||
| AnyNodeRef::Comprehension(_)
|
| AnyNodeRef::Comprehension(_)
|
||||||
| AnyNodeRef::Arguments(_)
|
| AnyNodeRef::Arguments(_)
|
||||||
| AnyNodeRef::Arg(_)
|
| AnyNodeRef::Arg(_)
|
||||||
|
| AnyNodeRef::ArgWithDefault(_)
|
||||||
| AnyNodeRef::Keyword(_)
|
| AnyNodeRef::Keyword(_)
|
||||||
| AnyNodeRef::Alias(_)
|
| AnyNodeRef::Alias(_)
|
||||||
| AnyNodeRef::Withitem(_)
|
| AnyNodeRef::WithItem(_)
|
||||||
| AnyNodeRef::MatchCase(_)
|
| AnyNodeRef::MatchCase(_)
|
||||||
| AnyNodeRef::Decorator(_) => false,
|
| AnyNodeRef::Decorator(_) => false,
|
||||||
}
|
}
|
||||||
|
@ -3864,7 +3910,7 @@ impl AnyNodeRef<'_> {
|
||||||
| AnyNodeRef::StmtPass(_)
|
| AnyNodeRef::StmtPass(_)
|
||||||
| AnyNodeRef::StmtBreak(_)
|
| AnyNodeRef::StmtBreak(_)
|
||||||
| AnyNodeRef::StmtContinue(_)
|
| AnyNodeRef::StmtContinue(_)
|
||||||
| AnyNodeRef::ExcepthandlerExceptHandler(_)
|
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||||
| AnyNodeRef::PatternMatchValue(_)
|
| AnyNodeRef::PatternMatchValue(_)
|
||||||
| AnyNodeRef::PatternMatchSingleton(_)
|
| AnyNodeRef::PatternMatchSingleton(_)
|
||||||
| AnyNodeRef::PatternMatchSequence(_)
|
| AnyNodeRef::PatternMatchSequence(_)
|
||||||
|
@ -3877,9 +3923,10 @@ impl AnyNodeRef<'_> {
|
||||||
| AnyNodeRef::Comprehension(_)
|
| AnyNodeRef::Comprehension(_)
|
||||||
| AnyNodeRef::Arguments(_)
|
| AnyNodeRef::Arguments(_)
|
||||||
| AnyNodeRef::Arg(_)
|
| AnyNodeRef::Arg(_)
|
||||||
|
| AnyNodeRef::ArgWithDefault(_)
|
||||||
| AnyNodeRef::Keyword(_)
|
| AnyNodeRef::Keyword(_)
|
||||||
| AnyNodeRef::Alias(_)
|
| AnyNodeRef::Alias(_)
|
||||||
| AnyNodeRef::Withitem(_)
|
| AnyNodeRef::WithItem(_)
|
||||||
| AnyNodeRef::MatchCase(_)
|
| AnyNodeRef::MatchCase(_)
|
||||||
| AnyNodeRef::Decorator(_) => false,
|
| AnyNodeRef::Decorator(_) => false,
|
||||||
}
|
}
|
||||||
|
@ -3946,7 +3993,7 @@ impl AnyNodeRef<'_> {
|
||||||
| AnyNodeRef::ExprList(_)
|
| AnyNodeRef::ExprList(_)
|
||||||
| AnyNodeRef::ExprTuple(_)
|
| AnyNodeRef::ExprTuple(_)
|
||||||
| AnyNodeRef::ExprSlice(_)
|
| AnyNodeRef::ExprSlice(_)
|
||||||
| AnyNodeRef::ExcepthandlerExceptHandler(_)
|
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||||
| AnyNodeRef::PatternMatchValue(_)
|
| AnyNodeRef::PatternMatchValue(_)
|
||||||
| AnyNodeRef::PatternMatchSingleton(_)
|
| AnyNodeRef::PatternMatchSingleton(_)
|
||||||
| AnyNodeRef::PatternMatchSequence(_)
|
| AnyNodeRef::PatternMatchSequence(_)
|
||||||
|
@ -3959,9 +4006,10 @@ impl AnyNodeRef<'_> {
|
||||||
| AnyNodeRef::Comprehension(_)
|
| AnyNodeRef::Comprehension(_)
|
||||||
| AnyNodeRef::Arguments(_)
|
| AnyNodeRef::Arguments(_)
|
||||||
| AnyNodeRef::Arg(_)
|
| AnyNodeRef::Arg(_)
|
||||||
|
| AnyNodeRef::ArgWithDefault(_)
|
||||||
| AnyNodeRef::Keyword(_)
|
| AnyNodeRef::Keyword(_)
|
||||||
| AnyNodeRef::Alias(_)
|
| AnyNodeRef::Alias(_)
|
||||||
| AnyNodeRef::Withitem(_)
|
| AnyNodeRef::WithItem(_)
|
||||||
| AnyNodeRef::MatchCase(_)
|
| AnyNodeRef::MatchCase(_)
|
||||||
| AnyNodeRef::Decorator(_) => false,
|
| AnyNodeRef::Decorator(_) => false,
|
||||||
}
|
}
|
||||||
|
@ -4036,14 +4084,15 @@ impl AnyNodeRef<'_> {
|
||||||
| AnyNodeRef::ExprList(_)
|
| AnyNodeRef::ExprList(_)
|
||||||
| AnyNodeRef::ExprTuple(_)
|
| AnyNodeRef::ExprTuple(_)
|
||||||
| AnyNodeRef::ExprSlice(_)
|
| AnyNodeRef::ExprSlice(_)
|
||||||
| AnyNodeRef::ExcepthandlerExceptHandler(_)
|
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||||
| AnyNodeRef::TypeIgnoreTypeIgnore(_)
|
| AnyNodeRef::TypeIgnoreTypeIgnore(_)
|
||||||
| AnyNodeRef::Comprehension(_)
|
| AnyNodeRef::Comprehension(_)
|
||||||
| AnyNodeRef::Arguments(_)
|
| AnyNodeRef::Arguments(_)
|
||||||
| AnyNodeRef::Arg(_)
|
| AnyNodeRef::Arg(_)
|
||||||
|
| AnyNodeRef::ArgWithDefault(_)
|
||||||
| AnyNodeRef::Keyword(_)
|
| AnyNodeRef::Keyword(_)
|
||||||
| AnyNodeRef::Alias(_)
|
| AnyNodeRef::Alias(_)
|
||||||
| AnyNodeRef::Withitem(_)
|
| AnyNodeRef::WithItem(_)
|
||||||
| AnyNodeRef::MatchCase(_)
|
| AnyNodeRef::MatchCase(_)
|
||||||
| AnyNodeRef::Decorator(_) => false,
|
| AnyNodeRef::Decorator(_) => false,
|
||||||
}
|
}
|
||||||
|
@ -4051,7 +4100,7 @@ impl AnyNodeRef<'_> {
|
||||||
|
|
||||||
pub const fn is_except_handler(self) -> bool {
|
pub const fn is_except_handler(self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
AnyNodeRef::ExcepthandlerExceptHandler(_) => true,
|
AnyNodeRef::ExceptHandlerExceptHandler(_) => true,
|
||||||
|
|
||||||
AnyNodeRef::ModModule(_)
|
AnyNodeRef::ModModule(_)
|
||||||
| AnyNodeRef::ModInteractive(_)
|
| AnyNodeRef::ModInteractive(_)
|
||||||
|
@ -4123,9 +4172,10 @@ impl AnyNodeRef<'_> {
|
||||||
| AnyNodeRef::Comprehension(_)
|
| AnyNodeRef::Comprehension(_)
|
||||||
| AnyNodeRef::Arguments(_)
|
| AnyNodeRef::Arguments(_)
|
||||||
| AnyNodeRef::Arg(_)
|
| AnyNodeRef::Arg(_)
|
||||||
|
| AnyNodeRef::ArgWithDefault(_)
|
||||||
| AnyNodeRef::Keyword(_)
|
| AnyNodeRef::Keyword(_)
|
||||||
| AnyNodeRef::Alias(_)
|
| AnyNodeRef::Alias(_)
|
||||||
| AnyNodeRef::Withitem(_)
|
| AnyNodeRef::WithItem(_)
|
||||||
| AnyNodeRef::MatchCase(_)
|
| AnyNodeRef::MatchCase(_)
|
||||||
| AnyNodeRef::Decorator(_) => false,
|
| AnyNodeRef::Decorator(_) => false,
|
||||||
}
|
}
|
||||||
|
@ -4201,13 +4251,14 @@ impl AnyNodeRef<'_> {
|
||||||
| AnyNodeRef::PatternMatchStar(_)
|
| AnyNodeRef::PatternMatchStar(_)
|
||||||
| AnyNodeRef::PatternMatchAs(_)
|
| AnyNodeRef::PatternMatchAs(_)
|
||||||
| AnyNodeRef::PatternMatchOr(_)
|
| AnyNodeRef::PatternMatchOr(_)
|
||||||
| AnyNodeRef::ExcepthandlerExceptHandler(_)
|
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||||
| AnyNodeRef::Comprehension(_)
|
| AnyNodeRef::Comprehension(_)
|
||||||
| AnyNodeRef::Arguments(_)
|
| AnyNodeRef::Arguments(_)
|
||||||
| AnyNodeRef::Arg(_)
|
| AnyNodeRef::Arg(_)
|
||||||
|
| AnyNodeRef::ArgWithDefault(_)
|
||||||
| AnyNodeRef::Keyword(_)
|
| AnyNodeRef::Keyword(_)
|
||||||
| AnyNodeRef::Alias(_)
|
| AnyNodeRef::Alias(_)
|
||||||
| AnyNodeRef::Withitem(_)
|
| AnyNodeRef::WithItem(_)
|
||||||
| AnyNodeRef::MatchCase(_)
|
| AnyNodeRef::MatchCase(_)
|
||||||
| AnyNodeRef::Decorator(_) => false,
|
| AnyNodeRef::Decorator(_) => false,
|
||||||
}
|
}
|
||||||
|
@ -4578,9 +4629,9 @@ impl<'a> From<&'a ExprSlice> for AnyNodeRef<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a ExcepthandlerExceptHandler> for AnyNodeRef<'a> {
|
impl<'a> From<&'a ExceptHandlerExceptHandler> for AnyNodeRef<'a> {
|
||||||
fn from(node: &'a ExcepthandlerExceptHandler) -> Self {
|
fn from(node: &'a ExceptHandlerExceptHandler) -> Self {
|
||||||
AnyNodeRef::ExcepthandlerExceptHandler(node)
|
AnyNodeRef::ExceptHandlerExceptHandler(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4738,11 +4789,11 @@ impl<'a> From<&'a Pattern> for AnyNodeRef<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a Excepthandler> for AnyNodeRef<'a> {
|
impl<'a> From<&'a ExceptHandler> for AnyNodeRef<'a> {
|
||||||
fn from(handler: &'a Excepthandler) -> Self {
|
fn from(handler: &'a ExceptHandler) -> Self {
|
||||||
match handler {
|
match handler {
|
||||||
Excepthandler::ExceptHandler(handler) => {
|
ExceptHandler::ExceptHandler(handler) => {
|
||||||
AnyNodeRef::ExcepthandlerExceptHandler(handler)
|
AnyNodeRef::ExceptHandlerExceptHandler(handler)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4771,6 +4822,11 @@ impl<'a> From<&'a Arg> for AnyNodeRef<'a> {
|
||||||
AnyNodeRef::Arg(node)
|
AnyNodeRef::Arg(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'a> From<&'a ArgWithDefault> for AnyNodeRef<'a> {
|
||||||
|
fn from(node: &'a ArgWithDefault) -> Self {
|
||||||
|
AnyNodeRef::ArgWithDefault(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl<'a> From<&'a Keyword> for AnyNodeRef<'a> {
|
impl<'a> From<&'a Keyword> for AnyNodeRef<'a> {
|
||||||
fn from(node: &'a Keyword) -> Self {
|
fn from(node: &'a Keyword) -> Self {
|
||||||
AnyNodeRef::Keyword(node)
|
AnyNodeRef::Keyword(node)
|
||||||
|
@ -4781,9 +4837,9 @@ impl<'a> From<&'a Alias> for AnyNodeRef<'a> {
|
||||||
AnyNodeRef::Alias(node)
|
AnyNodeRef::Alias(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> From<&'a Withitem> for AnyNodeRef<'a> {
|
impl<'a> From<&'a WithItem> for AnyNodeRef<'a> {
|
||||||
fn from(node: &'a Withitem) -> Self {
|
fn from(node: &'a WithItem) -> Self {
|
||||||
AnyNodeRef::Withitem(node)
|
AnyNodeRef::WithItem(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> From<&'a MatchCase> for AnyNodeRef<'a> {
|
impl<'a> From<&'a MatchCase> for AnyNodeRef<'a> {
|
||||||
|
@ -4853,7 +4909,7 @@ impl Ranged for AnyNodeRef<'_> {
|
||||||
AnyNodeRef::ExprList(node) => node.range(),
|
AnyNodeRef::ExprList(node) => node.range(),
|
||||||
AnyNodeRef::ExprTuple(node) => node.range(),
|
AnyNodeRef::ExprTuple(node) => node.range(),
|
||||||
AnyNodeRef::ExprSlice(node) => node.range(),
|
AnyNodeRef::ExprSlice(node) => node.range(),
|
||||||
AnyNodeRef::ExcepthandlerExceptHandler(node) => node.range(),
|
AnyNodeRef::ExceptHandlerExceptHandler(node) => node.range(),
|
||||||
AnyNodeRef::PatternMatchValue(node) => node.range(),
|
AnyNodeRef::PatternMatchValue(node) => node.range(),
|
||||||
AnyNodeRef::PatternMatchSingleton(node) => node.range(),
|
AnyNodeRef::PatternMatchSingleton(node) => node.range(),
|
||||||
AnyNodeRef::PatternMatchSequence(node) => node.range(),
|
AnyNodeRef::PatternMatchSequence(node) => node.range(),
|
||||||
|
@ -4866,9 +4922,10 @@ impl Ranged for AnyNodeRef<'_> {
|
||||||
AnyNodeRef::Comprehension(node) => node.range(),
|
AnyNodeRef::Comprehension(node) => node.range(),
|
||||||
AnyNodeRef::Arguments(node) => node.range(),
|
AnyNodeRef::Arguments(node) => node.range(),
|
||||||
AnyNodeRef::Arg(node) => node.range(),
|
AnyNodeRef::Arg(node) => node.range(),
|
||||||
|
AnyNodeRef::ArgWithDefault(node) => node.range(),
|
||||||
AnyNodeRef::Keyword(node) => node.range(),
|
AnyNodeRef::Keyword(node) => node.range(),
|
||||||
AnyNodeRef::Alias(node) => node.range(),
|
AnyNodeRef::Alias(node) => node.range(),
|
||||||
AnyNodeRef::Withitem(node) => node.range(),
|
AnyNodeRef::WithItem(node) => node.range(),
|
||||||
AnyNodeRef::MatchCase(node) => node.range(),
|
AnyNodeRef::MatchCase(node) => node.range(),
|
||||||
AnyNodeRef::Decorator(node) => node.range(),
|
AnyNodeRef::Decorator(node) => node.range(),
|
||||||
}
|
}
|
||||||
|
@ -4935,7 +4992,7 @@ pub enum NodeKind {
|
||||||
ExprList,
|
ExprList,
|
||||||
ExprTuple,
|
ExprTuple,
|
||||||
ExprSlice,
|
ExprSlice,
|
||||||
ExcepthandlerExceptHandler,
|
ExceptHandlerExceptHandler,
|
||||||
PatternMatchValue,
|
PatternMatchValue,
|
||||||
PatternMatchSingleton,
|
PatternMatchSingleton,
|
||||||
PatternMatchSequence,
|
PatternMatchSequence,
|
||||||
|
@ -4948,9 +5005,10 @@ pub enum NodeKind {
|
||||||
Comprehension,
|
Comprehension,
|
||||||
Arguments,
|
Arguments,
|
||||||
Arg,
|
Arg,
|
||||||
|
ArgWithDefault,
|
||||||
Keyword,
|
Keyword,
|
||||||
Alias,
|
Alias,
|
||||||
Withitem,
|
WithItem,
|
||||||
MatchCase,
|
MatchCase,
|
||||||
Decorator,
|
Decorator,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
//! Generate Python source code from an abstract syntax tree (AST).
|
//! Generate Python source code from an abstract syntax tree (AST).
|
||||||
|
|
||||||
|
use rustpython_ast::ArgWithDefault;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use rustpython_literal::escape::{AsciiEscape, Escape, UnicodeEscape};
|
use rustpython_literal::escape::{AsciiEscape, Escape, UnicodeEscape};
|
||||||
use rustpython_parser::ast::{
|
use rustpython_parser::ast::{
|
||||||
self, Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant, ConversionFlag,
|
self, Alias, Arg, Arguments, BoolOp, CmpOp, Comprehension, Constant, ConversionFlag,
|
||||||
Excepthandler, Expr, Identifier, MatchCase, Operator, Pattern, Stmt, Suite, Withitem,
|
ExceptHandler, Expr, Identifier, MatchCase, Operator, Pattern, Stmt, Suite, WithItem,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ruff_python_whitespace::LineEnding;
|
use ruff_python_whitespace::LineEnding;
|
||||||
|
@ -501,7 +502,7 @@ impl<'a> Generator<'a> {
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for item in items {
|
for item in items {
|
||||||
self.p_delim(&mut first, ", ");
|
self.p_delim(&mut first, ", ");
|
||||||
self.unparse_withitem(item);
|
self.unparse_with_item(item);
|
||||||
}
|
}
|
||||||
self.p(":");
|
self.p(":");
|
||||||
});
|
});
|
||||||
|
@ -513,7 +514,7 @@ impl<'a> Generator<'a> {
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for item in items {
|
for item in items {
|
||||||
self.p_delim(&mut first, ", ");
|
self.p_delim(&mut first, ", ");
|
||||||
self.unparse_withitem(item);
|
self.unparse_with_item(item);
|
||||||
}
|
}
|
||||||
self.p(":");
|
self.p(":");
|
||||||
});
|
});
|
||||||
|
@ -568,7 +569,7 @@ impl<'a> Generator<'a> {
|
||||||
|
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
statement!({
|
statement!({
|
||||||
self.unparse_excepthandler(handler, false);
|
self.unparse_except_handler(handler, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +600,7 @@ impl<'a> Generator<'a> {
|
||||||
|
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
statement!({
|
statement!({
|
||||||
self.unparse_excepthandler(handler, true);
|
self.unparse_except_handler(handler, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,9 +718,9 @@ impl<'a> Generator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unparse_excepthandler<U>(&mut self, ast: &Excepthandler<U>, star: bool) {
|
fn unparse_except_handler<U>(&mut self, ast: &ExceptHandler<U>, star: bool) {
|
||||||
match ast {
|
match ast {
|
||||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||||
type_,
|
type_,
|
||||||
name,
|
name,
|
||||||
body,
|
body,
|
||||||
|
@ -870,7 +871,7 @@ impl<'a> Generator<'a> {
|
||||||
values,
|
values,
|
||||||
range: _range,
|
range: _range,
|
||||||
}) => {
|
}) => {
|
||||||
let (op, prec) = opprec!(bin, op, Boolop, And("and", AND), Or("or", OR));
|
let (op, prec) = opprec!(bin, op, BoolOp, And("and", AND), Or("or", OR));
|
||||||
group_if!(prec, {
|
group_if!(prec, {
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for val in values {
|
for val in values {
|
||||||
|
@ -929,7 +930,7 @@ impl<'a> Generator<'a> {
|
||||||
let (op, prec) = opprec!(
|
let (op, prec) = opprec!(
|
||||||
un,
|
un,
|
||||||
op,
|
op,
|
||||||
rustpython_parser::ast::Unaryop,
|
rustpython_parser::ast::UnaryOp,
|
||||||
Invert("~", INVERT),
|
Invert("~", INVERT),
|
||||||
Not("not ", NOT),
|
Not("not ", NOT),
|
||||||
UAdd("+", UADD),
|
UAdd("+", UADD),
|
||||||
|
@ -1087,16 +1088,16 @@ impl<'a> Generator<'a> {
|
||||||
self.unparse_expr(left, new_lvl);
|
self.unparse_expr(left, new_lvl);
|
||||||
for (op, cmp) in ops.iter().zip(comparators) {
|
for (op, cmp) in ops.iter().zip(comparators) {
|
||||||
let op = match op {
|
let op = match op {
|
||||||
Cmpop::Eq => " == ",
|
CmpOp::Eq => " == ",
|
||||||
Cmpop::NotEq => " != ",
|
CmpOp::NotEq => " != ",
|
||||||
Cmpop::Lt => " < ",
|
CmpOp::Lt => " < ",
|
||||||
Cmpop::LtE => " <= ",
|
CmpOp::LtE => " <= ",
|
||||||
Cmpop::Gt => " > ",
|
CmpOp::Gt => " > ",
|
||||||
Cmpop::GtE => " >= ",
|
CmpOp::GtE => " >= ",
|
||||||
Cmpop::Is => " is ",
|
CmpOp::Is => " is ",
|
||||||
Cmpop::IsNot => " is not ",
|
CmpOp::IsNot => " is not ",
|
||||||
Cmpop::In => " in ",
|
CmpOp::In => " in ",
|
||||||
Cmpop::NotIn => " not in ",
|
CmpOp::NotIn => " not in ",
|
||||||
};
|
};
|
||||||
self.p(op);
|
self.p(op);
|
||||||
self.unparse_expr(cmp, new_lvl);
|
self.unparse_expr(cmp, new_lvl);
|
||||||
|
@ -1290,14 +1291,9 @@ impl<'a> Generator<'a> {
|
||||||
|
|
||||||
fn unparse_args<U>(&mut self, args: &Arguments<U>) {
|
fn unparse_args<U>(&mut self, args: &Arguments<U>) {
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
let defaults_start = args.posonlyargs.len() + args.args.len() - args.defaults.len();
|
for (i, arg_with_default) in args.posonlyargs.iter().chain(&args.args).enumerate() {
|
||||||
for (i, arg) in args.posonlyargs.iter().chain(&args.args).enumerate() {
|
|
||||||
self.p_delim(&mut first, ", ");
|
self.p_delim(&mut first, ", ");
|
||||||
self.unparse_arg(arg);
|
self.unparse_arg_with_default(arg_with_default);
|
||||||
if let Some(i) = i.checked_sub(defaults_start) {
|
|
||||||
self.p("=");
|
|
||||||
self.unparse_expr(&args.defaults[i], precedence::COMMA);
|
|
||||||
}
|
|
||||||
self.p_if(i + 1 == args.posonlyargs.len(), ", /");
|
self.p_if(i + 1 == args.posonlyargs.len(), ", /");
|
||||||
}
|
}
|
||||||
if args.vararg.is_some() || !args.kwonlyargs.is_empty() {
|
if args.vararg.is_some() || !args.kwonlyargs.is_empty() {
|
||||||
|
@ -1307,17 +1303,9 @@ impl<'a> Generator<'a> {
|
||||||
if let Some(vararg) = &args.vararg {
|
if let Some(vararg) = &args.vararg {
|
||||||
self.unparse_arg(vararg);
|
self.unparse_arg(vararg);
|
||||||
}
|
}
|
||||||
let defaults_start = args.kwonlyargs.len() - args.kw_defaults.len();
|
for kwarg in &args.kwonlyargs {
|
||||||
for (i, kwarg) in args.kwonlyargs.iter().enumerate() {
|
|
||||||
self.p_delim(&mut first, ", ");
|
self.p_delim(&mut first, ", ");
|
||||||
self.unparse_arg(kwarg);
|
self.unparse_arg_with_default(kwarg);
|
||||||
if let Some(default) = i
|
|
||||||
.checked_sub(defaults_start)
|
|
||||||
.and_then(|i| args.kw_defaults.get(i))
|
|
||||||
{
|
|
||||||
self.p("=");
|
|
||||||
self.unparse_expr(default, precedence::COMMA);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if let Some(kwarg) = &args.kwarg {
|
if let Some(kwarg) = &args.kwarg {
|
||||||
self.p_delim(&mut first, ", ");
|
self.p_delim(&mut first, ", ");
|
||||||
|
@ -1334,6 +1322,14 @@ impl<'a> Generator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unparse_arg_with_default<U>(&mut self, arg_with_default: &ArgWithDefault<U>) {
|
||||||
|
self.unparse_arg(&arg_with_default.def);
|
||||||
|
if let Some(default) = &arg_with_default.default {
|
||||||
|
self.p("=");
|
||||||
|
self.unparse_expr(default, precedence::COMMA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn unparse_comp<U>(&mut self, generators: &[Comprehension<U>]) {
|
fn unparse_comp<U>(&mut self, generators: &[Comprehension<U>]) {
|
||||||
for comp in generators {
|
for comp in generators {
|
||||||
self.p(if comp.is_async {
|
self.p(if comp.is_async {
|
||||||
|
@ -1445,9 +1441,9 @@ impl<'a> Generator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unparse_withitem<U>(&mut self, withitem: &Withitem<U>) {
|
fn unparse_with_item<U>(&mut self, with_item: &WithItem<U>) {
|
||||||
self.unparse_expr(&withitem.context_expr, precedence::MAX);
|
self.unparse_expr(&with_item.context_expr, precedence::MAX);
|
||||||
if let Some(optional_vars) = &withitem.optional_vars {
|
if let Some(optional_vars) = &with_item.optional_vars {
|
||||||
self.p(" as ");
|
self.p(" as ");
|
||||||
self.unparse_expr(optional_vars, precedence::MAX);
|
self.unparse_expr(optional_vars, precedence::MAX);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Specialized AST visitor trait and walk functions that only visit statements.
|
//! Specialized AST visitor trait and walk functions that only visit statements.
|
||||||
|
|
||||||
use rustpython_parser::ast::{self, Excepthandler, MatchCase, Stmt};
|
use rustpython_parser::ast::{self, ExceptHandler, MatchCase, Stmt};
|
||||||
|
|
||||||
/// A trait for AST visitors that only need to visit statements.
|
/// A trait for AST visitors that only need to visit statements.
|
||||||
pub trait StatementVisitor<'a> {
|
pub trait StatementVisitor<'a> {
|
||||||
|
@ -10,8 +10,8 @@ pub trait StatementVisitor<'a> {
|
||||||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||||
walk_stmt(self, stmt);
|
walk_stmt(self, stmt);
|
||||||
}
|
}
|
||||||
fn visit_excepthandler(&mut self, excepthandler: &'a Excepthandler) {
|
fn visit_except_handler(&mut self, except_handler: &'a ExceptHandler) {
|
||||||
walk_excepthandler(self, excepthandler);
|
walk_except_handler(self, except_handler);
|
||||||
}
|
}
|
||||||
fn visit_match_case(&mut self, match_case: &'a MatchCase) {
|
fn visit_match_case(&mut self, match_case: &'a MatchCase) {
|
||||||
walk_match_case(self, match_case);
|
walk_match_case(self, match_case);
|
||||||
|
@ -70,8 +70,8 @@ pub fn walk_stmt<'a, V: StatementVisitor<'a> + ?Sized>(visitor: &mut V, stmt: &'
|
||||||
range: _range,
|
range: _range,
|
||||||
}) => {
|
}) => {
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(body);
|
||||||
for excepthandler in handlers {
|
for except_handler in handlers {
|
||||||
visitor.visit_excepthandler(excepthandler);
|
visitor.visit_except_handler(except_handler);
|
||||||
}
|
}
|
||||||
visitor.visit_body(orelse);
|
visitor.visit_body(orelse);
|
||||||
visitor.visit_body(finalbody);
|
visitor.visit_body(finalbody);
|
||||||
|
@ -84,8 +84,8 @@ pub fn walk_stmt<'a, V: StatementVisitor<'a> + ?Sized>(visitor: &mut V, stmt: &'
|
||||||
range: _range,
|
range: _range,
|
||||||
}) => {
|
}) => {
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(body);
|
||||||
for excepthandler in handlers {
|
for except_handler in handlers {
|
||||||
visitor.visit_excepthandler(excepthandler);
|
visitor.visit_except_handler(except_handler);
|
||||||
}
|
}
|
||||||
visitor.visit_body(orelse);
|
visitor.visit_body(orelse);
|
||||||
visitor.visit_body(finalbody);
|
visitor.visit_body(finalbody);
|
||||||
|
@ -94,12 +94,12 @@ pub fn walk_stmt<'a, V: StatementVisitor<'a> + ?Sized>(visitor: &mut V, stmt: &'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_excepthandler<'a, V: StatementVisitor<'a> + ?Sized>(
|
pub fn walk_except_handler<'a, V: StatementVisitor<'a> + ?Sized>(
|
||||||
visitor: &mut V,
|
visitor: &mut V,
|
||||||
excepthandler: &'a Excepthandler,
|
except_handler: &'a ExceptHandler,
|
||||||
) {
|
) {
|
||||||
match excepthandler {
|
match except_handler {
|
||||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) => {
|
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { body, .. }) => {
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
pub mod preorder;
|
pub mod preorder;
|
||||||
|
|
||||||
use rustpython_ast::Decorator;
|
use rustpython_ast::{ArgWithDefault, Decorator};
|
||||||
use rustpython_parser::ast::{
|
use rustpython_parser::ast::{
|
||||||
self, Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant, Excepthandler, Expr,
|
self, Alias, Arg, Arguments, BoolOp, CmpOp, Comprehension, Constant, ExceptHandler, Expr,
|
||||||
ExprContext, Keyword, MatchCase, Operator, Pattern, Stmt, Unaryop, Withitem,
|
ExprContext, Keyword, MatchCase, Operator, Pattern, Stmt, UnaryOp, WithItem,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A trait for AST visitors. Visits all nodes in the AST recursively in evaluation-order.
|
/// A trait for AST visitors. Visits all nodes in the AST recursively in evaluation-order.
|
||||||
|
@ -34,23 +34,23 @@ pub trait Visitor<'a> {
|
||||||
fn visit_expr_context(&mut self, expr_context: &'a ExprContext) {
|
fn visit_expr_context(&mut self, expr_context: &'a ExprContext) {
|
||||||
walk_expr_context(self, expr_context);
|
walk_expr_context(self, expr_context);
|
||||||
}
|
}
|
||||||
fn visit_boolop(&mut self, boolop: &'a Boolop) {
|
fn visit_bool_op(&mut self, bool_op: &'a BoolOp) {
|
||||||
walk_boolop(self, boolop);
|
walk_bool_op(self, bool_op);
|
||||||
}
|
}
|
||||||
fn visit_operator(&mut self, operator: &'a Operator) {
|
fn visit_operator(&mut self, operator: &'a Operator) {
|
||||||
walk_operator(self, operator);
|
walk_operator(self, operator);
|
||||||
}
|
}
|
||||||
fn visit_unaryop(&mut self, unaryop: &'a Unaryop) {
|
fn visit_unary_op(&mut self, unary_op: &'a UnaryOp) {
|
||||||
walk_unaryop(self, unaryop);
|
walk_unary_op(self, unary_op);
|
||||||
}
|
}
|
||||||
fn visit_cmpop(&mut self, cmpop: &'a Cmpop) {
|
fn visit_cmp_op(&mut self, cmp_op: &'a CmpOp) {
|
||||||
walk_cmpop(self, cmpop);
|
walk_cmp_op(self, cmp_op);
|
||||||
}
|
}
|
||||||
fn visit_comprehension(&mut self, comprehension: &'a Comprehension) {
|
fn visit_comprehension(&mut self, comprehension: &'a Comprehension) {
|
||||||
walk_comprehension(self, comprehension);
|
walk_comprehension(self, comprehension);
|
||||||
}
|
}
|
||||||
fn visit_excepthandler(&mut self, excepthandler: &'a Excepthandler) {
|
fn visit_except_handler(&mut self, except_handler: &'a ExceptHandler) {
|
||||||
walk_excepthandler(self, excepthandler);
|
walk_except_handler(self, except_handler);
|
||||||
}
|
}
|
||||||
fn visit_format_spec(&mut self, format_spec: &'a Expr) {
|
fn visit_format_spec(&mut self, format_spec: &'a Expr) {
|
||||||
walk_expr(self, format_spec);
|
walk_expr(self, format_spec);
|
||||||
|
@ -61,14 +61,17 @@ pub trait Visitor<'a> {
|
||||||
fn visit_arg(&mut self, arg: &'a Arg) {
|
fn visit_arg(&mut self, arg: &'a Arg) {
|
||||||
walk_arg(self, arg);
|
walk_arg(self, arg);
|
||||||
}
|
}
|
||||||
|
fn visit_arg_with_default(&mut self, arg_with_default: &'a ArgWithDefault) {
|
||||||
|
walk_arg_with_default(self, arg_with_default);
|
||||||
|
}
|
||||||
fn visit_keyword(&mut self, keyword: &'a Keyword) {
|
fn visit_keyword(&mut self, keyword: &'a Keyword) {
|
||||||
walk_keyword(self, keyword);
|
walk_keyword(self, keyword);
|
||||||
}
|
}
|
||||||
fn visit_alias(&mut self, alias: &'a Alias) {
|
fn visit_alias(&mut self, alias: &'a Alias) {
|
||||||
walk_alias(self, alias);
|
walk_alias(self, alias);
|
||||||
}
|
}
|
||||||
fn visit_withitem(&mut self, withitem: &'a Withitem) {
|
fn visit_with_item(&mut self, with_item: &'a WithItem) {
|
||||||
walk_withitem(self, withitem);
|
walk_with_item(self, with_item);
|
||||||
}
|
}
|
||||||
fn visit_match_case(&mut self, match_case: &'a MatchCase) {
|
fn visit_match_case(&mut self, match_case: &'a MatchCase) {
|
||||||
walk_match_case(self, match_case);
|
walk_match_case(self, match_case);
|
||||||
|
@ -228,14 +231,14 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
|
||||||
visitor.visit_body(orelse);
|
visitor.visit_body(orelse);
|
||||||
}
|
}
|
||||||
Stmt::With(ast::StmtWith { items, body, .. }) => {
|
Stmt::With(ast::StmtWith { items, body, .. }) => {
|
||||||
for withitem in items {
|
for with_item in items {
|
||||||
visitor.visit_withitem(withitem);
|
visitor.visit_with_item(with_item);
|
||||||
}
|
}
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(body);
|
||||||
}
|
}
|
||||||
Stmt::AsyncWith(ast::StmtAsyncWith { items, body, .. }) => {
|
Stmt::AsyncWith(ast::StmtAsyncWith { items, body, .. }) => {
|
||||||
for withitem in items {
|
for with_item in items {
|
||||||
visitor.visit_withitem(withitem);
|
visitor.visit_with_item(with_item);
|
||||||
}
|
}
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(body);
|
||||||
}
|
}
|
||||||
|
@ -269,8 +272,8 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
|
||||||
range: _range,
|
range: _range,
|
||||||
}) => {
|
}) => {
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(body);
|
||||||
for excepthandler in handlers {
|
for except_handler in handlers {
|
||||||
visitor.visit_excepthandler(excepthandler);
|
visitor.visit_except_handler(except_handler);
|
||||||
}
|
}
|
||||||
visitor.visit_body(orelse);
|
visitor.visit_body(orelse);
|
||||||
visitor.visit_body(finalbody);
|
visitor.visit_body(finalbody);
|
||||||
|
@ -283,8 +286,8 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
|
||||||
range: _range,
|
range: _range,
|
||||||
}) => {
|
}) => {
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(body);
|
||||||
for excepthandler in handlers {
|
for except_handler in handlers {
|
||||||
visitor.visit_excepthandler(excepthandler);
|
visitor.visit_except_handler(except_handler);
|
||||||
}
|
}
|
||||||
visitor.visit_body(orelse);
|
visitor.visit_body(orelse);
|
||||||
visitor.visit_body(finalbody);
|
visitor.visit_body(finalbody);
|
||||||
|
@ -333,7 +336,7 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) {
|
||||||
values,
|
values,
|
||||||
range: _range,
|
range: _range,
|
||||||
}) => {
|
}) => {
|
||||||
visitor.visit_boolop(op);
|
visitor.visit_bool_op(op);
|
||||||
for expr in values {
|
for expr in values {
|
||||||
visitor.visit_expr(expr);
|
visitor.visit_expr(expr);
|
||||||
}
|
}
|
||||||
|
@ -361,7 +364,7 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) {
|
||||||
operand,
|
operand,
|
||||||
range: _range,
|
range: _range,
|
||||||
}) => {
|
}) => {
|
||||||
visitor.visit_unaryop(op);
|
visitor.visit_unary_op(op);
|
||||||
visitor.visit_expr(operand);
|
visitor.visit_expr(operand);
|
||||||
}
|
}
|
||||||
Expr::Lambda(ast::ExprLambda {
|
Expr::Lambda(ast::ExprLambda {
|
||||||
|
@ -467,8 +470,8 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) {
|
||||||
range: _range,
|
range: _range,
|
||||||
}) => {
|
}) => {
|
||||||
visitor.visit_expr(left);
|
visitor.visit_expr(left);
|
||||||
for cmpop in ops {
|
for cmp_op in ops {
|
||||||
visitor.visit_cmpop(cmpop);
|
visitor.visit_cmp_op(cmp_op);
|
||||||
}
|
}
|
||||||
for expr in comparators {
|
for expr in comparators {
|
||||||
visitor.visit_expr(expr);
|
visitor.visit_expr(expr);
|
||||||
|
@ -588,12 +591,12 @@ pub fn walk_comprehension<'a, V: Visitor<'a> + ?Sized>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_excepthandler<'a, V: Visitor<'a> + ?Sized>(
|
pub fn walk_except_handler<'a, V: Visitor<'a> + ?Sized>(
|
||||||
visitor: &mut V,
|
visitor: &mut V,
|
||||||
excepthandler: &'a Excepthandler,
|
except_handler: &'a ExceptHandler,
|
||||||
) {
|
) {
|
||||||
match excepthandler {
|
match except_handler {
|
||||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, body, .. }) => {
|
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, body, .. }) => {
|
||||||
if let Some(expr) = type_ {
|
if let Some(expr) = type_ {
|
||||||
visitor.visit_expr(expr);
|
visitor.visit_expr(expr);
|
||||||
}
|
}
|
||||||
|
@ -604,26 +607,20 @@ pub fn walk_excepthandler<'a, V: Visitor<'a> + ?Sized>(
|
||||||
|
|
||||||
pub fn walk_arguments<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, arguments: &'a Arguments) {
|
pub fn walk_arguments<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, arguments: &'a Arguments) {
|
||||||
for arg in &arguments.posonlyargs {
|
for arg in &arguments.posonlyargs {
|
||||||
visitor.visit_arg(arg);
|
visitor.visit_arg_with_default(arg);
|
||||||
}
|
}
|
||||||
for arg in &arguments.args {
|
for arg in &arguments.args {
|
||||||
visitor.visit_arg(arg);
|
visitor.visit_arg_with_default(arg);
|
||||||
}
|
}
|
||||||
if let Some(arg) = &arguments.vararg {
|
if let Some(arg) = &arguments.vararg {
|
||||||
visitor.visit_arg(arg);
|
visitor.visit_arg(arg);
|
||||||
}
|
}
|
||||||
for arg in &arguments.kwonlyargs {
|
for arg in &arguments.kwonlyargs {
|
||||||
visitor.visit_arg(arg);
|
visitor.visit_arg_with_default(arg);
|
||||||
}
|
|
||||||
for expr in &arguments.kw_defaults {
|
|
||||||
visitor.visit_expr(expr);
|
|
||||||
}
|
}
|
||||||
if let Some(arg) = &arguments.kwarg {
|
if let Some(arg) = &arguments.kwarg {
|
||||||
visitor.visit_arg(arg);
|
visitor.visit_arg(arg);
|
||||||
}
|
}
|
||||||
for expr in &arguments.defaults {
|
|
||||||
visitor.visit_expr(expr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_arg<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, arg: &'a Arg) {
|
pub fn walk_arg<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, arg: &'a Arg) {
|
||||||
|
@ -632,13 +629,23 @@ pub fn walk_arg<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, arg: &'a Arg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn walk_arg_with_default<'a, V: Visitor<'a> + ?Sized>(
|
||||||
|
visitor: &mut V,
|
||||||
|
arg_with_default: &'a ArgWithDefault,
|
||||||
|
) {
|
||||||
|
visitor.visit_arg(&arg_with_default.def);
|
||||||
|
if let Some(expr) = &arg_with_default.default {
|
||||||
|
visitor.visit_expr(expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn walk_keyword<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, keyword: &'a Keyword) {
|
pub fn walk_keyword<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, keyword: &'a Keyword) {
|
||||||
visitor.visit_expr(&keyword.value);
|
visitor.visit_expr(&keyword.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_withitem<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, withitem: &'a Withitem) {
|
pub fn walk_with_item<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, with_item: &'a WithItem) {
|
||||||
visitor.visit_expr(&withitem.context_expr);
|
visitor.visit_expr(&with_item.context_expr);
|
||||||
if let Some(expr) = &withitem.optional_vars {
|
if let Some(expr) = &with_item.optional_vars {
|
||||||
visitor.visit_expr(expr);
|
visitor.visit_expr(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -719,16 +726,16 @@ pub fn walk_expr_context<'a, V: Visitor<'a> + ?Sized>(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub fn walk_boolop<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, boolop: &'a Boolop) {}
|
pub fn walk_bool_op<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, bool_op: &'a BoolOp) {}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub fn walk_operator<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, operator: &'a Operator) {}
|
pub fn walk_operator<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, operator: &'a Operator) {}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub fn walk_unaryop<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, unaryop: &'a Unaryop) {}
|
pub fn walk_unary_op<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, unary_op: &'a UnaryOp) {}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub fn walk_cmpop<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, cmpop: &'a Cmpop) {}
|
pub fn walk_cmp_op<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, cmp_op: &'a CmpOp) {}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub fn walk_alias<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, alias: &'a Alias) {}
|
pub fn walk_alias<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, alias: &'a Alias) {}
|
||||||
|
|
|
@ -26,28 +26,28 @@ pub trait PreorderVisitor<'a> {
|
||||||
walk_constant(self, constant);
|
walk_constant(self, constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_boolop(&mut self, boolop: &'a Boolop) {
|
fn visit_bool_op(&mut self, bool_op: &'a BoolOp) {
|
||||||
walk_boolop(self, boolop);
|
walk_bool_op(self, bool_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_operator(&mut self, operator: &'a Operator) {
|
fn visit_operator(&mut self, operator: &'a Operator) {
|
||||||
walk_operator(self, operator);
|
walk_operator(self, operator);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_unaryop(&mut self, unaryop: &'a Unaryop) {
|
fn visit_unary_op(&mut self, unary_op: &'a UnaryOp) {
|
||||||
walk_unaryop(self, unaryop);
|
walk_unary_op(self, unary_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_cmpop(&mut self, cmpop: &'a Cmpop) {
|
fn visit_cmp_op(&mut self, cmp_op: &'a CmpOp) {
|
||||||
walk_cmpop(self, cmpop);
|
walk_cmp_op(self, cmp_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_comprehension(&mut self, comprehension: &'a Comprehension) {
|
fn visit_comprehension(&mut self, comprehension: &'a Comprehension) {
|
||||||
walk_comprehension(self, comprehension);
|
walk_comprehension(self, comprehension);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_excepthandler(&mut self, excepthandler: &'a Excepthandler) {
|
fn visit_except_handler(&mut self, except_handler: &'a ExceptHandler) {
|
||||||
walk_excepthandler(self, excepthandler);
|
walk_except_handler(self, except_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_format_spec(&mut self, format_spec: &'a Expr) {
|
fn visit_format_spec(&mut self, format_spec: &'a Expr) {
|
||||||
|
@ -62,6 +62,10 @@ pub trait PreorderVisitor<'a> {
|
||||||
walk_arg(self, arg);
|
walk_arg(self, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_arg_with_default(&mut self, arg_with_default: &'a ArgWithDefault) {
|
||||||
|
walk_arg_with_default(self, arg_with_default);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_keyword(&mut self, keyword: &'a Keyword) {
|
fn visit_keyword(&mut self, keyword: &'a Keyword) {
|
||||||
walk_keyword(self, keyword);
|
walk_keyword(self, keyword);
|
||||||
}
|
}
|
||||||
|
@ -70,8 +74,8 @@ pub trait PreorderVisitor<'a> {
|
||||||
walk_alias(self, alias);
|
walk_alias(self, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_withitem(&mut self, withitem: &'a Withitem) {
|
fn visit_with_item(&mut self, with_item: &'a WithItem) {
|
||||||
walk_withitem(self, withitem);
|
walk_with_item(self, with_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_match_case(&mut self, match_case: &'a MatchCase) {
|
fn visit_match_case(&mut self, match_case: &'a MatchCase) {
|
||||||
|
@ -300,8 +304,8 @@ where
|
||||||
type_comment: _,
|
type_comment: _,
|
||||||
range: _,
|
range: _,
|
||||||
}) => {
|
}) => {
|
||||||
for withitem in items {
|
for with_item in items {
|
||||||
visitor.visit_withitem(withitem);
|
visitor.visit_with_item(with_item);
|
||||||
}
|
}
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(body);
|
||||||
}
|
}
|
||||||
|
@ -345,8 +349,8 @@ where
|
||||||
range: _range,
|
range: _range,
|
||||||
}) => {
|
}) => {
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(body);
|
||||||
for excepthandler in handlers {
|
for except_handler in handlers {
|
||||||
visitor.visit_excepthandler(excepthandler);
|
visitor.visit_except_handler(except_handler);
|
||||||
}
|
}
|
||||||
visitor.visit_body(orelse);
|
visitor.visit_body(orelse);
|
||||||
visitor.visit_body(finalbody);
|
visitor.visit_body(finalbody);
|
||||||
|
@ -410,13 +414,13 @@ where
|
||||||
}) => match values.as_slice() {
|
}) => match values.as_slice() {
|
||||||
[left, rest @ ..] => {
|
[left, rest @ ..] => {
|
||||||
visitor.visit_expr(left);
|
visitor.visit_expr(left);
|
||||||
visitor.visit_boolop(op);
|
visitor.visit_bool_op(op);
|
||||||
for expr in rest {
|
for expr in rest {
|
||||||
visitor.visit_expr(expr);
|
visitor.visit_expr(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[] => {
|
[] => {
|
||||||
visitor.visit_boolop(op);
|
visitor.visit_bool_op(op);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -445,7 +449,7 @@ where
|
||||||
operand,
|
operand,
|
||||||
range: _range,
|
range: _range,
|
||||||
}) => {
|
}) => {
|
||||||
visitor.visit_unaryop(op);
|
visitor.visit_unary_op(op);
|
||||||
visitor.visit_expr(operand);
|
visitor.visit_expr(operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,7 +569,7 @@ where
|
||||||
visitor.visit_expr(left);
|
visitor.visit_expr(left);
|
||||||
|
|
||||||
for (op, comparator) in ops.iter().zip(comparators) {
|
for (op, comparator) in ops.iter().zip(comparators) {
|
||||||
visitor.visit_cmpop(op);
|
visitor.visit_cmp_op(op);
|
||||||
visitor.visit_expr(comparator);
|
visitor.visit_expr(comparator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -703,12 +707,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_excepthandler<'a, V>(visitor: &mut V, excepthandler: &'a Excepthandler)
|
pub fn walk_except_handler<'a, V>(visitor: &mut V, except_handler: &'a ExceptHandler)
|
||||||
where
|
where
|
||||||
V: PreorderVisitor<'a> + ?Sized,
|
V: PreorderVisitor<'a> + ?Sized,
|
||||||
{
|
{
|
||||||
match excepthandler {
|
match except_handler {
|
||||||
Excepthandler::ExceptHandler(ExcepthandlerExceptHandler {
|
ExceptHandler::ExceptHandler(ExceptHandlerExceptHandler {
|
||||||
range: _,
|
range: _,
|
||||||
type_,
|
type_,
|
||||||
name: _,
|
name: _,
|
||||||
|
@ -726,34 +730,16 @@ pub fn walk_arguments<'a, V>(visitor: &mut V, arguments: &'a Arguments)
|
||||||
where
|
where
|
||||||
V: PreorderVisitor<'a> + ?Sized,
|
V: PreorderVisitor<'a> + ?Sized,
|
||||||
{
|
{
|
||||||
let non_default_args_len =
|
for arg in arguments.posonlyargs.iter().chain(&arguments.args) {
|
||||||
arguments.posonlyargs.len() + arguments.args.len() - arguments.defaults.len();
|
visitor.visit_arg_with_default(arg);
|
||||||
|
|
||||||
let mut args_iter = arguments.posonlyargs.iter().chain(&arguments.args);
|
|
||||||
|
|
||||||
for _ in 0..non_default_args_len {
|
|
||||||
visitor.visit_arg(args_iter.next().unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (arg, default) in args_iter.zip(&arguments.defaults) {
|
|
||||||
visitor.visit_arg(arg);
|
|
||||||
visitor.visit_expr(default);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(arg) = &arguments.vararg {
|
if let Some(arg) = &arguments.vararg {
|
||||||
visitor.visit_arg(arg);
|
visitor.visit_arg(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
let non_default_kwargs_len = arguments.kwonlyargs.len() - arguments.kw_defaults.len();
|
for arg in &arguments.kwonlyargs {
|
||||||
let mut kwargsonly_iter = arguments.kwonlyargs.iter();
|
visitor.visit_arg_with_default(arg);
|
||||||
|
|
||||||
for _ in 0..non_default_kwargs_len {
|
|
||||||
visitor.visit_arg(kwargsonly_iter.next().unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (arg, default) in kwargsonly_iter.zip(&arguments.kw_defaults) {
|
|
||||||
visitor.visit_arg(arg);
|
|
||||||
visitor.visit_expr(default);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(arg) = &arguments.kwarg {
|
if let Some(arg) = &arguments.kwarg {
|
||||||
|
@ -770,6 +756,16 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn walk_arg_with_default<'a, V>(visitor: &mut V, arg_with_default: &'a ArgWithDefault)
|
||||||
|
where
|
||||||
|
V: PreorderVisitor<'a> + ?Sized,
|
||||||
|
{
|
||||||
|
visitor.visit_arg(&arg_with_default.def);
|
||||||
|
if let Some(expr) = &arg_with_default.default {
|
||||||
|
visitor.visit_expr(expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn walk_keyword<'a, V>(visitor: &mut V, keyword: &'a Keyword)
|
pub fn walk_keyword<'a, V>(visitor: &mut V, keyword: &'a Keyword)
|
||||||
where
|
where
|
||||||
|
@ -778,13 +774,13 @@ where
|
||||||
visitor.visit_expr(&keyword.value);
|
visitor.visit_expr(&keyword.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_withitem<'a, V>(visitor: &mut V, withitem: &'a Withitem)
|
pub fn walk_with_item<'a, V>(visitor: &mut V, with_item: &'a WithItem)
|
||||||
where
|
where
|
||||||
V: PreorderVisitor<'a> + ?Sized,
|
V: PreorderVisitor<'a> + ?Sized,
|
||||||
{
|
{
|
||||||
visitor.visit_expr(&withitem.context_expr);
|
visitor.visit_expr(&with_item.context_expr);
|
||||||
|
|
||||||
if let Some(expr) = &withitem.optional_vars {
|
if let Some(expr) = &with_item.optional_vars {
|
||||||
visitor.visit_expr(expr);
|
visitor.visit_expr(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -885,7 +881,7 @@ where
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_boolop<'a, V>(_visitor: &mut V, _boolop: &'a Boolop)
|
pub fn walk_bool_op<'a, V>(_visitor: &mut V, _bool_op: &'a BoolOp)
|
||||||
where
|
where
|
||||||
V: PreorderVisitor<'a> + ?Sized,
|
V: PreorderVisitor<'a> + ?Sized,
|
||||||
{
|
{
|
||||||
|
@ -899,14 +895,14 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn walk_unaryop<'a, V>(_visitor: &mut V, _unaryop: &'a Unaryop)
|
pub fn walk_unary_op<'a, V>(_visitor: &mut V, _unary_op: &'a UnaryOp)
|
||||||
where
|
where
|
||||||
V: PreorderVisitor<'a> + ?Sized,
|
V: PreorderVisitor<'a> + ?Sized,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn walk_cmpop<'a, V>(_visitor: &mut V, _cmpop: &'a Cmpop)
|
pub fn walk_cmp_op<'a, V>(_visitor: &mut V, _cmp_op: &'a CmpOp)
|
||||||
where
|
where
|
||||||
V: PreorderVisitor<'a> + ?Sized,
|
V: PreorderVisitor<'a> + ?Sized,
|
||||||
{
|
{
|
||||||
|
@ -923,11 +919,11 @@ where
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::node::AnyNodeRef;
|
use crate::node::AnyNodeRef;
|
||||||
use crate::visitor::preorder::{
|
use crate::visitor::preorder::{
|
||||||
walk_alias, walk_arg, walk_arguments, walk_comprehension, walk_excepthandler, walk_expr,
|
walk_alias, walk_arg, walk_arguments, walk_comprehension, walk_except_handler, walk_expr,
|
||||||
walk_keyword, walk_match_case, walk_module, walk_pattern, walk_stmt, walk_type_ignore,
|
walk_keyword, walk_match_case, walk_module, walk_pattern, walk_stmt, walk_type_ignore,
|
||||||
walk_withitem, Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant,
|
walk_with_item, Alias, Arg, Arguments, BoolOp, CmpOp, Comprehension, Constant,
|
||||||
Excepthandler, Expr, Keyword, MatchCase, Mod, Operator, Pattern, PreorderVisitor, Stmt,
|
ExceptHandler, Expr, Keyword, MatchCase, Mod, Operator, Pattern, PreorderVisitor, Stmt,
|
||||||
String, TypeIgnore, Unaryop, Withitem,
|
String, TypeIgnore, UnaryOp, WithItem,
|
||||||
};
|
};
|
||||||
use insta::assert_snapshot;
|
use insta::assert_snapshot;
|
||||||
use rustpython_parser::lexer::lex;
|
use rustpython_parser::lexer::lex;
|
||||||
|
@ -1089,20 +1085,20 @@ class A:
|
||||||
self.emit(&constant);
|
self.emit(&constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_boolop(&mut self, boolop: &Boolop) {
|
fn visit_bool_op(&mut self, bool_op: &BoolOp) {
|
||||||
self.emit(&boolop);
|
self.emit(&bool_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_operator(&mut self, operator: &Operator) {
|
fn visit_operator(&mut self, operator: &Operator) {
|
||||||
self.emit(&operator);
|
self.emit(&operator);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_unaryop(&mut self, unaryop: &Unaryop) {
|
fn visit_unary_op(&mut self, unary_op: &UnaryOp) {
|
||||||
self.emit(&unaryop);
|
self.emit(&unary_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_cmpop(&mut self, cmpop: &Cmpop) {
|
fn visit_cmp_op(&mut self, cmp_op: &CmpOp) {
|
||||||
self.emit(&cmpop);
|
self.emit(&cmp_op);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_comprehension(&mut self, comprehension: &Comprehension) {
|
fn visit_comprehension(&mut self, comprehension: &Comprehension) {
|
||||||
|
@ -1111,9 +1107,9 @@ class A:
|
||||||
self.exit_node();
|
self.exit_node();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_excepthandler(&mut self, excepthandler: &Excepthandler) {
|
fn visit_except_handler(&mut self, except_handler: &ExceptHandler) {
|
||||||
self.enter_node(excepthandler);
|
self.enter_node(except_handler);
|
||||||
walk_excepthandler(self, excepthandler);
|
walk_except_handler(self, except_handler);
|
||||||
self.exit_node();
|
self.exit_node();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1147,9 +1143,9 @@ class A:
|
||||||
self.exit_node();
|
self.exit_node();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_withitem(&mut self, withitem: &Withitem) {
|
fn visit_with_item(&mut self, with_item: &WithItem) {
|
||||||
self.enter_node(withitem);
|
self.enter_node(with_item);
|
||||||
walk_withitem(self, withitem);
|
walk_with_item(self, with_item);
|
||||||
self.exit_node();
|
self.exit_node();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,21 +14,21 @@ pub(super) fn place_comment<'a>(
|
||||||
comment: DecoratedComment<'a>,
|
comment: DecoratedComment<'a>,
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
) -> CommentPlacement<'a> {
|
) -> CommentPlacement<'a> {
|
||||||
handle_in_between_excepthandlers_or_except_handler_and_else_or_finally_comment(comment, locator)
|
handle_in_between_except_handlers_or_except_handler_and_else_or_finally_comment(
|
||||||
.or_else(|comment| handle_match_comment(comment, locator))
|
comment, locator,
|
||||||
.or_else(|comment| handle_in_between_bodies_own_line_comment(comment, locator))
|
)
|
||||||
.or_else(|comment| handle_in_between_bodies_end_of_line_comment(comment, locator))
|
.or_else(|comment| handle_match_comment(comment, locator))
|
||||||
.or_else(|comment| handle_trailing_body_comment(comment, locator))
|
.or_else(|comment| handle_in_between_bodies_own_line_comment(comment, locator))
|
||||||
.or_else(handle_trailing_end_of_line_body_comment)
|
.or_else(|comment| handle_in_between_bodies_end_of_line_comment(comment, locator))
|
||||||
.or_else(|comment| handle_trailing_end_of_line_condition_comment(comment, locator))
|
.or_else(|comment| handle_trailing_body_comment(comment, locator))
|
||||||
.or_else(|comment| {
|
.or_else(handle_trailing_end_of_line_body_comment)
|
||||||
handle_module_level_own_line_comment_before_class_or_function_comment(comment, locator)
|
.or_else(|comment| handle_trailing_end_of_line_condition_comment(comment, locator))
|
||||||
})
|
.or_else(|comment| {
|
||||||
.or_else(|comment| handle_positional_only_arguments_separator_comment(comment, locator))
|
handle_module_level_own_line_comment_before_class_or_function_comment(comment, locator)
|
||||||
.or_else(|comment| {
|
})
|
||||||
handle_trailing_binary_expression_left_or_operator_comment(comment, locator)
|
.or_else(|comment| handle_positional_only_arguments_separator_comment(comment, locator))
|
||||||
})
|
.or_else(|comment| handle_trailing_binary_expression_left_or_operator_comment(comment, locator))
|
||||||
.or_else(handle_leading_function_with_decorators_comment)
|
.or_else(handle_leading_function_with_decorators_comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles leading comments in front of a match case or a trailing comment of the `match` statement.
|
/// Handles leading comments in front of a match case or a trailing comment of the `match` statement.
|
||||||
|
@ -138,8 +138,8 @@ fn handle_match_comment<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles comments between excepthandlers and between the last except handler and any following `else` or `finally` block.
|
/// Handles comments between except handlers and between the last except handler and any following `else` or `finally` block.
|
||||||
fn handle_in_between_excepthandlers_or_except_handler_and_else_or_finally_comment<'a>(
|
fn handle_in_between_except_handlers_or_except_handler_and_else_or_finally_comment<'a>(
|
||||||
comment: DecoratedComment<'a>,
|
comment: DecoratedComment<'a>,
|
||||||
locator: &Locator,
|
locator: &Locator,
|
||||||
) -> CommentPlacement<'a> {
|
) -> CommentPlacement<'a> {
|
||||||
|
@ -147,7 +147,7 @@ fn handle_in_between_excepthandlers_or_except_handler_and_else_or_finally_commen
|
||||||
return CommentPlacement::Default(comment);
|
return CommentPlacement::Default(comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(AnyNodeRef::ExcepthandlerExceptHandler(except_handler)) = comment.preceding_node() {
|
if let Some(AnyNodeRef::ExceptHandlerExceptHandler(except_handler)) = comment.preceding_node() {
|
||||||
// it now depends on the indentation level of the comment if it is a leading comment for e.g.
|
// it now depends on the indentation level of the comment if it is a leading comment for e.g.
|
||||||
// the following `elif` or indeed a trailing comment of the previous body's last statement.
|
// the following `elif` or indeed a trailing comment of the previous body's last statement.
|
||||||
let comment_indentation =
|
let comment_indentation =
|
||||||
|
@ -627,11 +627,8 @@ fn handle_positional_only_arguments_separator_comment<'a>(
|
||||||
// ```python
|
// ```python
|
||||||
// def test(a=10, /, b): pass
|
// def test(a=10, /, b): pass
|
||||||
// ```
|
// ```
|
||||||
|| arguments
|
|| are_same_optional(last_argument_or_default, arguments
|
||||||
.defaults
|
.posonlyargs.last().and_then(|arg| arg.default.as_deref()));
|
||||||
.iter()
|
|
||||||
.position(|default| AnyNodeRef::from(default).ptr_eq(last_argument_or_default))
|
|
||||||
== Some(arguments.posonlyargs.len().saturating_sub(1));
|
|
||||||
|
|
||||||
if !is_last_positional_argument {
|
if !is_last_positional_argument {
|
||||||
return CommentPlacement::Default(comment);
|
return CommentPlacement::Default(comment);
|
||||||
|
@ -906,7 +903,7 @@ fn last_child_in_body(node: AnyNodeRef) -> Option<AnyNodeRef> {
|
||||||
| AnyNodeRef::StmtWith(StmtWith { body, .. })
|
| AnyNodeRef::StmtWith(StmtWith { body, .. })
|
||||||
| AnyNodeRef::StmtAsyncWith(StmtAsyncWith { body, .. })
|
| AnyNodeRef::StmtAsyncWith(StmtAsyncWith { body, .. })
|
||||||
| AnyNodeRef::MatchCase(MatchCase { body, .. })
|
| AnyNodeRef::MatchCase(MatchCase { body, .. })
|
||||||
| AnyNodeRef::ExcepthandlerExceptHandler(ExcepthandlerExceptHandler { body, .. }) => body,
|
| AnyNodeRef::ExceptHandlerExceptHandler(ExceptHandlerExceptHandler { body, .. }) => body,
|
||||||
|
|
||||||
AnyNodeRef::StmtIf(StmtIf { body, orelse, .. })
|
AnyNodeRef::StmtIf(StmtIf { body, orelse, .. })
|
||||||
| AnyNodeRef::StmtFor(StmtFor { body, orelse, .. })
|
| AnyNodeRef::StmtFor(StmtFor { body, orelse, .. })
|
||||||
|
@ -988,7 +985,7 @@ fn is_first_statement_in_enclosing_alternate_body(
|
||||||
}) => {
|
}) => {
|
||||||
are_same_optional(following, handlers.first())
|
are_same_optional(following, handlers.first())
|
||||||
// Comments between the handlers and the `else`, or comments between the `handlers` and the `finally`
|
// Comments between the handlers and the `else`, or comments between the `handlers` and the `finally`
|
||||||
// are already handled by `handle_in_between_excepthandlers_or_except_handler_and_else_or_finally_comment`
|
// are already handled by `handle_in_between_except_handlers_or_except_handler_and_else_or_finally_comment`
|
||||||
|| handlers.is_empty() && are_same_optional(following, orelse.first())
|
|| handlers.is_empty() && are_same_optional(following, orelse.first())
|
||||||
|| (handlers.is_empty() || !orelse.is_empty())
|
|| (handlers.is_empty() || !orelse.is_empty())
|
||||||
&& are_same_optional(following, finalbody.first())
|
&& are_same_optional(following, finalbody.first())
|
||||||
|
|
|
@ -34,7 +34,7 @@ expression: comments.debug(test_case.source_code)
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
Node {
|
Node {
|
||||||
kind: ExcepthandlerExceptHandler,
|
kind: ExceptHandlerExceptHandler,
|
||||||
range: 100..136,
|
range: 100..136,
|
||||||
source: `except Exception as ex:⏎`,
|
source: `except Exception as ex:⏎`,
|
||||||
}: {
|
}: {
|
||||||
|
|
|
@ -39,7 +39,7 @@ expression: comments.debug(test_case.source_code)
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
Node {
|
Node {
|
||||||
kind: ExcepthandlerExceptHandler,
|
kind: ExceptHandlerExceptHandler,
|
||||||
range: 68..100,
|
range: 68..100,
|
||||||
source: `except Exception as ex:⏎`,
|
source: `except Exception as ex:⏎`,
|
||||||
}: {
|
}: {
|
||||||
|
|
|
@ -208,11 +208,11 @@ impl<'ast> PreorderVisitor<'ast> for CommentsVisitor<'ast> {
|
||||||
self.finish_node(comprehension);
|
self.finish_node(comprehension);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_excepthandler(&mut self, excepthandler: &'ast Excepthandler) {
|
fn visit_except_handler(&mut self, except_handler: &'ast ExceptHandler) {
|
||||||
if self.start_node(excepthandler).is_traverse() {
|
if self.start_node(except_handler).is_traverse() {
|
||||||
walk_excepthandler(self, excepthandler);
|
walk_except_handler(self, except_handler);
|
||||||
}
|
}
|
||||||
self.finish_node(excepthandler);
|
self.finish_node(except_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_format_spec(&mut self, format_spec: &'ast Expr) {
|
fn visit_format_spec(&mut self, format_spec: &'ast Expr) {
|
||||||
|
@ -250,12 +250,12 @@ impl<'ast> PreorderVisitor<'ast> for CommentsVisitor<'ast> {
|
||||||
self.finish_node(alias);
|
self.finish_node(alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_withitem(&mut self, withitem: &'ast Withitem) {
|
fn visit_with_item(&mut self, with_item: &'ast WithItem) {
|
||||||
if self.start_node(withitem).is_traverse() {
|
if self.start_node(with_item).is_traverse() {
|
||||||
walk_withitem(self, withitem);
|
walk_with_item(self, with_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.finish_node(withitem);
|
self.finish_node(with_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_match_case(&mut self, match_case: &'ast MatchCase) {
|
fn visit_match_case(&mut self, match_case: &'ast MatchCase) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use ruff_formatter::{
|
||||||
};
|
};
|
||||||
use ruff_python_ast::node::AstNode;
|
use ruff_python_ast::node::AstNode;
|
||||||
use rustpython_parser::ast::{
|
use rustpython_parser::ast::{
|
||||||
Constant, Expr, ExprAttribute, ExprBinOp, ExprConstant, ExprUnaryOp, Operator, Unaryop,
|
Constant, Expr, ExprAttribute, ExprBinOp, ExprConstant, ExprUnaryOp, Operator, UnaryOp,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -116,7 +116,7 @@ const fn is_simple_power_expression(expr: &ExprBinOp) -> bool {
|
||||||
const fn is_simple_power_operand(expr: &Expr) -> bool {
|
const fn is_simple_power_operand(expr: &Expr) -> bool {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::UnaryOp(ExprUnaryOp {
|
Expr::UnaryOp(ExprUnaryOp {
|
||||||
op: Unaryop::Not, ..
|
op: UnaryOp::Not, ..
|
||||||
}) => false,
|
}) => false,
|
||||||
Expr::Constant(ExprConstant {
|
Expr::Constant(ExprConstant {
|
||||||
value: Constant::Complex { .. } | Constant::Float(_) | Constant::Int(_),
|
value: Constant::Complex { .. } | Constant::Float(_) | Constant::Int(_),
|
||||||
|
|
|
@ -2253,42 +2253,44 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::ExprSlice {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatRule<ast::ExcepthandlerExceptHandler, PyFormatContext<'_>>
|
impl FormatRule<ast::ExceptHandlerExceptHandler, PyFormatContext<'_>>
|
||||||
for crate::other::excepthandler_except_handler::FormatExcepthandlerExceptHandler
|
for crate::other::except_handler_except_handler::FormatExceptHandlerExceptHandler
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt(
|
fn fmt(
|
||||||
&self,
|
&self,
|
||||||
node: &ast::ExcepthandlerExceptHandler,
|
node: &ast::ExceptHandlerExceptHandler,
|
||||||
f: &mut Formatter<PyFormatContext<'_>>,
|
f: &mut Formatter<PyFormatContext<'_>>,
|
||||||
) -> FormatResult<()> {
|
) -> FormatResult<()> {
|
||||||
FormatNodeRule::<ast::ExcepthandlerExceptHandler>::fmt(self, node, f)
|
FormatNodeRule::<ast::ExceptHandlerExceptHandler>::fmt(self, node, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::ExcepthandlerExceptHandler {
|
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::ExceptHandlerExceptHandler {
|
||||||
type Format<'a> = FormatRefWithRule<
|
type Format<'a> = FormatRefWithRule<
|
||||||
'a,
|
'a,
|
||||||
ast::ExcepthandlerExceptHandler,
|
ast::ExceptHandlerExceptHandler,
|
||||||
crate::other::excepthandler_except_handler::FormatExcepthandlerExceptHandler,
|
crate::other::except_handler_except_handler::FormatExceptHandlerExceptHandler,
|
||||||
PyFormatContext<'ast>,
|
PyFormatContext<'ast>,
|
||||||
>;
|
>;
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
FormatRefWithRule::new(
|
FormatRefWithRule::new(
|
||||||
self,
|
self,
|
||||||
crate::other::excepthandler_except_handler::FormatExcepthandlerExceptHandler::default(),
|
crate::other::except_handler_except_handler::FormatExceptHandlerExceptHandler::default(
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::ExcepthandlerExceptHandler {
|
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::ExceptHandlerExceptHandler {
|
||||||
type Format = FormatOwnedWithRule<
|
type Format = FormatOwnedWithRule<
|
||||||
ast::ExcepthandlerExceptHandler,
|
ast::ExceptHandlerExceptHandler,
|
||||||
crate::other::excepthandler_except_handler::FormatExcepthandlerExceptHandler,
|
crate::other::except_handler_except_handler::FormatExceptHandlerExceptHandler,
|
||||||
PyFormatContext<'ast>,
|
PyFormatContext<'ast>,
|
||||||
>;
|
>;
|
||||||
fn into_format(self) -> Self::Format {
|
fn into_format(self) -> Self::Format {
|
||||||
FormatOwnedWithRule::new(
|
FormatOwnedWithRule::new(
|
||||||
self,
|
self,
|
||||||
crate::other::excepthandler_except_handler::FormatExcepthandlerExceptHandler::default(),
|
crate::other::except_handler_except_handler::FormatExceptHandlerExceptHandler::default(
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2746,6 +2748,46 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::Arg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FormatRule<ast::ArgWithDefault, PyFormatContext<'_>>
|
||||||
|
for crate::other::arg_with_default::FormatArgWithDefault
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn fmt(
|
||||||
|
&self,
|
||||||
|
node: &ast::ArgWithDefault,
|
||||||
|
f: &mut Formatter<PyFormatContext<'_>>,
|
||||||
|
) -> FormatResult<()> {
|
||||||
|
FormatNodeRule::<ast::ArgWithDefault>::fmt(self, node, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::ArgWithDefault {
|
||||||
|
type Format<'a> = FormatRefWithRule<
|
||||||
|
'a,
|
||||||
|
ast::ArgWithDefault,
|
||||||
|
crate::other::arg_with_default::FormatArgWithDefault,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
FormatRefWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::other::arg_with_default::FormatArgWithDefault::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::ArgWithDefault {
|
||||||
|
type Format = FormatOwnedWithRule<
|
||||||
|
ast::ArgWithDefault,
|
||||||
|
crate::other::arg_with_default::FormatArgWithDefault,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn into_format(self) -> Self::Format {
|
||||||
|
FormatOwnedWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::other::arg_with_default::FormatArgWithDefault::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FormatRule<ast::Keyword, PyFormatContext<'_>> for crate::other::keyword::FormatKeyword {
|
impl FormatRule<ast::Keyword, PyFormatContext<'_>> for crate::other::keyword::FormatKeyword {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt(&self, node: &ast::Keyword, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
|
fn fmt(&self, node: &ast::Keyword, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
|
||||||
|
@ -2795,35 +2837,35 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::Alias {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatRule<ast::Withitem, PyFormatContext<'_>> for crate::other::withitem::FormatWithitem {
|
impl FormatRule<ast::WithItem, PyFormatContext<'_>> for crate::other::with_item::FormatWithItem {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt(
|
fn fmt(
|
||||||
&self,
|
&self,
|
||||||
node: &ast::Withitem,
|
node: &ast::WithItem,
|
||||||
f: &mut Formatter<PyFormatContext<'_>>,
|
f: &mut Formatter<PyFormatContext<'_>>,
|
||||||
) -> FormatResult<()> {
|
) -> FormatResult<()> {
|
||||||
FormatNodeRule::<ast::Withitem>::fmt(self, node, f)
|
FormatNodeRule::<ast::WithItem>::fmt(self, node, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::Withitem {
|
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::WithItem {
|
||||||
type Format<'a> = FormatRefWithRule<
|
type Format<'a> = FormatRefWithRule<
|
||||||
'a,
|
'a,
|
||||||
ast::Withitem,
|
ast::WithItem,
|
||||||
crate::other::withitem::FormatWithitem,
|
crate::other::with_item::FormatWithItem,
|
||||||
PyFormatContext<'ast>,
|
PyFormatContext<'ast>,
|
||||||
>;
|
>;
|
||||||
fn format(&self) -> Self::Format<'_> {
|
fn format(&self) -> Self::Format<'_> {
|
||||||
FormatRefWithRule::new(self, crate::other::withitem::FormatWithitem::default())
|
FormatRefWithRule::new(self, crate::other::with_item::FormatWithItem::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::Withitem {
|
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::WithItem {
|
||||||
type Format = FormatOwnedWithRule<
|
type Format = FormatOwnedWithRule<
|
||||||
ast::Withitem,
|
ast::WithItem,
|
||||||
crate::other::withitem::FormatWithitem,
|
crate::other::with_item::FormatWithItem,
|
||||||
PyFormatContext<'ast>,
|
PyFormatContext<'ast>,
|
||||||
>;
|
>;
|
||||||
fn into_format(self) -> Self::Format {
|
fn into_format(self) -> Self::Format {
|
||||||
FormatOwnedWithRule::new(self, crate::other::withitem::FormatWithitem::default())
|
FormatOwnedWithRule::new(self, crate::other::with_item::FormatWithItem::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
crates/ruff_python_formatter/src/other/arg_with_default.rs
Normal file
28
crates/ruff_python_formatter/src/other/arg_with_default.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
use rustpython_parser::ast::ArgWithDefault;
|
||||||
|
|
||||||
|
use ruff_formatter::write;
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
use crate::FormatNodeRule;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct FormatArgWithDefault;
|
||||||
|
|
||||||
|
impl FormatNodeRule<ArgWithDefault> for FormatArgWithDefault {
|
||||||
|
fn fmt_fields(&self, item: &ArgWithDefault, f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
|
let ArgWithDefault {
|
||||||
|
range: _,
|
||||||
|
def,
|
||||||
|
default,
|
||||||
|
} = item;
|
||||||
|
|
||||||
|
write!(f, [def.format()])?;
|
||||||
|
|
||||||
|
if let Some(default) = default {
|
||||||
|
let space = def.annotation.is_some().then_some(space());
|
||||||
|
write!(f, [space, text("="), space, default.format()])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,15 @@
|
||||||
|
use std::usize;
|
||||||
|
|
||||||
|
use rustpython_parser::ast::{Arguments, Ranged};
|
||||||
|
|
||||||
|
use ruff_formatter::{format_args, write};
|
||||||
|
use ruff_python_ast::node::{AnyNodeRef, AstNode};
|
||||||
|
|
||||||
use crate::comments::{dangling_node_comments, leading_node_comments};
|
use crate::comments::{dangling_node_comments, leading_node_comments};
|
||||||
use crate::context::NodeLevel;
|
use crate::context::NodeLevel;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::trivia::{first_non_trivia_token, SimpleTokenizer, Token, TokenKind};
|
use crate::trivia::{first_non_trivia_token, SimpleTokenizer, Token, TokenKind};
|
||||||
use crate::FormatNodeRule;
|
use crate::FormatNodeRule;
|
||||||
use ruff_formatter::{format_args, write, FormatError};
|
|
||||||
use ruff_python_ast::node::{AnyNodeRef, AstNode};
|
|
||||||
use rustpython_parser::ast::{Arg, Arguments, Expr, Ranged};
|
|
||||||
use std::usize;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct FormatArguments;
|
pub struct FormatArguments;
|
||||||
|
@ -17,10 +20,8 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
||||||
range: _,
|
range: _,
|
||||||
posonlyargs,
|
posonlyargs,
|
||||||
args,
|
args,
|
||||||
defaults,
|
|
||||||
vararg,
|
vararg,
|
||||||
kwonlyargs,
|
kwonlyargs,
|
||||||
kw_defaults,
|
|
||||||
kwarg,
|
kwarg,
|
||||||
} = item;
|
} = item;
|
||||||
|
|
||||||
|
@ -32,30 +33,30 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
||||||
let mut joiner = f.join_with(separator);
|
let mut joiner = f.join_with(separator);
|
||||||
let mut last_node: Option<AnyNodeRef> = None;
|
let mut last_node: Option<AnyNodeRef> = None;
|
||||||
|
|
||||||
let mut defaults = std::iter::repeat(None)
|
for arg_with_default in posonlyargs {
|
||||||
.take(posonlyargs.len() + args.len() - defaults.len())
|
joiner.entry(&arg_with_default.into_format());
|
||||||
.chain(defaults.iter().map(Some));
|
|
||||||
|
|
||||||
for positional in posonlyargs {
|
last_node = Some(
|
||||||
let default = defaults.next().ok_or(FormatError::SyntaxError)?;
|
arg_with_default
|
||||||
joiner.entry(&ArgumentWithDefault {
|
.default
|
||||||
argument: positional,
|
.as_deref()
|
||||||
default,
|
.map_or_else(|| (&arg_with_default.def).into(), AnyNodeRef::from),
|
||||||
});
|
);
|
||||||
|
|
||||||
last_node = Some(default.map_or_else(|| positional.into(), AnyNodeRef::from));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !posonlyargs.is_empty() {
|
if !posonlyargs.is_empty() {
|
||||||
joiner.entry(&text("/"));
|
joiner.entry(&text("/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
for argument in args {
|
for arg_with_default in args {
|
||||||
let default = defaults.next().ok_or(FormatError::SyntaxError)?;
|
joiner.entry(&arg_with_default.into_format());
|
||||||
|
|
||||||
joiner.entry(&ArgumentWithDefault { argument, default });
|
last_node = Some(
|
||||||
|
arg_with_default
|
||||||
last_node = Some(default.map_or_else(|| argument.into(), AnyNodeRef::from));
|
.default
|
||||||
|
.as_deref()
|
||||||
|
.map_or_else(|| (&arg_with_default.def).into(), AnyNodeRef::from),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// kw only args need either a `*args` ahead of them capturing all var args or a `*`
|
// kw only args need either a `*args` ahead of them capturing all var args or a `*`
|
||||||
|
@ -72,24 +73,17 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
||||||
joiner.entry(&text("*"));
|
joiner.entry(&text("*"));
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert!(defaults.next().is_none());
|
for arg_with_default in kwonlyargs {
|
||||||
|
joiner.entry(&arg_with_default.into_format());
|
||||||
|
|
||||||
let mut defaults = std::iter::repeat(None)
|
last_node = Some(
|
||||||
.take(kwonlyargs.len() - kw_defaults.len())
|
arg_with_default
|
||||||
.chain(kw_defaults.iter().map(Some));
|
.default
|
||||||
|
.as_deref()
|
||||||
for keyword_argument in kwonlyargs {
|
.map_or_else(|| (&arg_with_default.def).into(), AnyNodeRef::from),
|
||||||
let default = defaults.next().ok_or(FormatError::SyntaxError)?;
|
);
|
||||||
joiner.entry(&ArgumentWithDefault {
|
|
||||||
argument: keyword_argument,
|
|
||||||
default,
|
|
||||||
});
|
|
||||||
|
|
||||||
last_node = Some(default.map_or_else(|| keyword_argument.into(), AnyNodeRef::from));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert!(defaults.next().is_none());
|
|
||||||
|
|
||||||
if let Some(kwarg) = kwarg {
|
if let Some(kwarg) = kwarg {
|
||||||
joiner.entry(&format_args![
|
joiner.entry(&format_args![
|
||||||
leading_node_comments(kwarg.as_ref()),
|
leading_node_comments(kwarg.as_ref()),
|
||||||
|
@ -173,21 +167,3 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ArgumentWithDefault<'a> {
|
|
||||||
argument: &'a Arg,
|
|
||||||
default: Option<&'a Expr>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Format<PyFormatContext<'_>> for ArgumentWithDefault<'_> {
|
|
||||||
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
|
|
||||||
write!(f, [self.argument.format()])?;
|
|
||||||
|
|
||||||
if let Some(default) = self.default {
|
|
||||||
let space = self.argument.annotation.is_some().then_some(space());
|
|
||||||
write!(f, [space, text("="), space, default.format()])?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||||
use ruff_formatter::{write, Buffer, FormatResult};
|
use ruff_formatter::{write, Buffer, FormatResult};
|
||||||
use rustpython_parser::ast::ExcepthandlerExceptHandler;
|
use rustpython_parser::ast::ExceptHandlerExceptHandler;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct FormatExcepthandlerExceptHandler;
|
pub struct FormatExceptHandlerExceptHandler;
|
||||||
|
|
||||||
impl FormatNodeRule<ExcepthandlerExceptHandler> for FormatExcepthandlerExceptHandler {
|
impl FormatNodeRule<ExceptHandlerExceptHandler> for FormatExceptHandlerExceptHandler {
|
||||||
fn fmt_fields(
|
fn fmt_fields(
|
||||||
&self,
|
&self,
|
||||||
item: &ExcepthandlerExceptHandler,
|
item: &ExceptHandlerExceptHandler,
|
||||||
f: &mut PyFormatter,
|
f: &mut PyFormatter,
|
||||||
) -> FormatResult<()> {
|
) -> FormatResult<()> {
|
||||||
write!(f, [not_yet_implemented(item)])
|
write!(f, [not_yet_implemented(item)])
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue