mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 10:48:32 +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
|
@ -1,7 +1,7 @@
|
|||
//! Interface for generating autofix edits from higher-level actions (e.g., "remove an argument").
|
||||
use anyhow::{bail, Result};
|
||||
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 ruff_diagnostics::Edit;
|
||||
|
@ -218,7 +218,7 @@ fn is_lone_child(child: &Stmt, parent: &Stmt) -> bool {
|
|||
|| is_only(orelse, child)
|
||||
|| is_only(finalbody, child)
|
||||
|| handlers.iter().any(|handler| match handler {
|
||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||
body, ..
|
||||
}) => is_only(body, child),
|
||||
})
|
||||
|
|
|
@ -5,8 +5,8 @@ use log::error;
|
|||
use ruff_text_size::{TextRange, TextSize};
|
||||
use rustpython_format::cformat::{CFormatError, CFormatErrorType};
|
||||
use rustpython_parser::ast::{
|
||||
self, Arg, Arguments, Comprehension, Constant, Excepthandler, Expr, ExprContext, Keyword,
|
||||
Operator, Pattern, Ranged, Stmt, Suite, Unaryop,
|
||||
self, Arg, ArgWithDefault, Arguments, Comprehension, Constant, ExceptHandler, Expr,
|
||||
ExprContext, Keyword, Operator, Pattern, Ranged, Stmt, Suite, UnaryOp,
|
||||
};
|
||||
|
||||
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::types::Node;
|
||||
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_semantic::analyze::{branch_detection, typing, visibility};
|
||||
use ruff_python_semantic::{
|
||||
|
@ -1759,22 +1759,21 @@ where
|
|||
// are enabled.
|
||||
let runtime_annotation = !self.semantic.future_annotations();
|
||||
|
||||
for arg in &args.posonlyargs {
|
||||
if let Some(expr) = &arg.annotation {
|
||||
for arg_with_default in args
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(&args.args)
|
||||
.chain(&args.kwonlyargs)
|
||||
{
|
||||
if let Some(expr) = &arg_with_default.def.annotation {
|
||||
if runtime_annotation {
|
||||
self.visit_type_definition(expr);
|
||||
} else {
|
||||
self.visit_annotation(expr);
|
||||
};
|
||||
}
|
||||
}
|
||||
for arg in &args.args {
|
||||
if let Some(expr) = &arg.annotation {
|
||||
if runtime_annotation {
|
||||
self.visit_type_definition(expr);
|
||||
} else {
|
||||
self.visit_annotation(expr);
|
||||
};
|
||||
if let Some(expr) = &arg_with_default.default {
|
||||
self.visit_expr(expr);
|
||||
}
|
||||
}
|
||||
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(expr) = &arg.annotation {
|
||||
if runtime_annotation {
|
||||
|
@ -1811,12 +1801,6 @@ where
|
|||
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(
|
||||
name,
|
||||
|
@ -1929,8 +1913,8 @@ where
|
|||
self.semantic.handled_exceptions.pop();
|
||||
|
||||
self.semantic.flags |= SemanticModelFlags::EXCEPTION_HANDLER;
|
||||
for excepthandler in handlers {
|
||||
self.visit_excepthandler(excepthandler);
|
||||
for except_handler in handlers {
|
||||
self.visit_except_handler(except_handler);
|
||||
}
|
||||
|
||||
self.visit_body(orelse);
|
||||
|
@ -2100,7 +2084,7 @@ where
|
|||
expr,
|
||||
Expr::BoolOp(_)
|
||||
| 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.
|
||||
for expr in &args.kw_defaults {
|
||||
self.visit_expr(expr);
|
||||
}
|
||||
for expr in &args.defaults {
|
||||
self.visit_expr(expr);
|
||||
for ArgWithDefault {
|
||||
default,
|
||||
def: _,
|
||||
range: _,
|
||||
} 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));
|
||||
}
|
||||
Expr::IfExp(ast::ExprIfExp {
|
||||
|
@ -3794,9 +3787,9 @@ where
|
|||
self.semantic.pop_expr();
|
||||
}
|
||||
|
||||
fn visit_excepthandler(&mut self, excepthandler: &'b Excepthandler) {
|
||||
match excepthandler {
|
||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
fn visit_except_handler(&mut self, except_handler: &'b ExceptHandler) {
|
||||
match except_handler {
|
||||
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||
type_,
|
||||
name,
|
||||
body,
|
||||
|
@ -3807,7 +3800,7 @@ where
|
|||
if let Some(diagnostic) = pycodestyle::rules::bare_except(
|
||||
type_.as_deref(),
|
||||
body,
|
||||
excepthandler,
|
||||
except_handler,
|
||||
self.locator,
|
||||
) {
|
||||
self.diagnostics.push(diagnostic);
|
||||
|
@ -3822,7 +3815,7 @@ where
|
|||
if self.enabled(Rule::TryExceptPass) {
|
||||
flake8_bandit::rules::try_except_pass(
|
||||
self,
|
||||
excepthandler,
|
||||
except_handler,
|
||||
type_.as_deref(),
|
||||
name,
|
||||
body,
|
||||
|
@ -3832,7 +3825,7 @@ where
|
|||
if self.enabled(Rule::TryExceptContinue) {
|
||||
flake8_bandit::rules::try_except_continue(
|
||||
self,
|
||||
excepthandler,
|
||||
except_handler,
|
||||
type_.as_deref(),
|
||||
name,
|
||||
body,
|
||||
|
@ -3840,20 +3833,20 @@ where
|
|||
);
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
tryceratops::rules::reraise_no_cause(self, body);
|
||||
}
|
||||
if self.enabled(Rule::BinaryOpException) {
|
||||
pylint::rules::binary_op_exception(self, excepthandler);
|
||||
pylint::rules::binary_op_exception(self, except_handler);
|
||||
}
|
||||
match 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 let Some(diagnostic) =
|
||||
|
@ -3866,7 +3859,7 @@ where
|
|||
flake8_builtins::rules::builtin_variable_shadowing(
|
||||
self,
|
||||
name,
|
||||
AnyShadowing::from(excepthandler),
|
||||
AnyShadowing::from(except_handler),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3878,7 +3871,7 @@ where
|
|||
BindingFlags::empty(),
|
||||
);
|
||||
|
||||
walk_excepthandler(self, excepthandler);
|
||||
walk_except_handler(self, except_handler);
|
||||
|
||||
// Remove it from the scope immediately after.
|
||||
self.add_binding(
|
||||
|
@ -3898,7 +3891,7 @@ where
|
|||
if self.patch(Rule::UnusedVariable) {
|
||||
diagnostic.try_set_fix(|| {
|
||||
pyflakes::fixes::remove_exception_handler_assignment(
|
||||
excepthandler,
|
||||
except_handler,
|
||||
self.locator,
|
||||
)
|
||||
.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
|
||||
// upstream.
|
||||
for arg in &arguments.posonlyargs {
|
||||
self.visit_arg(arg);
|
||||
for arg_with_default in &arguments.posonlyargs {
|
||||
self.visit_arg(&arg_with_default.def);
|
||||
}
|
||||
for arg in &arguments.args {
|
||||
self.visit_arg(arg);
|
||||
for arg_with_default in &arguments.args {
|
||||
self.visit_arg(&arg_with_default.def);
|
||||
}
|
||||
if let Some(arg) = &arguments.vararg {
|
||||
self.visit_arg(arg);
|
||||
}
|
||||
for arg in &arguments.kwonlyargs {
|
||||
self.visit_arg(arg);
|
||||
for arg_with_default in &arguments.kwonlyargs {
|
||||
self.visit_arg(&arg_with_default.def);
|
||||
}
|
||||
if let Some(arg) = &arguments.kwarg {
|
||||
self.visit_arg(arg);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -66,7 +66,7 @@ impl Violation for SysVersionCmpStr10 {
|
|||
}
|
||||
|
||||
/// 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 {
|
||||
Expr::Subscript(ast::ExprSubscript { value, slice, .. })
|
||||
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 let (
|
||||
[Cmpop::Eq | Cmpop::NotEq],
|
||||
[CmpOp::Eq | CmpOp::NotEq],
|
||||
[Expr::Constant(ast::ExprConstant {
|
||||
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) {
|
||||
if let (
|
||||
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
||||
[CmpOp::Lt | CmpOp::LtE | CmpOp::Gt | CmpOp::GtE],
|
||||
[Expr::Constant(ast::ExprConstant {
|
||||
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 let (
|
||||
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
||||
[CmpOp::Lt | CmpOp::LtE | CmpOp::Gt | CmpOp::GtE],
|
||||
[Expr::Constant(ast::ExprConstant {
|
||||
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 let (
|
||||
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
||||
[CmpOp::Lt | CmpOp::LtE | CmpOp::Gt | CmpOp::GtE],
|
||||
[Expr::Constant(ast::ExprConstant {
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -471,7 +471,7 @@ pub(crate) fn definition(
|
|||
_ => 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.
|
||||
let mut has_any_typed_arg = false; // Any argument 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());
|
||||
|
||||
// ANN001, ANN401
|
||||
for arg in args
|
||||
for ArgWithDefault {
|
||||
def,
|
||||
default: _,
|
||||
range: _,
|
||||
} in arguments
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(args.args.iter())
|
||||
.chain(args.kwonlyargs.iter())
|
||||
.chain(&arguments.args)
|
||||
.chain(&arguments.kwonlyargs)
|
||||
.skip(
|
||||
// If this is a non-static method, skip `cls` or `self`.
|
||||
usize::from(
|
||||
|
@ -498,12 +502,12 @@ pub(crate) fn definition(
|
|||
)
|
||||
{
|
||||
// ANN401 for dynamically typed arguments
|
||||
if let Some(annotation) = &arg.annotation {
|
||||
if let Some(annotation) = &def.annotation {
|
||||
has_any_typed_arg = true;
|
||||
if checker.enabled(Rule::AnyType) {
|
||||
check_dynamically_typed(
|
||||
annotation,
|
||||
|| arg.arg.to_string(),
|
||||
|| def.arg.to_string(),
|
||||
&mut diagnostics,
|
||||
is_overridden,
|
||||
checker.semantic(),
|
||||
|
@ -511,14 +515,14 @@ pub(crate) fn definition(
|
|||
}
|
||||
} else {
|
||||
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) {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
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
|
||||
if let Some(arg) = &args.vararg {
|
||||
if let Some(arg) = &arguments.vararg {
|
||||
if let Some(expr) = &arg.annotation {
|
||||
has_any_typed_arg = true;
|
||||
if !checker.settings.flake8_annotations.allow_star_arg_any {
|
||||
|
@ -558,7 +562,7 @@ pub(crate) fn definition(
|
|||
}
|
||||
|
||||
// ANN003, ANN401
|
||||
if let Some(arg) = &args.kwarg {
|
||||
if let Some(arg) = &arguments.kwarg {
|
||||
if let Some(expr) = &arg.annotation {
|
||||
has_any_typed_arg = true;
|
||||
if !checker.settings.flake8_annotations.allow_star_arg_any {
|
||||
|
@ -591,24 +595,32 @@ pub(crate) fn definition(
|
|||
|
||||
// ANN101, ANN102
|
||||
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 arg.annotation.is_none() {
|
||||
if let Some(ArgWithDefault {
|
||||
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 checker.enabled(Rule::MissingTypeCls) {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
MissingTypeCls {
|
||||
name: arg.arg.to_string(),
|
||||
name: def.arg.to_string(),
|
||||
},
|
||||
arg.range(),
|
||||
def.range(),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
if checker.enabled(Rule::MissingTypeSelf) {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
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_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> {
|
||||
let mut diagnostics: Vec<Diagnostic> = Vec::new();
|
||||
|
||||
let defaults_start =
|
||||
arguments.posonlyargs.len() + arguments.args.len() - arguments.defaults.len();
|
||||
for (i, arg) in arguments
|
||||
for ArgWithDefault {
|
||||
def,
|
||||
default,
|
||||
range: _,
|
||||
} in arguments
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(&arguments.args)
|
||||
.enumerate()
|
||||
.chain(&arguments.kwonlyargs)
|
||||
{
|
||||
if let Some(i) = i.checked_sub(defaults_start) {
|
||||
let default = &arguments.defaults[i];
|
||||
if let Some(diagnostic) = check_password_kwarg(arg, 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);
|
||||
}
|
||||
let Some(default) = default else {
|
||||
continue;
|
||||
};
|
||||
if let Some(diagnostic) = check_password_kwarg(def, 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_macros::{derive_message_formats, violation};
|
||||
|
@ -19,7 +19,7 @@ impl Violation for TryExceptContinue {
|
|||
/// S112
|
||||
pub(crate) fn try_except_continue(
|
||||
checker: &mut Checker,
|
||||
excepthandler: &Excepthandler,
|
||||
except_handler: &ExceptHandler,
|
||||
type_: Option<&Expr>,
|
||||
_name: Option<&str>,
|
||||
body: &[Stmt],
|
||||
|
@ -31,6 +31,6 @@ pub(crate) fn try_except_continue(
|
|||
{
|
||||
checker
|
||||
.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_macros::{derive_message_formats, violation};
|
||||
|
@ -19,7 +19,7 @@ impl Violation for TryExceptPass {
|
|||
/// S110
|
||||
pub(crate) fn try_except_pass(
|
||||
checker: &mut Checker,
|
||||
excepthandler: &Excepthandler,
|
||||
except_handler: &ExceptHandler,
|
||||
type_: Option<&Expr>,
|
||||
_name: Option<&str>,
|
||||
body: &[Stmt],
|
||||
|
@ -31,6 +31,6 @@ pub(crate) fn try_except_pass(
|
|||
{
|
||||
checker
|
||||
.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;
|
||||
|
||||
|
@ -75,7 +75,19 @@ pub(crate) fn check_boolean_default_value_in_function_definition(
|
|||
return;
|
||||
}
|
||||
|
||||
for arg in &arguments.defaults {
|
||||
add_if_boolean(checker, arg, BooleanDefaultValueInFunctionDefinition.into());
|
||||
for ArgWithDefault {
|
||||
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::Violation;
|
||||
|
@ -93,11 +93,16 @@ pub(crate) fn check_positional_boolean_in_def(
|
|||
return;
|
||||
}
|
||||
|
||||
for arg in arguments.posonlyargs.iter().chain(arguments.args.iter()) {
|
||||
if arg.annotation.is_none() {
|
||||
for ArgWithDefault {
|
||||
def,
|
||||
default: _,
|
||||
range: _,
|
||||
} in arguments.posonlyargs.iter().chain(&arguments.args)
|
||||
{
|
||||
if def.annotation.is_none() {
|
||||
continue;
|
||||
}
|
||||
let Some(expr) = &arg.annotation else {
|
||||
let Some(expr) = &def.annotation else {
|
||||
continue;
|
||||
};
|
||||
|
||||
|
@ -115,7 +120,7 @@ pub(crate) fn check_positional_boolean_in_def(
|
|||
}
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -50,7 +50,7 @@ impl Violation for AssertRaisesException {
|
|||
}
|
||||
|
||||
/// 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 {
|
||||
return;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use itertools::Itertools;
|
||||
use ruff_text_size::TextRange;
|
||||
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::{Diagnostic, Edit, Fix};
|
||||
|
@ -105,11 +105,11 @@ fn duplicate_handler_exceptions<'a>(
|
|||
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 duplicates: FxHashMap<CallPath, Vec<&Expr>> = FxHashMap::default();
|
||||
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;
|
||||
};
|
||||
match type_.as_ref() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -17,8 +17,9 @@ impl Violation for ExceptWithEmptyTuple {
|
|||
}
|
||||
|
||||
/// B029
|
||||
pub(crate) fn except_with_empty_tuple(checker: &mut Checker, excepthandler: &Excepthandler) {
|
||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = excepthandler;
|
||||
pub(crate) fn except_with_empty_tuple(checker: &mut Checker, except_handler: &ExceptHandler) {
|
||||
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, .. }) =
|
||||
except_handler;
|
||||
let Some(type_) = type_ else {
|
||||
return;
|
||||
};
|
||||
|
@ -26,8 +27,9 @@ pub(crate) fn except_with_empty_tuple(checker: &mut Checker, excepthandler: &Exc
|
|||
return;
|
||||
};
|
||||
if elts.is_empty() {
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(ExceptWithEmptyTuple, excepthandler.range()));
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
ExceptWithEmptyTuple,
|
||||
except_handler.range(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -44,9 +44,10 @@ fn flatten_starred_iterables(expr: &Expr) -> Vec<&Expr> {
|
|||
/// B030
|
||||
pub(crate) fn except_with_non_exception_classes(
|
||||
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 {
|
||||
return;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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::{Diagnostic, DiagnosticKind};
|
||||
|
@ -114,12 +114,19 @@ pub(crate) fn function_call_argument_default(checker: &mut Checker, arguments: &
|
|||
.collect();
|
||||
let diagnostics = {
|
||||
let mut visitor = ArgumentDefaultVisitor::new(checker.semantic(), extend_immutable_calls);
|
||||
for expr in arguments
|
||||
.defaults
|
||||
for ArgWithDefault {
|
||||
default,
|
||||
def: _,
|
||||
range: _,
|
||||
} in arguments
|
||||
.posonlyargs
|
||||
.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
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -49,8 +49,17 @@ where
|
|||
range: _,
|
||||
}) => {
|
||||
visitor::walk_expr(self, body);
|
||||
for arg in &args.args {
|
||||
self.names.remove(arg.arg.as_str());
|
||||
for ArgWithDefault {
|
||||
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),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Arguments, Ranged};
|
||||
use rustpython_parser::ast::{ArgWithDefault, Arguments, Ranged};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -19,22 +19,22 @@ impl Violation for MutableArgumentDefault {
|
|||
/// B006
|
||||
pub(crate) fn mutable_argument_default(checker: &mut Checker, arguments: &Arguments) {
|
||||
// Scan in reverse order to right-align zip().
|
||||
for (arg, default) in arguments
|
||||
.kwonlyargs
|
||||
for ArgWithDefault {
|
||||
def,
|
||||
default,
|
||||
range: _,
|
||||
} in arguments
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.rev()
|
||||
.zip(arguments.kw_defaults.iter().rev())
|
||||
.chain(
|
||||
arguments
|
||||
.args
|
||||
.iter()
|
||||
.rev()
|
||||
.chain(arguments.posonlyargs.iter().rev())
|
||||
.zip(arguments.defaults.iter().rev()),
|
||||
)
|
||||
.chain(&arguments.args)
|
||||
.chain(&arguments.kwonlyargs)
|
||||
{
|
||||
let Some(default)= default else {
|
||||
continue;
|
||||
};
|
||||
|
||||
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())
|
||||
})
|
||||
{
|
||||
|
|
|
@ -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_macros::{derive_message_formats, violation};
|
||||
|
@ -30,10 +30,10 @@ impl AlwaysAutofixableViolation for RedundantTupleInExceptionHandler {
|
|||
/// B013
|
||||
pub(crate) fn redundant_tuple_in_exception_handler(
|
||||
checker: &mut Checker,
|
||||
handlers: &[Excepthandler],
|
||||
handlers: &[ExceptHandler],
|
||||
) {
|
||||
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;
|
||||
};
|
||||
let Expr::Tuple(ast::ExprTuple { elts, .. }) = type_.as_ref() else {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
//! 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_macros::{derive_message_formats, violation};
|
||||
|
@ -38,16 +38,16 @@ impl Violation for UnaryPrefixIncrement {
|
|||
pub(crate) fn unary_prefix_increment(
|
||||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
op: Unaryop,
|
||||
op: UnaryOp,
|
||||
operand: &Expr,
|
||||
) {
|
||||
if !matches!(op, Unaryop::UAdd) {
|
||||
if !matches!(op, UnaryOp::UAdd) {
|
||||
return;
|
||||
}
|
||||
let Expr::UnaryOp(ast::ExprUnaryOp { op, .. })= operand else {
|
||||
return;
|
||||
};
|
||||
if !matches!(op, Unaryop::UAdd) {
|
||||
if !matches!(op, UnaryOp::UAdd) {
|
||||
return;
|
||||
}
|
||||
checker
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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::source_code::Locator;
|
||||
|
@ -13,7 +13,7 @@ pub(super) fn shadows_builtin(name: &str, ignorelist: &[String]) -> bool {
|
|||
pub(crate) enum AnyShadowing<'a> {
|
||||
Expression(&'a Expr),
|
||||
Statement(&'a Stmt),
|
||||
ExceptHandler(&'a Excepthandler),
|
||||
ExceptHandler(&'a ExceptHandler),
|
||||
}
|
||||
|
||||
impl AnyShadowing<'_> {
|
||||
|
@ -38,8 +38,8 @@ impl<'a> From<&'a Expr> for AnyShadowing<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Excepthandler> for AnyShadowing<'a> {
|
||||
fn from(value: &'a Excepthandler) -> Self {
|
||||
impl<'a> From<&'a ExceptHandler> for AnyShadowing<'a> {
|
||||
fn from(value: &'a ExceptHandler) -> Self {
|
||||
AnyShadowing::ExceptHandler(value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -74,7 +74,7 @@ pub(crate) fn unnecessary_subscript_reversal(
|
|||
return;
|
||||
};
|
||||
let Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::USub,
|
||||
op: UnaryOp::USub,
|
||||
operand,
|
||||
range: _,
|
||||
}) = step.as_ref() else {
|
||||
|
|
|
@ -5,7 +5,7 @@ use itertools::Either::{Left, Right};
|
|||
|
||||
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::{Diagnostic, Edit, Fix};
|
||||
|
@ -60,7 +60,7 @@ impl AlwaysAutofixableViolation for MultipleStartsEndsWith {
|
|||
|
||||
/// PIE810
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -155,7 +155,7 @@ pub(crate) fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
|||
// Generate the combined `BoolOp`.
|
||||
let mut call = Some(call);
|
||||
let node = Expr::BoolOp(ast::ExprBoolOp {
|
||||
op: Boolop::Or,
|
||||
op: BoolOp::Or,
|
||||
values: values
|
||||
.iter()
|
||||
.enumerate()
|
||||
|
|
|
@ -62,7 +62,7 @@ pub(crate) fn any_eq_ne_annotation(checker: &mut Checker, name: &str, args: &Arg
|
|||
return;
|
||||
}
|
||||
|
||||
let Some(annotation) = &args.args[1].annotation else {
|
||||
let Some(annotation) = &args.args[1].def.annotation else {
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -61,7 +61,7 @@ pub(crate) fn bad_version_info_comparison(
|
|||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
left: &Expr,
|
||||
ops: &[Cmpop],
|
||||
ops: &[CmpOp],
|
||||
comparators: &[Expr],
|
||||
) {
|
||||
let ([op], [_right]) = (ops, comparators) else {
|
||||
|
@ -78,7 +78,7 @@ pub(crate) fn bad_version_info_comparison(
|
|||
return;
|
||||
}
|
||||
|
||||
if !matches!(op, Cmpop::Lt | Cmpop::GtE) {
|
||||
if !matches!(op, CmpOp::Lt | CmpOp::GtE) {
|
||||
let diagnostic = Diagnostic::new(BadVersionInfoComparison, expr.range());
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::fmt;
|
||||
|
||||
use itertools::chain;
|
||||
use rustpython_parser::ast::Ranged;
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
|
@ -49,12 +48,12 @@ impl Violation for NoReturnArgumentAnnotationInStub {
|
|||
|
||||
/// PYI050
|
||||
pub(crate) fn no_return_argument_annotation(checker: &mut Checker, args: &Arguments) {
|
||||
for annotation in chain!(
|
||||
args.args.iter(),
|
||||
args.posonlyargs.iter(),
|
||||
args.kwonlyargs.iter()
|
||||
)
|
||||
.filter_map(|arg| arg.annotation.as_ref())
|
||||
for annotation in args
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(&args.args)
|
||||
.chain(&args.kwonlyargs)
|
||||
.filter_map(|arg| arg.def.annotation.as_ref())
|
||||
{
|
||||
if checker.semantic().match_typing_expr(annotation, "NoReturn") {
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -156,7 +158,7 @@ fn is_valid_default_value_with_annotation(
|
|||
});
|
||||
}
|
||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::USub,
|
||||
op: UnaryOp::USub,
|
||||
operand,
|
||||
range: _,
|
||||
}) => {
|
||||
|
@ -199,7 +201,7 @@ fn is_valid_default_value_with_annotation(
|
|||
{
|
||||
return locator.slice(left.range()).len() <= 10;
|
||||
} else if let Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::USub,
|
||||
op: UnaryOp::USub,
|
||||
operand,
|
||||
range: _,
|
||||
}) = left.as_ref()
|
||||
|
@ -312,130 +314,74 @@ fn is_enum(bases: &[Expr], semantic: &SemanticModel) -> bool {
|
|||
}
|
||||
|
||||
/// PYI011
|
||||
pub(crate) fn typed_argument_simple_defaults(checker: &mut Checker, args: &Arguments) {
|
||||
if !args.defaults.is_empty() {
|
||||
let defaults_start = args.posonlyargs.len() + args.args.len() - args.defaults.len();
|
||||
for (i, arg) in args.posonlyargs.iter().chain(&args.args).enumerate() {
|
||||
if let Some(default) = i
|
||||
.checked_sub(defaults_start)
|
||||
.and_then(|i| args.defaults.get(i))
|
||||
{
|
||||
if arg.annotation.is_some() {
|
||||
if !is_valid_default_value_with_annotation(
|
||||
default,
|
||||
true,
|
||||
checker.locator,
|
||||
checker.semantic(),
|
||||
) {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(TypedArgumentDefaultInStub, default.range());
|
||||
pub(crate) fn typed_argument_simple_defaults(checker: &mut Checker, arguments: &Arguments) {
|
||||
for ArgWithDefault {
|
||||
def,
|
||||
default,
|
||||
range: _,
|
||||
} in arguments
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(&arguments.args)
|
||||
.chain(&arguments.kwonlyargs)
|
||||
{
|
||||
let Some(default) = default else {
|
||||
continue;
|
||||
};
|
||||
if def.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);
|
||||
}
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||
"...".to_string(),
|
||||
default.range(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !args.kw_defaults.is_empty() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// PYI014
|
||||
pub(crate) fn argument_simple_defaults(checker: &mut Checker, args: &Arguments) {
|
||||
if !args.defaults.is_empty() {
|
||||
let defaults_start = args.posonlyargs.len() + args.args.len() - args.defaults.len();
|
||||
for (i, arg) in args.posonlyargs.iter().chain(&args.args).enumerate() {
|
||||
if let Some(default) = i
|
||||
.checked_sub(defaults_start)
|
||||
.and_then(|i| args.defaults.get(i))
|
||||
{
|
||||
if arg.annotation.is_none() {
|
||||
if !is_valid_default_value_with_annotation(
|
||||
default,
|
||||
true,
|
||||
checker.locator,
|
||||
checker.semantic(),
|
||||
) {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(ArgumentDefaultInStub, default.range());
|
||||
pub(crate) fn argument_simple_defaults(checker: &mut Checker, arguments: &Arguments) {
|
||||
for ArgWithDefault {
|
||||
def,
|
||||
default,
|
||||
range: _,
|
||||
} in arguments
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(&arguments.args)
|
||||
.chain(&arguments.kwonlyargs)
|
||||
{
|
||||
let Some(default) = default else {
|
||||
continue;
|
||||
};
|
||||
if def.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);
|
||||
}
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.set_fix(Fix::suggested(Edit::range_replacement(
|
||||
"...".to_string(),
|
||||
default.range(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !args.kw_defaults.is_empty() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -93,7 +93,7 @@ pub(crate) fn unrecognized_platform(
|
|||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
left: &Expr,
|
||||
ops: &[Cmpop],
|
||||
ops: &[CmpOp],
|
||||
comparators: &[Expr],
|
||||
) {
|
||||
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.
|
||||
if !matches!(op, Cmpop::Eq | Cmpop::NotEq) && checker.enabled(Rule::UnrecognizedPlatformCheck) {
|
||||
if !matches!(op, CmpOp::Eq | CmpOp::NotEq) && checker.enabled(Rule::UnrecognizedPlatformCheck) {
|
||||
checker
|
||||
.diagnostics
|
||||
.push(diagnostic_unrecognized_platform_check);
|
||||
|
|
|
@ -3,11 +3,11 @@ use std::borrow::Cow;
|
|||
use anyhow::bail;
|
||||
use anyhow::Result;
|
||||
use libcst_native::{
|
||||
Assert, BooleanOp, CompoundStatement, Expression, ParenthesizableWhitespace, ParenthesizedNode,
|
||||
SimpleStatementLine, SimpleWhitespace, SmallStatement, Statement, TrailingWhitespace, UnaryOp,
|
||||
UnaryOperation,
|
||||
self, Assert, BooleanOp, CompoundStatement, Expression, ParenthesizableWhitespace,
|
||||
ParenthesizedNode, SimpleStatementLine, SimpleWhitespace, SmallStatement, Statement,
|
||||
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 ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||
|
@ -227,11 +227,11 @@ pub(crate) fn assert_falsy(checker: &mut Checker, stmt: &Stmt, test: &Expr) {
|
|||
}
|
||||
|
||||
/// PT017
|
||||
pub(crate) fn assert_in_exception_handler(handlers: &[Excepthandler]) -> Vec<Diagnostic> {
|
||||
pub(crate) fn assert_in_exception_handler(handlers: &[ExceptHandler]) -> Vec<Diagnostic> {
|
||||
handlers
|
||||
.iter()
|
||||
.flat_map(|handler| match handler {
|
||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||
name, body, ..
|
||||
}) => {
|
||||
if let Some(name) = name {
|
||||
|
@ -262,17 +262,17 @@ enum CompositionKind {
|
|||
fn is_composite_condition(test: &Expr) -> CompositionKind {
|
||||
match test {
|
||||
Expr::BoolOp(ast::ExprBoolOp {
|
||||
op: Boolop::And, ..
|
||||
op: BoolOp::And, ..
|
||||
}) => {
|
||||
return CompositionKind::Simple;
|
||||
}
|
||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::Not,
|
||||
op: UnaryOp::Not,
|
||||
operand,
|
||||
range: _,
|
||||
}) => {
|
||||
if let Expr::BoolOp(ast::ExprBoolOp {
|
||||
op: Boolop::Or,
|
||||
op: BoolOp::Or,
|
||||
values,
|
||||
range: _,
|
||||
}) = operand.as_ref()
|
||||
|
@ -282,7 +282,7 @@ fn is_composite_condition(test: &Expr) -> CompositionKind {
|
|||
!matches!(
|
||||
expr,
|
||||
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`.
|
||||
fn negate<'a>(expression: &Expression<'a>) -> Expression<'a> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
Expression::UnaryOperation(Box::new(UnaryOperation {
|
||||
operator: UnaryOp::Not {
|
||||
operator: libcst_native::UnaryOp::Not {
|
||||
whitespace_after: ParenthesizableWhitespace::SimpleWhitespace(SimpleWhitespace(" ")),
|
||||
},
|
||||
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);
|
||||
match &assert_statement.test {
|
||||
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 matches!(op.operator, BooleanOp::Or { .. }) {
|
||||
conditions.push(negate(&op.left));
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::fmt;
|
|||
|
||||
use anyhow::Result;
|
||||
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::{Diagnostic, Edit, Fix};
|
||||
|
@ -421,18 +421,29 @@ fn check_fixture_returns(checker: &mut Checker, stmt: &Stmt, name: &str, body: &
|
|||
}
|
||||
|
||||
/// PT019
|
||||
fn check_test_function_args(checker: &mut Checker, args: &Arguments) {
|
||||
args.args.iter().chain(&args.kwonlyargs).for_each(|arg| {
|
||||
let name = &arg.arg;
|
||||
if name.starts_with('_') {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
PytestFixtureParamWithoutValue {
|
||||
name: name.to_string(),
|
||||
},
|
||||
arg.range(),
|
||||
));
|
||||
}
|
||||
});
|
||||
fn check_test_function_args(checker: &mut Checker, arguments: &Arguments) {
|
||||
arguments
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(&arguments.args)
|
||||
.chain(&arguments.kwonlyargs)
|
||||
.for_each(
|
||||
|ArgWithDefault {
|
||||
def,
|
||||
default: _,
|
||||
range: _,
|
||||
}| {
|
||||
let name = &def.arg;
|
||||
if name.starts_with('_') {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
PytestFixtureParamWithoutValue {
|
||||
name: name.to_string(),
|
||||
},
|
||||
def.range(),
|
||||
));
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 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_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(
|
||||
checker: &mut Checker,
|
||||
stmt: &Stmt,
|
||||
items: &[Withitem],
|
||||
items: &[WithItem],
|
||||
body: &[Stmt],
|
||||
) {
|
||||
let mut is_too_complex = false;
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::hash::BuildHasherDefault;
|
|||
use anyhow::{anyhow, bail, Result};
|
||||
use ruff_text_size::TextRange;
|
||||
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
|
||||
/// `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 {
|
||||
left: Box::new(left.clone()),
|
||||
ops: vec![cmpop],
|
||||
ops: vec![cmp_op],
|
||||
comparators: vec![right.clone()],
|
||||
range: TextRange::default(),
|
||||
})
|
||||
|
@ -263,7 +263,7 @@ impl UnittestAssert {
|
|||
Ok(if matches!(self, UnittestAssert::False) {
|
||||
assert(
|
||||
&Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::Not,
|
||||
op: UnaryOp::Not,
|
||||
operand: Box::new(expr.clone()),
|
||||
range: TextRange::default(),
|
||||
}),
|
||||
|
@ -290,18 +290,18 @@ impl UnittestAssert {
|
|||
.get("second")
|
||||
.ok_or_else(|| anyhow!("Missing argument `second`"))?;
|
||||
let msg = args.get("msg").copied();
|
||||
let cmpop = match self {
|
||||
UnittestAssert::Equal | UnittestAssert::Equals => Cmpop::Eq,
|
||||
UnittestAssert::NotEqual | UnittestAssert::NotEquals => Cmpop::NotEq,
|
||||
UnittestAssert::Greater => Cmpop::Gt,
|
||||
UnittestAssert::GreaterEqual => Cmpop::GtE,
|
||||
UnittestAssert::Less => Cmpop::Lt,
|
||||
UnittestAssert::LessEqual => Cmpop::LtE,
|
||||
UnittestAssert::Is => Cmpop::Is,
|
||||
UnittestAssert::IsNot => Cmpop::IsNot,
|
||||
let cmp_op = match self {
|
||||
UnittestAssert::Equal | UnittestAssert::Equals => CmpOp::Eq,
|
||||
UnittestAssert::NotEqual | UnittestAssert::NotEquals => CmpOp::NotEq,
|
||||
UnittestAssert::Greater => CmpOp::Gt,
|
||||
UnittestAssert::GreaterEqual => CmpOp::GtE,
|
||||
UnittestAssert::Less => CmpOp::Lt,
|
||||
UnittestAssert::LessEqual => CmpOp::LtE,
|
||||
UnittestAssert::Is => CmpOp::Is,
|
||||
UnittestAssert::IsNot => CmpOp::IsNot,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let expr = compare(first, cmpop, second);
|
||||
let expr = compare(first, cmp_op, second);
|
||||
Ok(assert(&expr, msg))
|
||||
}
|
||||
UnittestAssert::In | UnittestAssert::NotIn => {
|
||||
|
@ -312,12 +312,12 @@ impl UnittestAssert {
|
|||
.get("container")
|
||||
.ok_or_else(|| anyhow!("Missing argument `container`"))?;
|
||||
let msg = args.get("msg").copied();
|
||||
let cmpop = if matches!(self, UnittestAssert::In) {
|
||||
Cmpop::In
|
||||
let cmp_op = if matches!(self, UnittestAssert::In) {
|
||||
CmpOp::In
|
||||
} else {
|
||||
Cmpop::NotIn
|
||||
CmpOp::NotIn
|
||||
};
|
||||
let expr = compare(member, cmpop, container);
|
||||
let expr = compare(member, cmp_op, container);
|
||||
Ok(assert(&expr, msg))
|
||||
}
|
||||
UnittestAssert::IsNone | UnittestAssert::IsNotNone => {
|
||||
|
@ -325,17 +325,17 @@ impl UnittestAssert {
|
|||
.get("expr")
|
||||
.ok_or_else(|| anyhow!("Missing argument `expr`"))?;
|
||||
let msg = args.get("msg").copied();
|
||||
let cmpop = if matches!(self, UnittestAssert::IsNone) {
|
||||
Cmpop::Is
|
||||
let cmp_op = if matches!(self, UnittestAssert::IsNone) {
|
||||
CmpOp::Is
|
||||
} else {
|
||||
Cmpop::IsNot
|
||||
CmpOp::IsNot
|
||||
};
|
||||
let node = Expr::Constant(ast::ExprConstant {
|
||||
value: Constant::None,
|
||||
kind: None,
|
||||
range: TextRange::default(),
|
||||
});
|
||||
let expr = compare(expr, cmpop, &node);
|
||||
let expr = compare(expr, cmp_op, &node);
|
||||
Ok(assert(&expr, msg))
|
||||
}
|
||||
UnittestAssert::IsInstance | UnittestAssert::NotIsInstance => {
|
||||
|
@ -362,7 +362,7 @@ impl UnittestAssert {
|
|||
Ok(assert(&isinstance, msg))
|
||||
} else {
|
||||
let node = ast::ExprUnaryOp {
|
||||
op: Unaryop::Not,
|
||||
op: UnaryOp::Not,
|
||||
operand: Box::new(isinstance),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
|
@ -403,7 +403,7 @@ impl UnittestAssert {
|
|||
Ok(assert(&re_search, msg))
|
||||
} else {
|
||||
let node = ast::ExprUnaryOp {
|
||||
op: Unaryop::Not,
|
||||
op: UnaryOp::Not,
|
||||
operand: Box::new(re_search),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
|
|
|
@ -5,7 +5,7 @@ use itertools::Either::{Left, Right};
|
|||
use itertools::Itertools;
|
||||
use ruff_text_size::TextRange;
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -299,7 +299,7 @@ fn is_same_expr<'a>(a: &'a Expr, b: &'a Expr) -> Option<&'a str> {
|
|||
|
||||
/// SIM101
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -402,7 +402,7 @@ pub(crate) fn duplicate_isinstance_call(checker: &mut Checker, expr: &Expr) {
|
|||
|
||||
// Generate the combined `BoolOp`.
|
||||
let node = ast::ExprBoolOp {
|
||||
op: Boolop::Or,
|
||||
op: BoolOp::Or,
|
||||
values: iter::once(call)
|
||||
.chain(
|
||||
values
|
||||
|
@ -437,7 +437,7 @@ fn match_eq_target(expr: &Expr) -> Option<(&str, &Expr)> {
|
|||
if ops.len() != 1 || comparators.len() != 1 {
|
||||
return None;
|
||||
}
|
||||
if !matches!(&ops[0], Cmpop::Eq) {
|
||||
if !matches!(&ops[0], CmpOp::Eq) {
|
||||
return None;
|
||||
}
|
||||
let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() else {
|
||||
|
@ -452,7 +452,7 @@ fn match_eq_target(expr: &Expr) -> Option<(&str, &Expr)> {
|
|||
|
||||
/// SIM109
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -501,7 +501,7 @@ pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) {
|
|||
};
|
||||
let node2 = ast::ExprCompare {
|
||||
left: Box::new(node1.into()),
|
||||
ops: vec![Cmpop::In],
|
||||
ops: vec![CmpOp::In],
|
||||
comparators: vec![node.into()],
|
||||
range: TextRange::default(),
|
||||
};
|
||||
|
@ -524,7 +524,7 @@ pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) {
|
|||
} else {
|
||||
// Wrap in a `x in (a, b) or ...` boolean operation.
|
||||
let node = ast::ExprBoolOp {
|
||||
op: Boolop::Or,
|
||||
op: BoolOp::Or,
|
||||
values: iter::once(in_expr).chain(unmatched).collect(),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
|
@ -542,7 +542,7 @@ pub(crate) fn compare_with_tuple(checker: &mut Checker, expr: &Expr) {
|
|||
|
||||
/// SIM220
|
||||
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;
|
||||
};
|
||||
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![];
|
||||
for expr in values {
|
||||
if let Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::Not,
|
||||
op: UnaryOp::Not,
|
||||
operand,
|
||||
range: _,
|
||||
}) = expr
|
||||
|
@ -597,7 +597,7 @@ pub(crate) fn expr_and_not_expr(checker: &mut Checker, expr: &Expr) {
|
|||
|
||||
/// SIM221
|
||||
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;
|
||||
};
|
||||
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![];
|
||||
for expr in values {
|
||||
if let Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::Not,
|
||||
op: UnaryOp::Not,
|
||||
operand,
|
||||
range: _,
|
||||
}) = expr
|
||||
|
@ -673,7 +673,7 @@ pub(crate) fn get_short_circuit_edit(
|
|||
|
||||
fn is_short_circuit(
|
||||
expr: &Expr,
|
||||
expected_op: Boolop,
|
||||
expected_op: BoolOp,
|
||||
checker: &Checker,
|
||||
) -> Option<(Edit, ContentAround)> {
|
||||
let Expr::BoolOp(ast::ExprBoolOp { op, values, range: _, }) = expr else {
|
||||
|
@ -683,8 +683,8 @@ fn is_short_circuit(
|
|||
return None;
|
||||
}
|
||||
let short_circuit_truthiness = match op {
|
||||
Boolop::And => Truthiness::Falsey,
|
||||
Boolop::Or => Truthiness::Truthy,
|
||||
BoolOp::And => Truthiness::Falsey,
|
||||
BoolOp::Or => Truthiness::Truthy,
|
||||
};
|
||||
|
||||
let mut location = expr.start();
|
||||
|
@ -753,7 +753,7 @@ fn is_short_circuit(
|
|||
|
||||
/// SIM222
|
||||
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(
|
||||
ExprOrTrue {
|
||||
expr: edit.content().unwrap_or_default().to_string(),
|
||||
|
@ -771,7 +771,7 @@ pub(crate) fn expr_or_true(checker: &mut Checker, expr: &Expr) {
|
|||
|
||||
/// SIM223
|
||||
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(
|
||||
ExprAndFalse {
|
||||
expr: edit.content().unwrap_or_default().to_string(),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use log::error;
|
||||
use ruff_text_size::TextRange;
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -734,7 +734,7 @@ pub(crate) fn manual_dict_lookup(
|
|||
if orelse.len() != 1 {
|
||||
return;
|
||||
}
|
||||
if !(ops.len() == 1 && ops[0] == Cmpop::Eq) {
|
||||
if !(ops.len() == 1 && ops[0] == CmpOp::Eq) {
|
||||
return;
|
||||
}
|
||||
if comparators.len() != 1 {
|
||||
|
@ -807,7 +807,7 @@ pub(crate) fn manual_dict_lookup(
|
|||
let Expr::Name(ast::ExprName { id, .. }) = left.as_ref() else {
|
||||
return;
|
||||
};
|
||||
if !(id == target && ops.len() == 1 && ops[0] == Cmpop::Eq) {
|
||||
if !(id == target && ops.len() == 1 && ops[0] == CmpOp::Eq) {
|
||||
return;
|
||||
}
|
||||
if comparators.len() != 1 {
|
||||
|
@ -882,8 +882,8 @@ pub(crate) fn use_dict_get_with_default(
|
|||
return;
|
||||
}
|
||||
let (expected_var, expected_value, default_var, default_value) = match ops[..] {
|
||||
[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::In] => (&body_var[0], body_value, &orelse_var[0], orelse_value),
|
||||
[CmpOp::NotIn] => (&orelse_var[0], orelse_value, &body_var[0], body_value),
|
||||
_ => {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -219,7 +219,7 @@ pub(crate) fn explicit_false_true_in_ifexpr(
|
|||
if checker.patch(diagnostic.kind.rule()) {
|
||||
let node = test.clone();
|
||||
let node1 = ast::ExprUnaryOp {
|
||||
op: Unaryop::Not,
|
||||
op: UnaryOp::Not,
|
||||
operand: Box::new(node),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -138,16 +138,16 @@ fn is_exception_check(stmt: &Stmt) -> bool {
|
|||
pub(crate) fn negation_with_equal_op(
|
||||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
op: Unaryop,
|
||||
op: UnaryOp,
|
||||
operand: &Expr,
|
||||
) {
|
||||
if !matches!(op, Unaryop::Not) {
|
||||
if !matches!(op, UnaryOp::Not) {
|
||||
return;
|
||||
}
|
||||
let Expr::Compare(ast::ExprCompare { left, ops, comparators, range: _}) = operand else {
|
||||
return;
|
||||
};
|
||||
if !matches!(&ops[..], [Cmpop::Eq]) {
|
||||
if !matches!(&ops[..], [CmpOp::Eq]) {
|
||||
return;
|
||||
}
|
||||
if is_exception_check(checker.semantic().stmt()) {
|
||||
|
@ -174,7 +174,7 @@ pub(crate) fn negation_with_equal_op(
|
|||
if checker.patch(diagnostic.kind.rule()) {
|
||||
let node = ast::ExprCompare {
|
||||
left: left.clone(),
|
||||
ops: vec![Cmpop::NotEq],
|
||||
ops: vec![CmpOp::NotEq],
|
||||
comparators: comparators.clone(),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
|
@ -191,16 +191,16 @@ pub(crate) fn negation_with_equal_op(
|
|||
pub(crate) fn negation_with_not_equal_op(
|
||||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
op: Unaryop,
|
||||
op: UnaryOp,
|
||||
operand: &Expr,
|
||||
) {
|
||||
if !matches!(op, Unaryop::Not) {
|
||||
if !matches!(op, UnaryOp::Not) {
|
||||
return;
|
||||
}
|
||||
let Expr::Compare(ast::ExprCompare { left, ops, comparators, range: _}) = operand else {
|
||||
return;
|
||||
};
|
||||
if !matches!(&ops[..], [Cmpop::NotEq]) {
|
||||
if !matches!(&ops[..], [CmpOp::NotEq]) {
|
||||
return;
|
||||
}
|
||||
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()) {
|
||||
let node = ast::ExprCompare {
|
||||
left: left.clone(),
|
||||
ops: vec![Cmpop::Eq],
|
||||
ops: vec![CmpOp::Eq],
|
||||
comparators: comparators.clone(),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
|
@ -241,14 +241,14 @@ pub(crate) fn negation_with_not_equal_op(
|
|||
}
|
||||
|
||||
/// SIM208
|
||||
pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: Unaryop, operand: &Expr) {
|
||||
if !matches!(op, Unaryop::Not) {
|
||||
pub(crate) fn double_negation(checker: &mut Checker, expr: &Expr, op: UnaryOp, operand: &Expr) {
|
||||
if !matches!(op, UnaryOp::Not) {
|
||||
return;
|
||||
}
|
||||
let Expr::UnaryOp(ast::ExprUnaryOp { op: operand_op, operand, range: _ }) = operand else {
|
||||
return;
|
||||
};
|
||||
if !matches!(operand_op, Unaryop::Not) {
|
||||
if !matches!(operand_op, UnaryOp::Not) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use log::error;
|
||||
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::{Diagnostic, Fix};
|
||||
|
@ -62,7 +62,7 @@ impl Violation for MultipleWithStatements {
|
|||
|
||||
/// Returns a boolean indicating whether it's an async with statement, the items
|
||||
/// and body.
|
||||
fn next_with(body: &[Stmt]) -> Option<(bool, &[Withitem], &[Stmt])> {
|
||||
fn next_with(body: &[Stmt]) -> Option<(bool, &[WithItem], &[Stmt])> {
|
||||
match body {
|
||||
[Stmt::With(ast::StmtWith { items, body, .. })] => Some((false, items, body)),
|
||||
[Stmt::AsyncWith(ast::StmtAsyncWith { items, body, .. })] => Some((true, items, body)),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::Result;
|
||||
use log::error;
|
||||
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::{AlwaysAutofixableViolation, Diagnostic, Fix};
|
||||
|
@ -128,10 +128,10 @@ pub(crate) fn key_in_dict_compare(
|
|||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
left: &Expr,
|
||||
ops: &[Cmpop],
|
||||
ops: &[CmpOp],
|
||||
comparators: &[Expr],
|
||||
) {
|
||||
if !matches!(ops[..], [Cmpop::In]) {
|
||||
if !matches!(ops[..], [CmpOp::In]) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_text_size::{TextRange, TextSize};
|
||||
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};
|
||||
|
@ -117,7 +117,7 @@ pub(crate) fn convert_for_loop_to_any_all(
|
|||
// Invert the condition.
|
||||
let test = {
|
||||
if let Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::Not,
|
||||
op: UnaryOp::Not,
|
||||
operand,
|
||||
range: _,
|
||||
}) = &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()) {
|
||||
let op = match op {
|
||||
Cmpop::Eq => Cmpop::NotEq,
|
||||
Cmpop::NotEq => Cmpop::Eq,
|
||||
Cmpop::Lt => Cmpop::GtE,
|
||||
Cmpop::LtE => Cmpop::Gt,
|
||||
Cmpop::Gt => Cmpop::LtE,
|
||||
Cmpop::GtE => Cmpop::Lt,
|
||||
Cmpop::Is => Cmpop::IsNot,
|
||||
Cmpop::IsNot => Cmpop::Is,
|
||||
Cmpop::In => Cmpop::NotIn,
|
||||
Cmpop::NotIn => Cmpop::In,
|
||||
CmpOp::Eq => CmpOp::NotEq,
|
||||
CmpOp::NotEq => CmpOp::Eq,
|
||||
CmpOp::Lt => CmpOp::GtE,
|
||||
CmpOp::LtE => CmpOp::Gt,
|
||||
CmpOp::Gt => CmpOp::LtE,
|
||||
CmpOp::GtE => CmpOp::Lt,
|
||||
CmpOp::Is => CmpOp::IsNot,
|
||||
CmpOp::IsNot => CmpOp::Is,
|
||||
CmpOp::In => CmpOp::NotIn,
|
||||
CmpOp::NotIn => CmpOp::In,
|
||||
};
|
||||
let node = ast::ExprCompare {
|
||||
left: left.clone(),
|
||||
|
@ -152,7 +152,7 @@ pub(crate) fn convert_for_loop_to_any_all(
|
|||
node.into()
|
||||
} else {
|
||||
let node = ast::ExprUnaryOp {
|
||||
op: Unaryop::Not,
|
||||
op: UnaryOp::Not,
|
||||
operand: Box::new(loop_info.test.clone()),
|
||||
range: TextRange::default(),
|
||||
};
|
||||
|
@ -160,7 +160,7 @@ pub(crate) fn convert_for_loop_to_any_all(
|
|||
}
|
||||
} else {
|
||||
let node = ast::ExprUnaryOp {
|
||||
op: Unaryop::Not,
|
||||
op: UnaryOp::Not,
|
||||
operand: Box::new(loop_info.test.clone()),
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -57,12 +57,12 @@ fn find_return(stmts: &[Stmt]) -> Option<&Stmt> {
|
|||
pub(crate) fn return_in_try_except_finally(
|
||||
checker: &mut Checker,
|
||||
body: &[Stmt],
|
||||
handlers: &[Excepthandler],
|
||||
handlers: &[ExceptHandler],
|
||||
finalbody: &[Stmt],
|
||||
) {
|
||||
let try_has_return = find_return(body).is_some();
|
||||
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()
|
||||
});
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -68,7 +68,7 @@ pub(crate) fn suppressible_exception(
|
|||
checker: &mut Checker,
|
||||
stmt: &Stmt,
|
||||
try_body: &[Stmt],
|
||||
handlers: &[Excepthandler],
|
||||
handlers: &[ExceptHandler],
|
||||
orelse: &[Stmt],
|
||||
finalbody: &[Stmt],
|
||||
) {
|
||||
|
@ -90,7 +90,7 @@ pub(crate) fn suppressible_exception(
|
|||
return;
|
||||
}
|
||||
let handler = &handlers[0];
|
||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = handler;
|
||||
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { body, .. }) = handler;
|
||||
if body.len() == 1 {
|
||||
let node = &body[0];
|
||||
if node.is_pass_stmt()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::Result;
|
||||
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 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::Name(ast::ExprName { id, .. }) => str::is_cased_uppercase(id),
|
||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::UAdd | Unaryop::USub | Unaryop::Invert,
|
||||
op: UnaryOp::UAdd | UnaryOp::USub | UnaryOp::Invert,
|
||||
operand,
|
||||
range: _,
|
||||
}) => operand.is_constant_expr(),
|
||||
|
@ -156,7 +156,7 @@ pub(crate) fn yoda_conditions(
|
|||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
left: &Expr,
|
||||
ops: &[Cmpop],
|
||||
ops: &[CmpOp],
|
||||
comparators: &[Expr],
|
||||
) {
|
||||
let ([op], [right]) = (ops, comparators) else {
|
||||
|
@ -165,7 +165,7 @@ pub(crate) fn yoda_conditions(
|
|||
|
||||
if !matches!(
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -225,8 +225,9 @@ fn function(
|
|||
let args = args
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(args.args.iter())
|
||||
.chain(args.kwonlyargs.iter())
|
||||
.chain(&args.args)
|
||||
.chain(&args.kwonlyargs)
|
||||
.map(|arg_with_default| &arg_with_default.def)
|
||||
.chain(
|
||||
iter::once::<Option<&Arg>>(args.vararg.as_deref())
|
||||
.flatten()
|
||||
|
@ -252,9 +253,10 @@ fn method(
|
|||
let args = args
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(args.args.iter())
|
||||
.chain(&args.args)
|
||||
.chain(&args.kwonlyargs)
|
||||
.skip(1)
|
||||
.chain(args.kwonlyargs.iter())
|
||||
.map(|arg_with_default| &arg_with_default.def)
|
||||
.chain(
|
||||
iter::once::<Option<&Arg>>(args.vararg.as_deref())
|
||||
.flatten()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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::statement_visitor::StatementVisitor;
|
||||
|
@ -267,8 +267,8 @@ where
|
|||
finalbody,
|
||||
range: _,
|
||||
}) => {
|
||||
for excepthandler in handlers {
|
||||
self.visit_excepthandler(excepthandler);
|
||||
for except_handler in handlers {
|
||||
self.visit_except_handler(except_handler);
|
||||
}
|
||||
|
||||
for stmt in body {
|
||||
|
@ -291,12 +291,12 @@ where
|
|||
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;
|
||||
self.nested = true;
|
||||
|
||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) =
|
||||
excepthandler;
|
||||
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { body, .. }) =
|
||||
except_handler;
|
||||
for stmt in body {
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -117,7 +117,7 @@ fn get_complexity_number(stmts: &[Stmt]) -> usize {
|
|||
complexity += get_complexity_number(finalbody);
|
||||
for handler in handlers {
|
||||
complexity += 1;
|
||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||
body, ..
|
||||
}) = handler;
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -74,8 +74,13 @@ pub(crate) fn invalid_first_argument_name_for_class_method(
|
|||
) {
|
||||
return None;
|
||||
}
|
||||
if let Some(arg) = args.posonlyargs.first().or_else(|| args.args.first()) {
|
||||
if &arg.arg != "cls" {
|
||||
if let Some(ArgWithDefault {
|
||||
def,
|
||||
default: _,
|
||||
range: _,
|
||||
}) = args.posonlyargs.first().or_else(|| args.args.first())
|
||||
{
|
||||
if &def.arg != "cls" {
|
||||
if checker
|
||||
.settings
|
||||
.pep8_naming
|
||||
|
@ -87,7 +92,7 @@ pub(crate) fn invalid_first_argument_name_for_class_method(
|
|||
}
|
||||
return Some(Diagnostic::new(
|
||||
InvalidFirstArgumentNameForClassMethod,
|
||||
arg.range(),
|
||||
def.range(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ pub(crate) fn invalid_first_argument_name_for_method(
|
|||
return None;
|
||||
}
|
||||
let arg = args.posonlyargs.first().or_else(|| args.args.first())?;
|
||||
if &arg.arg == "self" {
|
||||
if &arg.def.arg == "self" {
|
||||
return None;
|
||||
}
|
||||
if checker
|
||||
|
@ -87,6 +87,6 @@ pub(crate) fn invalid_first_argument_name_for_method(
|
|||
}
|
||||
Some(Diagnostic::new(
|
||||
InvalidFirstArgumentNameForMethod,
|
||||
arg.range(),
|
||||
arg.def.range(),
|
||||
))
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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 ruff_python_ast::source_code::Generator;
|
||||
|
@ -13,7 +13,7 @@ pub(crate) fn is_ambiguous_name(name: &str) -> bool {
|
|||
|
||||
pub(crate) fn compare(
|
||||
left: &Expr,
|
||||
ops: &[Cmpop],
|
||||
ops: &[CmpOp],
|
||||
comparators: &[Expr],
|
||||
generator: Generator,
|
||||
) -> 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_macros::{derive_message_formats, violation};
|
||||
|
@ -58,7 +58,7 @@ impl Violation for BareExcept {
|
|||
pub(crate) fn bare_except(
|
||||
type_: Option<&Expr>,
|
||||
body: &[Stmt],
|
||||
handler: &Excepthandler,
|
||||
handler: &ExceptHandler,
|
||||
locator: &Locator,
|
||||
) -> Option<Diagnostic> {
|
||||
if type_.is_none()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -176,22 +176,28 @@ fn function(
|
|||
.posonlyargs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, arg)| Arg {
|
||||
annotation: arg_types
|
||||
.get(idx)
|
||||
.map(|arg_type| Box::new(arg_type.clone())),
|
||||
..arg.clone()
|
||||
.map(|(idx, arg_with_default)| ArgWithDefault {
|
||||
def: Arg {
|
||||
annotation: arg_types
|
||||
.get(idx)
|
||||
.map(|arg_type| Box::new(arg_type.clone())),
|
||||
..arg_with_default.def.clone()
|
||||
},
|
||||
..arg_with_default.clone()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let new_args = args
|
||||
.args
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, arg)| Arg {
|
||||
annotation: arg_types
|
||||
.get(idx + new_posonlyargs.len())
|
||||
.map(|arg_type| Box::new(arg_type.clone())),
|
||||
..arg.clone()
|
||||
.map(|(idx, arg_with_default)| ArgWithDefault {
|
||||
def: Arg {
|
||||
annotation: arg_types
|
||||
.get(idx + new_posonlyargs.len())
|
||||
.map(|arg_type| Box::new(arg_type.clone())),
|
||||
..arg_with_default.def.clone()
|
||||
},
|
||||
..arg_with_default.clone()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let func = Stmt::FunctionDef(ast::StmtFunctionDef {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use itertools::izip;
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -12,16 +12,16 @@ use crate::registry::AsRule;
|
|||
use crate::rules::pycodestyle::helpers::compare;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
enum EqCmpop {
|
||||
enum EqCmpOp {
|
||||
Eq,
|
||||
NotEq,
|
||||
}
|
||||
|
||||
impl EqCmpop {
|
||||
fn try_from(value: Cmpop) -> Option<EqCmpop> {
|
||||
impl EqCmpOp {
|
||||
fn try_from(value: CmpOp) -> Option<EqCmpOp> {
|
||||
match value {
|
||||
Cmpop::Eq => Some(EqCmpop::Eq),
|
||||
Cmpop::NotEq => Some(EqCmpop::NotEq),
|
||||
CmpOp::Eq => Some(EqCmpOp::Eq),
|
||||
CmpOp::NotEq => Some(EqCmpOp::NotEq),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -50,23 +50,23 @@ impl EqCmpop {
|
|||
///
|
||||
/// [PEP 8]: https://peps.python.org/pep-0008/#programming-recommendations
|
||||
#[violation]
|
||||
pub struct NoneComparison(EqCmpop);
|
||||
pub struct NoneComparison(EqCmpOp);
|
||||
|
||||
impl AlwaysAutofixableViolation for NoneComparison {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let NoneComparison(op) = self;
|
||||
match op {
|
||||
EqCmpop::Eq => format!("Comparison to `None` should be `cond is None`"),
|
||||
EqCmpop::NotEq => format!("Comparison to `None` should be `cond is not None`"),
|
||||
EqCmpOp::Eq => format!("Comparison to `None` should be `cond is None`"),
|
||||
EqCmpOp::NotEq => format!("Comparison to `None` should be `cond is not None`"),
|
||||
}
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let NoneComparison(op) = self;
|
||||
match op {
|
||||
EqCmpop::Eq => "Replace with `cond is None`".to_string(),
|
||||
EqCmpop::NotEq => "Replace with `cond is not None`".to_string(),
|
||||
EqCmpOp::Eq => "Replace with `cond is 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
|
||||
#[violation]
|
||||
pub struct TrueFalseComparison(bool, EqCmpop);
|
||||
pub struct TrueFalseComparison(bool, EqCmpOp);
|
||||
|
||||
impl AlwaysAutofixableViolation for TrueFalseComparison {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let TrueFalseComparison(value, op) = self;
|
||||
match (value, op) {
|
||||
(true, EqCmpop::Eq) => {
|
||||
(true, EqCmpOp::Eq) => {
|
||||
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:`")
|
||||
}
|
||||
(false, EqCmpop::Eq) => {
|
||||
(false, EqCmpOp::Eq) => {
|
||||
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:`")
|
||||
}
|
||||
}
|
||||
|
@ -121,10 +121,10 @@ impl AlwaysAutofixableViolation for TrueFalseComparison {
|
|||
fn autofix_title(&self) -> String {
|
||||
let TrueFalseComparison(value, op) = self;
|
||||
match (value, op) {
|
||||
(true, EqCmpop::Eq) => "Replace with `cond is 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::NotEq) => "Replace with `cond is not False`".to_string(),
|
||||
(true, EqCmpOp::Eq) => "Replace with `cond is 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::NotEq) => "Replace with `cond is not False`".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ pub(crate) fn literal_comparisons(
|
|||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
left: &Expr,
|
||||
ops: &[Cmpop],
|
||||
ops: &[CmpOp],
|
||||
comparators: &[Expr],
|
||||
check_none_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,
|
||||
// then replace the entire expression at the end with one "real" fix, to
|
||||
// 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 op = ops.first().unwrap();
|
||||
|
@ -153,20 +153,20 @@ pub(crate) fn literal_comparisons(
|
|||
let next = &comparators[0];
|
||||
|
||||
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) {
|
||||
match op {
|
||||
EqCmpop::Eq => {
|
||||
EqCmpOp::Eq => {
|
||||
let diagnostic = Diagnostic::new(NoneComparison(op), comparator.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
bad_ops.insert(0, Cmpop::Is);
|
||||
bad_ops.insert(0, CmpOp::Is);
|
||||
}
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
EqCmpop::NotEq => {
|
||||
EqCmpOp::NotEq => {
|
||||
let diagnostic = Diagnostic::new(NoneComparison(op), comparator.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
bad_ops.insert(0, Cmpop::IsNot);
|
||||
bad_ops.insert(0, CmpOp::IsNot);
|
||||
}
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
|
@ -181,23 +181,23 @@ pub(crate) fn literal_comparisons(
|
|||
}) = comparator
|
||||
{
|
||||
match op {
|
||||
EqCmpop::Eq => {
|
||||
EqCmpOp::Eq => {
|
||||
let diagnostic = Diagnostic::new(
|
||||
TrueFalseComparison(*value, op),
|
||||
comparator.range(),
|
||||
);
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
bad_ops.insert(0, Cmpop::Is);
|
||||
bad_ops.insert(0, CmpOp::Is);
|
||||
}
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
EqCmpop::NotEq => {
|
||||
EqCmpOp::NotEq => {
|
||||
let diagnostic = Diagnostic::new(
|
||||
TrueFalseComparison(*value, op),
|
||||
comparator.range(),
|
||||
);
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
bad_ops.insert(0, Cmpop::IsNot);
|
||||
bad_ops.insert(0, CmpOp::IsNot);
|
||||
}
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
|
@ -214,20 +214,20 @@ pub(crate) fn literal_comparisons(
|
|||
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) {
|
||||
match op {
|
||||
EqCmpop::Eq => {
|
||||
EqCmpOp::Eq => {
|
||||
let diagnostic = Diagnostic::new(NoneComparison(op), next.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
bad_ops.insert(idx, Cmpop::Is);
|
||||
bad_ops.insert(idx, CmpOp::Is);
|
||||
}
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
EqCmpop::NotEq => {
|
||||
EqCmpOp::NotEq => {
|
||||
let diagnostic = Diagnostic::new(NoneComparison(op), next.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
bad_ops.insert(idx, Cmpop::IsNot);
|
||||
bad_ops.insert(idx, CmpOp::IsNot);
|
||||
}
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
|
@ -242,19 +242,19 @@ pub(crate) fn literal_comparisons(
|
|||
}) = next
|
||||
{
|
||||
match op {
|
||||
EqCmpop::Eq => {
|
||||
EqCmpOp::Eq => {
|
||||
let diagnostic =
|
||||
Diagnostic::new(TrueFalseComparison(*value, op), next.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
bad_ops.insert(idx, Cmpop::Is);
|
||||
bad_ops.insert(idx, CmpOp::Is);
|
||||
}
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
EqCmpop::NotEq => {
|
||||
EqCmpOp::NotEq => {
|
||||
let diagnostic =
|
||||
Diagnostic::new(TrueFalseComparison(*value, op), next.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
bad_ops.insert(idx, Cmpop::IsNot);
|
||||
bad_ops.insert(idx, CmpOp::IsNot);
|
||||
}
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -77,12 +77,12 @@ impl AlwaysAutofixableViolation for NotIsTest {
|
|||
pub(crate) fn not_tests(
|
||||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
op: Unaryop,
|
||||
op: UnaryOp,
|
||||
operand: &Expr,
|
||||
check_not_in: bool,
|
||||
check_not_is: bool,
|
||||
) {
|
||||
if matches!(op, Unaryop::Not) {
|
||||
if matches!(op, UnaryOp::Not) {
|
||||
if let Expr::Compare(ast::ExprCompare {
|
||||
left,
|
||||
ops,
|
||||
|
@ -90,19 +90,19 @@ pub(crate) fn not_tests(
|
|||
range: _,
|
||||
}) = operand
|
||||
{
|
||||
if !matches!(&ops[..], [Cmpop::In | Cmpop::Is]) {
|
||||
if !matches!(&ops[..], [CmpOp::In | CmpOp::Is]) {
|
||||
return;
|
||||
}
|
||||
for op in ops.iter() {
|
||||
match op {
|
||||
Cmpop::In => {
|
||||
CmpOp::In => {
|
||||
if check_not_in {
|
||||
let mut diagnostic = Diagnostic::new(NotInTest, operand.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.set_fix(Fix::automatic(Edit::range_replacement(
|
||||
compare(
|
||||
left,
|
||||
&[Cmpop::NotIn],
|
||||
&[CmpOp::NotIn],
|
||||
comparators,
|
||||
checker.generator(),
|
||||
),
|
||||
|
@ -112,14 +112,14 @@ pub(crate) fn not_tests(
|
|||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
Cmpop::Is => {
|
||||
CmpOp::Is => {
|
||||
if check_not_is {
|
||||
let mut diagnostic = Diagnostic::new(NotIsTest, operand.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
diagnostic.set_fix(Fix::automatic(Edit::range_replacement(
|
||||
compare(
|
||||
left,
|
||||
&[Cmpop::IsNot],
|
||||
&[CmpOp::IsNot],
|
||||
comparators,
|
||||
checker.generator(),
|
||||
),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -41,11 +41,11 @@ impl Violation for TypeComparison {
|
|||
pub(crate) fn type_comparison(
|
||||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
ops: &[Cmpop],
|
||||
ops: &[CmpOp],
|
||||
comparators: &[Expr],
|
||||
) {
|
||||
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;
|
||||
}
|
||||
match right {
|
||||
|
|
|
@ -3,7 +3,7 @@ use once_cell::sync::Lazy;
|
|||
use regex::Regex;
|
||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||
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::{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.
|
||||
let mut missing_arg_names: FxHashSet<String> = FxHashSet::default();
|
||||
for arg in arguments
|
||||
for ArgWithDefault {
|
||||
def,
|
||||
default: _,
|
||||
range: _,
|
||||
} in arguments
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(arguments.args.iter())
|
||||
.chain(arguments.kwonlyargs.iter())
|
||||
.chain(&arguments.args)
|
||||
.chain(&arguments.kwonlyargs)
|
||||
.skip(
|
||||
// If this is a non-static method, skip `cls` or `self`.
|
||||
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) {
|
||||
missing_arg_names.insert(arg_name.to_string());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::{bail, Ok, Result};
|
||||
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 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.
|
||||
pub(crate) fn remove_exception_handler_assignment(
|
||||
excepthandler: &Excepthandler,
|
||||
except_handler: &ExceptHandler,
|
||||
locator: &Locator,
|
||||
) -> Result<Edit> {
|
||||
let contents = locator.slice(excepthandler.range());
|
||||
let contents = locator.slice(except_handler.range());
|
||||
let mut fix_start = None;
|
||||
let mut fix_end = None;
|
||||
|
||||
// End of the token just before the `as` to the semicolon.
|
||||
let mut prev = None;
|
||||
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) {
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -55,11 +55,11 @@ impl Violation for DefaultExceptNotLast {
|
|||
|
||||
/// F707
|
||||
pub(crate) fn default_except_not_last(
|
||||
handlers: &[Excepthandler],
|
||||
handlers: &[ExceptHandler],
|
||||
locator: &Locator,
|
||||
) -> Option<Diagnostic> {
|
||||
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 {
|
||||
return Some(Diagnostic::new(
|
||||
DefaultExceptNotLast,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use itertools::izip;
|
||||
use log::error;
|
||||
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_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/)
|
||||
#[violation]
|
||||
pub struct IsLiteral {
|
||||
cmpop: IsCmpop,
|
||||
cmp_op: IsCmpOp,
|
||||
}
|
||||
|
||||
impl AlwaysAutofixableViolation for IsLiteral {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
let IsLiteral { cmpop } = self;
|
||||
match cmpop {
|
||||
IsCmpop::Is => format!("Use `==` to compare constant literals"),
|
||||
IsCmpop::IsNot => format!("Use `!=` to compare constant literals"),
|
||||
let IsLiteral { cmp_op } = self;
|
||||
match cmp_op {
|
||||
IsCmpOp::Is => format!("Use `==` to compare constant literals"),
|
||||
IsCmpOp::IsNot => format!("Use `!=` to compare constant literals"),
|
||||
}
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
let IsLiteral { cmpop } = self;
|
||||
match cmpop {
|
||||
IsCmpop::Is => "Replace `is` with `==`".to_string(),
|
||||
IsCmpop::IsNot => "Replace `is not` with `!=`".to_string(),
|
||||
let IsLiteral { cmp_op } = self;
|
||||
match cmp_op {
|
||||
IsCmpOp::Is => "Replace `is` 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(
|
||||
checker: &mut Checker,
|
||||
left: &Expr,
|
||||
ops: &[Cmpop],
|
||||
ops: &[CmpOp],
|
||||
comparators: &[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;
|
||||
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(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 let Some(located_op) = &located.get(index) {
|
||||
assert_eq!(located_op.op, *op);
|
||||
if let Some(content) = match located_op.op {
|
||||
Cmpop::Is => Some("==".to_string()),
|
||||
Cmpop::IsNot => Some("!=".to_string()),
|
||||
CmpOp::Is => Some("==".to_string()),
|
||||
CmpOp::IsNot => Some("!=".to_string()),
|
||||
node => {
|
||||
error!("Failed to fix invalid comparison: {node:?}");
|
||||
None
|
||||
|
@ -112,17 +112,17 @@ pub(crate) fn invalid_literal_comparison(
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
enum IsCmpop {
|
||||
enum IsCmpOp {
|
||||
Is,
|
||||
IsNot,
|
||||
}
|
||||
|
||||
impl From<&Cmpop> for IsCmpop {
|
||||
fn from(cmpop: &Cmpop) -> Self {
|
||||
match cmpop {
|
||||
Cmpop::Is => IsCmpop::Is,
|
||||
Cmpop::IsNot => IsCmpop::IsNot,
|
||||
_ => panic!("Expected Cmpop::Is | Cmpop::IsNot"),
|
||||
impl From<&CmpOp> for IsCmpOp {
|
||||
fn from(cmp_op: &CmpOp) -> Self {
|
||||
match cmp_op {
|
||||
CmpOp::Is => IsCmpOp::Is,
|
||||
CmpOp::IsNot => IsCmpOp::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 {
|
||||
// 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 {
|
||||
if let Some(optional_vars) = &item.optional_vars {
|
||||
if optional_vars.range() == range {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::fmt;
|
||||
|
||||
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::{ScopeKind, SemanticModel};
|
||||
|
@ -47,29 +47,29 @@ pub(super) fn in_dunder_init(semantic: &SemanticModel, settings: &Settings) -> b
|
|||
true
|
||||
}
|
||||
|
||||
/// A wrapper around [`Cmpop`] that implements `Display`.
|
||||
/// A wrapper around [`CmpOp`] that implements `Display`.
|
||||
#[derive(Debug)]
|
||||
pub(super) struct CmpopExt(Cmpop);
|
||||
pub(super) struct CmpOpExt(CmpOp);
|
||||
|
||||
impl From<&Cmpop> for CmpopExt {
|
||||
fn from(cmpop: &Cmpop) -> Self {
|
||||
CmpopExt(*cmpop)
|
||||
impl From<&CmpOp> for CmpOpExt {
|
||||
fn from(cmp_op: &CmpOp) -> Self {
|
||||
CmpOpExt(*cmp_op)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CmpopExt {
|
||||
impl fmt::Display for CmpOpExt {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let representation = match self.0 {
|
||||
Cmpop::Eq => "==",
|
||||
Cmpop::NotEq => "!=",
|
||||
Cmpop::Lt => "<",
|
||||
Cmpop::LtE => "<=",
|
||||
Cmpop::Gt => ">",
|
||||
Cmpop::GtE => ">=",
|
||||
Cmpop::Is => "is",
|
||||
Cmpop::IsNot => "is not",
|
||||
Cmpop::In => "in",
|
||||
Cmpop::NotIn => "not in",
|
||||
CmpOp::Eq => "==",
|
||||
CmpOp::NotEq => "!=",
|
||||
CmpOp::Lt => "<",
|
||||
CmpOp::LtE => "<=",
|
||||
CmpOp::Gt => ">",
|
||||
CmpOp::GtE => ">=",
|
||||
CmpOp::Is => "is",
|
||||
CmpOp::IsNot => "is not",
|
||||
CmpOp::In => "in",
|
||||
CmpOp::NotIn => "not in",
|
||||
};
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -6,16 +6,16 @@ use ruff_macros::{derive_message_formats, violation};
|
|||
use crate::checkers::ast::Checker;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
enum Boolop {
|
||||
enum BoolOp {
|
||||
And,
|
||||
Or,
|
||||
}
|
||||
|
||||
impl From<&ast::Boolop> for Boolop {
|
||||
fn from(op: &ast::Boolop) -> Self {
|
||||
impl From<&ast::BoolOp> for BoolOp {
|
||||
fn from(op: &ast::BoolOp) -> Self {
|
||||
match op {
|
||||
ast::Boolop::And => Boolop::And,
|
||||
ast::Boolop::Or => Boolop::Or,
|
||||
ast::BoolOp::And => BoolOp::And,
|
||||
ast::BoolOp::Or => BoolOp::Or,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ impl From<&ast::Boolop> for Boolop {
|
|||
/// ```
|
||||
#[violation]
|
||||
pub struct BinaryOpException {
|
||||
op: Boolop,
|
||||
op: BoolOp,
|
||||
}
|
||||
|
||||
impl Violation for BinaryOpException {
|
||||
|
@ -55,15 +55,16 @@ impl Violation for BinaryOpException {
|
|||
fn message(&self) -> String {
|
||||
let BinaryOpException { op } = self;
|
||||
match op {
|
||||
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::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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// PLW0711
|
||||
pub(crate) fn binary_op_exception(checker: &mut Checker, excepthandler: &Excepthandler) {
|
||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = excepthandler;
|
||||
pub(crate) fn binary_op_exception(checker: &mut Checker, except_handler: &ExceptHandler) {
|
||||
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, .. }) =
|
||||
except_handler;
|
||||
|
||||
let Some(type_) = type_ else {
|
||||
return;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::bail;
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -8,28 +8,28 @@ use ruff_macros::{derive_message_formats, violation};
|
|||
use crate::checkers::ast::Checker;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub(crate) enum EmptyStringCmpop {
|
||||
pub(crate) enum EmptyStringCmpOp {
|
||||
Is,
|
||||
IsNot,
|
||||
Eq,
|
||||
NotEq,
|
||||
}
|
||||
|
||||
impl TryFrom<&Cmpop> for EmptyStringCmpop {
|
||||
impl TryFrom<&CmpOp> for EmptyStringCmpOp {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: &Cmpop) -> Result<Self, Self::Error> {
|
||||
fn try_from(value: &CmpOp) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
Cmpop::Is => Ok(Self::Is),
|
||||
Cmpop::IsNot => Ok(Self::IsNot),
|
||||
Cmpop::Eq => Ok(Self::Eq),
|
||||
Cmpop::NotEq => Ok(Self::NotEq),
|
||||
_ => bail!("{value:?} cannot be converted to EmptyStringCmpop"),
|
||||
CmpOp::Is => Ok(Self::Is),
|
||||
CmpOp::IsNot => Ok(Self::IsNot),
|
||||
CmpOp::Eq => Ok(Self::Eq),
|
||||
CmpOp::NotEq => Ok(Self::NotEq),
|
||||
_ => bail!("{value:?} cannot be converted to EmptyStringCmpOp"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EmptyStringCmpop {
|
||||
impl EmptyStringCmpOp {
|
||||
pub(crate) fn into_unary(self) -> &'static str {
|
||||
match self {
|
||||
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 {
|
||||
let repr = match self {
|
||||
Self::Is => "is",
|
||||
|
@ -93,7 +93,7 @@ impl Violation for CompareToEmptyString {
|
|||
pub(crate) fn compare_to_empty_string(
|
||||
checker: &mut Checker,
|
||||
left: &Expr,
|
||||
ops: &[Cmpop],
|
||||
ops: &[CmpOp],
|
||||
comparators: &[Expr],
|
||||
) {
|
||||
// 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<_>)>()
|
||||
.zip(ops)
|
||||
{
|
||||
if let Ok(op) = EmptyStringCmpop::try_from(op) {
|
||||
if let Ok(op) = EmptyStringCmpOp::try_from(op) {
|
||||
if std::mem::take(&mut first) {
|
||||
// Check the left-most expression.
|
||||
if let Expr::Constant(ast::ExprConstant { value, .. }) = &lhs {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::pylint::helpers::CmpopExt;
|
||||
use crate::rules::pylint::helpers::CmpOpExt;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for comparisons between constants.
|
||||
|
@ -30,7 +30,7 @@ use crate::rules::pylint::helpers::CmpopExt;
|
|||
#[violation]
|
||||
pub struct ComparisonOfConstant {
|
||||
left_constant: String,
|
||||
op: Cmpop,
|
||||
op: CmpOp,
|
||||
right_constant: String,
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ impl Violation for ComparisonOfConstant {
|
|||
|
||||
format!(
|
||||
"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(
|
||||
checker: &mut Checker,
|
||||
left: &Expr,
|
||||
ops: &[Cmpop],
|
||||
ops: &[CmpOp],
|
||||
comparators: &[Expr],
|
||||
) {
|
||||
for ((left, right), op) in std::iter::once(left)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use itertools::Itertools;
|
||||
use rustpython_parser::ast::{Cmpop, Expr, Ranged};
|
||||
use rustpython_parser::ast::{CmpOp, Expr, Ranged};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::pylint::helpers::CmpopExt;
|
||||
use crate::rules::pylint::helpers::CmpOpExt;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for operations that compare a name to itself.
|
||||
|
@ -24,7 +24,7 @@ use crate::rules::pylint::helpers::CmpopExt;
|
|||
#[violation]
|
||||
pub struct ComparisonWithItself {
|
||||
left: String,
|
||||
op: Cmpop,
|
||||
op: CmpOp,
|
||||
right: String,
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ impl Violation for ComparisonWithItself {
|
|||
let ComparisonWithItself { left, op, right } = self;
|
||||
format!(
|
||||
"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(
|
||||
checker: &mut Checker,
|
||||
left: &Expr,
|
||||
ops: &[Cmpop],
|
||||
ops: &[CmpOp],
|
||||
comparators: &[Expr],
|
||||
) {
|
||||
for ((left, right), op) in std::iter::once(left)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -55,7 +55,7 @@ fn as_constant(expr: &Expr) -> Option<&Constant> {
|
|||
match expr {
|
||||
Expr::Constant(ast::ExprConstant { value, .. }) => Some(value),
|
||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::UAdd | Unaryop::USub | Unaryop::Invert,
|
||||
op: UnaryOp::UAdd | UnaryOp::USub | UnaryOp::Invert,
|
||||
operand,
|
||||
range: _,
|
||||
}) => match operand.as_ref() {
|
||||
|
|
|
@ -59,14 +59,14 @@ pub(crate) fn property_with_parameters(
|
|||
{
|
||||
return;
|
||||
}
|
||||
if checker.semantic().is_builtin("property")
|
||||
&& args
|
||||
.args
|
||||
.iter()
|
||||
.chain(args.posonlyargs.iter())
|
||||
.chain(args.kwonlyargs.iter())
|
||||
.count()
|
||||
> 1
|
||||
if args
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.chain(&args.args)
|
||||
.chain(&args.kwonlyargs)
|
||||
.count()
|
||||
> 1
|
||||
&& checker.semantic().is_builtin("property")
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
PropertyWithParameters,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{fmt, iter};
|
||||
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -308,7 +308,7 @@ fn assignment_targets_from_expr<'a>(
|
|||
}
|
||||
|
||||
fn assignment_targets_from_with_items<'a>(
|
||||
items: &'a [Withitem],
|
||||
items: &'a [WithItem],
|
||||
dummy_variable_rgx: &'a Regex,
|
||||
) -> impl Iterator<Item = &'a Expr> + 'a {
|
||||
items
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use itertools::Itertools;
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -63,7 +63,7 @@ impl AlwaysAutofixableViolation for RepeatedIsinstanceCalls {
|
|||
pub(crate) fn repeated_isinstance_calls(
|
||||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
op: Boolop,
|
||||
op: BoolOp,
|
||||
values: &[Expr],
|
||||
) {
|
||||
if !op.is_or() {
|
||||
|
|
|
@ -58,18 +58,18 @@ impl Violation for TooManyArguments {
|
|||
}
|
||||
|
||||
/// PLR0913
|
||||
pub(crate) fn too_many_arguments(checker: &mut Checker, args: &Arguments, stmt: &Stmt) {
|
||||
let num_args = args
|
||||
pub(crate) fn too_many_arguments(checker: &mut Checker, arguments: &Arguments, stmt: &Stmt) {
|
||||
let num_arguments = arguments
|
||||
.args
|
||||
.iter()
|
||||
.chain(args.kwonlyargs.iter())
|
||||
.chain(args.posonlyargs.iter())
|
||||
.filter(|arg| !checker.settings.dummy_variable_rgx.is_match(&arg.arg))
|
||||
.chain(&arguments.kwonlyargs)
|
||||
.chain(&arguments.posonlyargs)
|
||||
.filter(|arg| !checker.settings.dummy_variable_rgx.is_match(&arg.def.arg))
|
||||
.count();
|
||||
if num_args > checker.settings.pylint.max_args {
|
||||
if num_arguments > checker.settings.pylint.max_args {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
TooManyArguments {
|
||||
c_args: num_args,
|
||||
c_args: num_arguments,
|
||||
max_args: checker.settings.pylint.max_args,
|
||||
},
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -147,8 +147,8 @@ fn num_branches(stmts: &[Stmt]) -> usize {
|
|||
.iter()
|
||||
.map(|handler| {
|
||||
1 + {
|
||||
let Excepthandler::ExceptHandler(
|
||||
ast::ExcepthandlerExceptHandler { body, .. },
|
||||
let ExceptHandler::ExceptHandler(
|
||||
ast::ExceptHandlerExceptHandler { body, .. },
|
||||
) = handler;
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -123,7 +123,7 @@ fn num_statements(stmts: &[Stmt]) -> usize {
|
|||
}
|
||||
for handler in handlers {
|
||||
count += 1;
|
||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||
body, ..
|
||||
}) = handler;
|
||||
count += num_statements(body);
|
||||
|
|
|
@ -160,8 +160,7 @@ pub(crate) fn unexpected_special_method_signature(
|
|||
}
|
||||
|
||||
let actual_params = args.args.len();
|
||||
let optional_params = args.defaults.len();
|
||||
let mandatory_params = actual_params - optional_params;
|
||||
let mandatory_params = args.args.iter().filter(|arg| arg.default.is_none()).count();
|
||||
|
||||
let Some(expected_params) = ExpectedParams::from_method(name, is_staticmethod(decorator_list, checker.semantic())) else {
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -79,7 +79,7 @@ fn loop_exits_early(body: &[Stmt]) -> bool {
|
|||
|| loop_exits_early(orelse)
|
||||
|| loop_exits_early(finalbody)
|
||||
|| handlers.iter().any(|handler| match handler {
|
||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||
body, ..
|
||||
}) => loop_exits_early(body),
|
||||
})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -151,9 +151,9 @@ fn tuple_diagnostic(checker: &mut Checker, target: &Expr, aliases: &[&Expr]) {
|
|||
}
|
||||
|
||||
/// 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 {
|
||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) = handler;
|
||||
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, .. }) = handler;
|
||||
let Some(expr) = type_.as_ref() else {
|
||||
continue;
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::cmp::Ordering;
|
|||
|
||||
use num_bigint::{BigInt, Sign};
|
||||
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 ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||
|
@ -370,8 +370,8 @@ pub(crate) fn outdated_version_block(
|
|||
Expr::Tuple(ast::ExprTuple { elts, .. }) => {
|
||||
let version = extract_version(elts);
|
||||
let target = checker.settings.target_version;
|
||||
if op == &Cmpop::Lt || op == &Cmpop::LtE {
|
||||
if compare_version(&version, target, op == &Cmpop::LtE) {
|
||||
if op == &CmpOp::Lt || op == &CmpOp::LtE {
|
||||
if compare_version(&version, target, op == &CmpOp::LtE) {
|
||||
let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
if let Some(block) = metadata(checker.locator, stmt, body) {
|
||||
|
@ -382,8 +382,8 @@ pub(crate) fn outdated_version_block(
|
|||
}
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
} else if op == &Cmpop::Gt || op == &Cmpop::GtE {
|
||||
if compare_version(&version, target, op == &Cmpop::GtE) {
|
||||
} else if op == &CmpOp::Gt || op == &CmpOp::GtE {
|
||||
if compare_version(&version, target, op == &CmpOp::GtE) {
|
||||
let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
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);
|
||||
if version_number == 2 && op == &Cmpop::Eq {
|
||||
if version_number == 2 && op == &CmpOp::Eq {
|
||||
let mut diagnostic = Diagnostic::new(OutdatedVersionBlock, stmt.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
if let Some(block) = metadata(checker.locator, stmt, body) {
|
||||
|
@ -412,7 +412,7 @@ pub(crate) fn outdated_version_block(
|
|||
}
|
||||
}
|
||||
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());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
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_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.
|
||||
let Some(Arg {
|
||||
arg: parent_arg, ..
|
||||
let Some(ArgWithDefault {
|
||||
def: Arg { arg: parent_arg, .. },
|
||||
..
|
||||
}) = parent_args.args.first() else {
|
||||
return;
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use std::fmt;
|
||||
|
||||
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_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::helpers::is_const_none;
|
||||
use ruff_python_semantic::SemanticModel;
|
||||
use ruff_text_size::TextRange;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::importer::ImportRequest;
|
||||
|
@ -307,24 +307,23 @@ fn generate_fix(checker: &Checker, conversion_type: ConversionType, expr: &Expr)
|
|||
|
||||
/// RUF011
|
||||
pub(crate) fn implicit_optional(checker: &mut Checker, arguments: &Arguments) {
|
||||
let arguments_with_defaults = arguments
|
||||
.kwonlyargs
|
||||
for ArgWithDefault {
|
||||
def,
|
||||
default,
|
||||
range: _,
|
||||
} in arguments
|
||||
.posonlyargs
|
||||
.iter()
|
||||
.rev()
|
||||
.zip(arguments.kw_defaults.iter().rev())
|
||||
.chain(
|
||||
arguments
|
||||
.args
|
||||
.iter()
|
||||
.rev()
|
||||
.chain(arguments.posonlyargs.iter().rev())
|
||||
.zip(arguments.defaults.iter().rev()),
|
||||
);
|
||||
for (arg, default) in arguments_with_defaults {
|
||||
.chain(&arguments.args)
|
||||
.chain(&arguments.kwonlyargs)
|
||||
{
|
||||
let Some(default) = default else {
|
||||
continue
|
||||
};
|
||||
if !is_const_none(default) {
|
||||
continue;
|
||||
}
|
||||
let Some(annotation) = &arg.annotation else {
|
||||
let Some(annotation) = &def.annotation else {
|
||||
continue
|
||||
};
|
||||
let Some(expr) = type_hint_explicitly_allows_none(annotation, checker.semantic()) else {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -69,7 +69,7 @@ fn to_bound(expr: &Expr) -> Option<i64> {
|
|||
..
|
||||
}) => value.to_i64(),
|
||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::USub | Unaryop::Invert,
|
||||
op: UnaryOp::USub | UnaryOp::Invert,
|
||||
operand,
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -54,9 +54,9 @@ impl Violation for ErrorInsteadOfException {
|
|||
}
|
||||
|
||||
/// 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 {
|
||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) = handler;
|
||||
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { body, .. }) = handler;
|
||||
let calls = {
|
||||
let mut visitor = LoggerCandidateVisitor::new(checker.semantic());
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -72,7 +72,7 @@ where
|
|||
}
|
||||
|
||||
/// 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() {
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -60,7 +60,7 @@ pub(crate) fn try_consider_else(
|
|||
checker: &mut Checker,
|
||||
body: &[Stmt],
|
||||
orelse: &[Stmt],
|
||||
handler: &[Excepthandler],
|
||||
handler: &[ExceptHandler],
|
||||
) {
|
||||
if body.len() > 1 && orelse.is_empty() && !handler.is_empty() {
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -39,11 +38,12 @@ impl Violation for UselessTryExcept {
|
|||
}
|
||||
|
||||
/// 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
|
||||
.iter()
|
||||
.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 {
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -57,9 +57,9 @@ impl<'a> Visitor<'a> for NameVisitor<'a> {
|
|||
}
|
||||
|
||||
/// 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 {
|
||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { name, body, .. }) =
|
||||
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { name, body, .. }) =
|
||||
handler;
|
||||
let Some(target) = name else {
|
||||
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_macros::{derive_message_formats, violation};
|
||||
|
@ -74,10 +74,10 @@ where
|
|||
}
|
||||
|
||||
/// 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 {
|
||||
// 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),
|
||||
body,
|
||||
..
|
||||
|
|
|
@ -22,16 +22,16 @@ impl From<&ast::ExprContext> for ComparableExprContext {
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum ComparableBoolop {
|
||||
pub enum ComparableBoolOp {
|
||||
And,
|
||||
Or,
|
||||
}
|
||||
|
||||
impl From<ast::Boolop> for ComparableBoolop {
|
||||
fn from(op: ast::Boolop) -> Self {
|
||||
impl From<ast::BoolOp> for ComparableBoolOp {
|
||||
fn from(op: ast::BoolOp) -> Self {
|
||||
match op {
|
||||
ast::Boolop::And => Self::And,
|
||||
ast::Boolop::Or => Self::Or,
|
||||
ast::BoolOp::And => Self::And,
|
||||
ast::BoolOp::Or => Self::Or,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,26 +74,26 @@ impl From<ast::Operator> for ComparableOperator {
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum ComparableUnaryop {
|
||||
pub enum ComparableUnaryOp {
|
||||
Invert,
|
||||
Not,
|
||||
UAdd,
|
||||
USub,
|
||||
}
|
||||
|
||||
impl From<ast::Unaryop> for ComparableUnaryop {
|
||||
fn from(op: ast::Unaryop) -> Self {
|
||||
impl From<ast::UnaryOp> for ComparableUnaryOp {
|
||||
fn from(op: ast::UnaryOp) -> Self {
|
||||
match op {
|
||||
ast::Unaryop::Invert => Self::Invert,
|
||||
ast::Unaryop::Not => Self::Not,
|
||||
ast::Unaryop::UAdd => Self::UAdd,
|
||||
ast::Unaryop::USub => Self::USub,
|
||||
ast::UnaryOp::Invert => Self::Invert,
|
||||
ast::UnaryOp::Not => Self::Not,
|
||||
ast::UnaryOp::UAdd => Self::UAdd,
|
||||
ast::UnaryOp::USub => Self::USub,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum ComparableCmpop {
|
||||
pub enum ComparableCmpOp {
|
||||
Eq,
|
||||
NotEq,
|
||||
Lt,
|
||||
|
@ -106,19 +106,19 @@ pub enum ComparableCmpop {
|
|||
NotIn,
|
||||
}
|
||||
|
||||
impl From<ast::Cmpop> for ComparableCmpop {
|
||||
fn from(op: ast::Cmpop) -> Self {
|
||||
impl From<ast::CmpOp> for ComparableCmpOp {
|
||||
fn from(op: ast::CmpOp) -> Self {
|
||||
match op {
|
||||
ast::Cmpop::Eq => Self::Eq,
|
||||
ast::Cmpop::NotEq => Self::NotEq,
|
||||
ast::Cmpop::Lt => Self::Lt,
|
||||
ast::Cmpop::LtE => Self::LtE,
|
||||
ast::Cmpop::Gt => Self::Gt,
|
||||
ast::Cmpop::GtE => Self::GtE,
|
||||
ast::Cmpop::Is => Self::Is,
|
||||
ast::Cmpop::IsNot => Self::IsNot,
|
||||
ast::Cmpop::In => Self::In,
|
||||
ast::Cmpop::NotIn => Self::NotIn,
|
||||
ast::CmpOp::Eq => Self::Eq,
|
||||
ast::CmpOp::NotEq => Self::NotEq,
|
||||
ast::CmpOp::Lt => Self::Lt,
|
||||
ast::CmpOp::LtE => Self::LtE,
|
||||
ast::CmpOp::Gt => Self::Gt,
|
||||
ast::CmpOp::GtE => Self::GtE,
|
||||
ast::CmpOp::Is => Self::Is,
|
||||
ast::CmpOp::IsNot => Self::IsNot,
|
||||
ast::CmpOp::In => Self::In,
|
||||
ast::CmpOp::NotIn => Self::NotIn,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,16 +139,16 @@ impl<'a> From<&'a ast::Alias> for ComparableAlias<'a> {
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ComparableWithitem<'a> {
|
||||
pub struct ComparableWithItem<'a> {
|
||||
context_expr: ComparableExpr<'a>,
|
||||
optional_vars: Option<ComparableExpr<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ast::Withitem> for ComparableWithitem<'a> {
|
||||
fn from(withitem: &'a ast::Withitem) -> Self {
|
||||
impl<'a> From<&'a ast::WithItem> for ComparableWithItem<'a> {
|
||||
fn from(with_item: &'a ast::WithItem) -> Self {
|
||||
Self {
|
||||
context_expr: (&withitem.context_expr).into(),
|
||||
optional_vars: withitem.optional_vars.as_ref().map(Into::into),
|
||||
context_expr: (&with_item.context_expr).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)]
|
||||
pub struct ComparableArguments<'a> {
|
||||
posonlyargs: Vec<ComparableArg<'a>>,
|
||||
args: Vec<ComparableArg<'a>>,
|
||||
posonlyargs: Vec<ComparableArgWithDefault<'a>>,
|
||||
args: Vec<ComparableArgWithDefault<'a>>,
|
||||
vararg: Option<ComparableArg<'a>>,
|
||||
kwonlyargs: Vec<ComparableArg<'a>>,
|
||||
kw_defaults: Vec<ComparableExpr<'a>>,
|
||||
kwonlyargs: Vec<ComparableArgWithDefault<'a>>,
|
||||
kwarg: Option<ComparableArg<'a>>,
|
||||
defaults: Vec<ComparableExpr<'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(),
|
||||
vararg: arguments.vararg.as_ref().map(Into::into),
|
||||
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),
|
||||
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)]
|
||||
pub struct ComparableKeyword<'a> {
|
||||
arg: Option<&'a str>,
|
||||
|
@ -429,26 +440,26 @@ impl<'a> From<&'a ast::Comprehension> for ComparableComprehension<'a> {
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ExcepthandlerExceptHandler<'a> {
|
||||
pub struct ExceptHandlerExceptHandler<'a> {
|
||||
type_: Option<Box<ComparableExpr<'a>>>,
|
||||
name: Option<&'a str>,
|
||||
body: Vec<ComparableStmt<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub enum ComparableExcepthandler<'a> {
|
||||
ExceptHandler(ExcepthandlerExceptHandler<'a>),
|
||||
pub enum ComparableExceptHandler<'a> {
|
||||
ExceptHandler(ExceptHandlerExceptHandler<'a>),
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ast::Excepthandler> for ComparableExcepthandler<'a> {
|
||||
fn from(excepthandler: &'a ast::Excepthandler) -> Self {
|
||||
let ast::Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
impl<'a> From<&'a ast::ExceptHandler> for ComparableExceptHandler<'a> {
|
||||
fn from(except_handler: &'a ast::ExceptHandler) -> Self {
|
||||
let ast::ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||
type_,
|
||||
name,
|
||||
body,
|
||||
..
|
||||
}) = excepthandler;
|
||||
Self::ExceptHandler(ExcepthandlerExceptHandler {
|
||||
}) = except_handler;
|
||||
Self::ExceptHandler(ExceptHandlerExceptHandler {
|
||||
type_: type_.as_ref().map(Into::into),
|
||||
name: name.as_deref(),
|
||||
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)]
|
||||
pub struct ExprBoolOp<'a> {
|
||||
op: ComparableBoolop,
|
||||
op: ComparableBoolOp,
|
||||
values: Vec<ComparableExpr<'a>>,
|
||||
}
|
||||
|
||||
|
@ -477,7 +488,7 @@ pub struct ExprBinOp<'a> {
|
|||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ExprUnaryOp<'a> {
|
||||
op: ComparableUnaryop,
|
||||
op: ComparableUnaryOp,
|
||||
operand: Box<ComparableExpr<'a>>,
|
||||
}
|
||||
|
||||
|
@ -548,7 +559,7 @@ pub struct ExprYieldFrom<'a> {
|
|||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ExprCompare<'a> {
|
||||
left: Box<ComparableExpr<'a>>,
|
||||
ops: Vec<ComparableCmpop>,
|
||||
ops: Vec<ComparableCmpOp>,
|
||||
comparators: Vec<ComparableExpr<'a>>,
|
||||
}
|
||||
|
||||
|
@ -994,14 +1005,14 @@ pub struct StmtIf<'a> {
|
|||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct StmtWith<'a> {
|
||||
items: Vec<ComparableWithitem<'a>>,
|
||||
items: Vec<ComparableWithItem<'a>>,
|
||||
body: Vec<ComparableStmt<'a>>,
|
||||
type_comment: Option<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct StmtAsyncWith<'a> {
|
||||
items: Vec<ComparableWithitem<'a>>,
|
||||
items: Vec<ComparableWithItem<'a>>,
|
||||
body: Vec<ComparableStmt<'a>>,
|
||||
type_comment: Option<&'a str>,
|
||||
}
|
||||
|
@ -1021,7 +1032,7 @@ pub struct StmtRaise<'a> {
|
|||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct StmtTry<'a> {
|
||||
body: Vec<ComparableStmt<'a>>,
|
||||
handlers: Vec<ComparableExcepthandler<'a>>,
|
||||
handlers: Vec<ComparableExceptHandler<'a>>,
|
||||
orelse: Vec<ComparableStmt<'a>>,
|
||||
finalbody: Vec<ComparableStmt<'a>>,
|
||||
}
|
||||
|
@ -1029,7 +1040,7 @@ pub struct StmtTry<'a> {
|
|||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct StmtTryStar<'a> {
|
||||
body: Vec<ComparableStmt<'a>>,
|
||||
handlers: Vec<ComparableExcepthandler<'a>>,
|
||||
handlers: Vec<ComparableExceptHandler<'a>>,
|
||||
orelse: Vec<ComparableStmt<'a>>,
|
||||
finalbody: Vec<ComparableStmt<'a>>,
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ use std::path::Path;
|
|||
use num_traits::Zero;
|
||||
use ruff_text_size::{TextRange, TextSize};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_ast::Cmpop;
|
||||
use rustpython_ast::CmpOp;
|
||||
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 smallvec::SmallVec;
|
||||
|
@ -333,25 +333,19 @@ where
|
|||
returns,
|
||||
..
|
||||
}) => {
|
||||
args.defaults.iter().any(|expr| any_over_expr(expr, func))
|
||||
|| args
|
||||
.kw_defaults
|
||||
.iter()
|
||||
.any(|expr| any_over_expr(expr, func))
|
||||
|| args.args.iter().any(|arg| {
|
||||
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
|
||||
args.posonlyargs
|
||||
.iter()
|
||||
.chain(args.args.iter().chain(args.kwonlyargs.iter()))
|
||||
.any(|arg_with_default| {
|
||||
arg_with_default
|
||||
.default
|
||||
.as_ref()
|
||||
.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| {
|
||||
arg.annotation
|
||||
|
@ -448,9 +442,9 @@ where
|
|||
}) => any_over_expr(test, func) || any_over_body(body, func) || any_over_body(orelse, func),
|
||||
Stmt::With(ast::StmtWith { items, body, .. })
|
||||
| Stmt::AsyncWith(ast::StmtAsyncWith { items, body, .. }) => {
|
||||
items.iter().any(|withitem| {
|
||||
any_over_expr(&withitem.context_expr, func)
|
||||
|| withitem
|
||||
items.iter().any(|with_item| {
|
||||
any_over_expr(&with_item.context_expr, func)
|
||||
|| with_item
|
||||
.optional_vars
|
||||
.as_ref()
|
||||
.map_or(false, |expr| any_over_expr(expr, func))
|
||||
|
@ -483,7 +477,7 @@ where
|
|||
}) => {
|
||||
any_over_body(body, func)
|
||||
|| handlers.iter().any(|handler| {
|
||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||
type_,
|
||||
body,
|
||||
..
|
||||
|
@ -655,11 +649,11 @@ pub fn has_non_none_keyword(keywords: &[Keyword], keyword: &str) -> bool {
|
|||
}
|
||||
|
||||
/// 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();
|
||||
for handler in handlers {
|
||||
match handler {
|
||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) => {
|
||||
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, .. }) => {
|
||||
if let Some(type_) = type_ {
|
||||
if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &type_.as_ref() {
|
||||
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.
|
||||
pub fn collect_arg_names<'a>(arguments: &'a Arguments) -> FxHashSet<&'a str> {
|
||||
let mut arg_names: FxHashSet<&'a str> = FxHashSet::default();
|
||||
for arg in &arguments.posonlyargs {
|
||||
arg_names.insert(arg.arg.as_str());
|
||||
for arg_with_default in &arguments.posonlyargs {
|
||||
arg_names.insert(arg_with_default.def.arg.as_str());
|
||||
}
|
||||
for arg in &arguments.args {
|
||||
arg_names.insert(arg.arg.as_str());
|
||||
for arg_with_default in &arguments.args {
|
||||
arg_names.insert(arg_with_default.def.arg.as_str());
|
||||
}
|
||||
if let Some(arg) = &arguments.vararg {
|
||||
arg_names.insert(arg.arg.as_str());
|
||||
}
|
||||
for arg in &arguments.kwonlyargs {
|
||||
arg_names.insert(arg.arg.as_str());
|
||||
for arg_with_default in &arguments.kwonlyargs {
|
||||
arg_names.insert(arg_with_default.def.arg.as_str());
|
||||
}
|
||||
if let Some(arg) = &arguments.kwarg {
|
||||
arg_names.insert(arg.arg.as_str());
|
||||
|
@ -1409,13 +1403,13 @@ impl Truthiness {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct LocatedCmpop {
|
||||
pub struct LocatedCmpOp {
|
||||
pub range: TextRange,
|
||||
pub op: Cmpop,
|
||||
pub op: CmpOp,
|
||||
}
|
||||
|
||||
impl LocatedCmpop {
|
||||
fn new<T: Into<TextRange>>(range: T, op: Cmpop) -> Self {
|
||||
impl LocatedCmpOp {
|
||||
fn new<T: Into<TextRange>>(range: T, op: CmpOp) -> Self {
|
||||
Self {
|
||||
range: range.into(),
|
||||
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.
|
||||
///
|
||||
/// `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
|
||||
/// re-identifies [`Cmpop`] nodes, annotating them with valid ranges.
|
||||
pub fn locate_cmpops(expr: &Expr, locator: &Locator) -> Vec<LocatedCmpop> {
|
||||
/// re-identifies [`CmpOp`] nodes, annotating them with valid ranges.
|
||||
pub fn locate_cmp_ops(expr: &Expr, locator: &Locator) -> Vec<LocatedCmpOp> {
|
||||
// If `Expr` is a multi-line expression, we need to parenthesize it to
|
||||
// ensure that it's lexed correctly.
|
||||
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(_)))
|
||||
.peekable();
|
||||
|
||||
let mut ops: Vec<LocatedCmpop> = vec![];
|
||||
let mut ops: Vec<LocatedCmpOp> = vec![];
|
||||
let mut count = 0u32;
|
||||
loop {
|
||||
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)) =
|
||||
tok_iter.next_if(|(tok, _)| matches!(tok, Tok::In))
|
||||
{
|
||||
ops.push(LocatedCmpop::new(
|
||||
ops.push(LocatedCmpOp::new(
|
||||
TextRange::new(range.start(), next_range.end()),
|
||||
Cmpop::NotIn,
|
||||
CmpOp::NotIn,
|
||||
));
|
||||
}
|
||||
}
|
||||
Tok::In => {
|
||||
ops.push(LocatedCmpop::new(range, Cmpop::In));
|
||||
ops.push(LocatedCmpOp::new(range, CmpOp::In));
|
||||
}
|
||||
Tok::Is => {
|
||||
let op = if let Some((_, next_range)) =
|
||||
tok_iter.next_if(|(tok, _)| matches!(tok, Tok::Not))
|
||||
{
|
||||
LocatedCmpop::new(
|
||||
LocatedCmpOp::new(
|
||||
TextRange::new(range.start(), next_range.end()),
|
||||
Cmpop::IsNot,
|
||||
CmpOp::IsNot,
|
||||
)
|
||||
} else {
|
||||
LocatedCmpop::new(range, Cmpop::Is)
|
||||
LocatedCmpOp::new(range, CmpOp::Is)
|
||||
};
|
||||
ops.push(op);
|
||||
}
|
||||
Tok::NotEqual => {
|
||||
ops.push(LocatedCmpop::new(range, Cmpop::NotEq));
|
||||
ops.push(LocatedCmpOp::new(range, CmpOp::NotEq));
|
||||
}
|
||||
Tok::EqEqual => {
|
||||
ops.push(LocatedCmpop::new(range, Cmpop::Eq));
|
||||
ops.push(LocatedCmpOp::new(range, CmpOp::Eq));
|
||||
}
|
||||
Tok::GreaterEqual => {
|
||||
ops.push(LocatedCmpop::new(range, Cmpop::GtE));
|
||||
ops.push(LocatedCmpOp::new(range, CmpOp::GtE));
|
||||
}
|
||||
Tok::Greater => {
|
||||
ops.push(LocatedCmpop::new(range, Cmpop::Gt));
|
||||
ops.push(LocatedCmpOp::new(range, CmpOp::Gt));
|
||||
}
|
||||
Tok::LessEqual => {
|
||||
ops.push(LocatedCmpop::new(range, Cmpop::LtE));
|
||||
ops.push(LocatedCmpOp::new(range, CmpOp::LtE));
|
||||
}
|
||||
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 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::Parse;
|
||||
|
||||
use crate::helpers::{
|
||||
elif_else_range, first_colon_range, has_trailing_content, locate_cmpops,
|
||||
resolve_imported_module_path, LocatedCmpop,
|
||||
elif_else_range, first_colon_range, has_trailing_content, locate_cmp_ops,
|
||||
resolve_imported_module_path, LocatedCmpOp,
|
||||
};
|
||||
use crate::source_code::Locator;
|
||||
|
||||
|
@ -1642,15 +1636,15 @@ else:
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn extract_cmpop_location() -> Result<()> {
|
||||
fn extract_cmp_op_location() -> Result<()> {
|
||||
let contents = "x == 1";
|
||||
let expr = Expr::parse(contents, "<filename>")?;
|
||||
let locator = Locator::new(contents);
|
||||
assert_eq!(
|
||||
locate_cmpops(&expr, &locator),
|
||||
vec![LocatedCmpop::new(
|
||||
locate_cmp_ops(&expr, &locator),
|
||||
vec![LocatedCmpOp::new(
|
||||
TextSize::from(2)..TextSize::from(4),
|
||||
Cmpop::Eq
|
||||
CmpOp::Eq
|
||||
)]
|
||||
);
|
||||
|
||||
|
@ -1658,10 +1652,10 @@ else:
|
|||
let expr = Expr::parse(contents, "<filename>")?;
|
||||
let locator = Locator::new(contents);
|
||||
assert_eq!(
|
||||
locate_cmpops(&expr, &locator),
|
||||
vec![LocatedCmpop::new(
|
||||
locate_cmp_ops(&expr, &locator),
|
||||
vec![LocatedCmpOp::new(
|
||||
TextSize::from(2)..TextSize::from(4),
|
||||
Cmpop::NotEq
|
||||
CmpOp::NotEq
|
||||
)]
|
||||
);
|
||||
|
||||
|
@ -1669,10 +1663,10 @@ else:
|
|||
let expr = Expr::parse(contents, "<filename>")?;
|
||||
let locator = Locator::new(contents);
|
||||
assert_eq!(
|
||||
locate_cmpops(&expr, &locator),
|
||||
vec![LocatedCmpop::new(
|
||||
locate_cmp_ops(&expr, &locator),
|
||||
vec![LocatedCmpOp::new(
|
||||
TextSize::from(2)..TextSize::from(4),
|
||||
Cmpop::Is
|
||||
CmpOp::Is
|
||||
)]
|
||||
);
|
||||
|
||||
|
@ -1680,10 +1674,10 @@ else:
|
|||
let expr = Expr::parse(contents, "<filename>")?;
|
||||
let locator = Locator::new(contents);
|
||||
assert_eq!(
|
||||
locate_cmpops(&expr, &locator),
|
||||
vec![LocatedCmpop::new(
|
||||
locate_cmp_ops(&expr, &locator),
|
||||
vec![LocatedCmpOp::new(
|
||||
TextSize::from(2)..TextSize::from(8),
|
||||
Cmpop::IsNot
|
||||
CmpOp::IsNot
|
||||
)]
|
||||
);
|
||||
|
||||
|
@ -1691,10 +1685,10 @@ else:
|
|||
let expr = Expr::parse(contents, "<filename>")?;
|
||||
let locator = Locator::new(contents);
|
||||
assert_eq!(
|
||||
locate_cmpops(&expr, &locator),
|
||||
vec![LocatedCmpop::new(
|
||||
locate_cmp_ops(&expr, &locator),
|
||||
vec![LocatedCmpOp::new(
|
||||
TextSize::from(2)..TextSize::from(4),
|
||||
Cmpop::In
|
||||
CmpOp::In
|
||||
)]
|
||||
);
|
||||
|
||||
|
@ -1702,10 +1696,10 @@ else:
|
|||
let expr = Expr::parse(contents, "<filename>")?;
|
||||
let locator = Locator::new(contents);
|
||||
assert_eq!(
|
||||
locate_cmpops(&expr, &locator),
|
||||
vec![LocatedCmpop::new(
|
||||
locate_cmp_ops(&expr, &locator),
|
||||
vec![LocatedCmpOp::new(
|
||||
TextSize::from(2)..TextSize::from(8),
|
||||
Cmpop::NotIn
|
||||
CmpOp::NotIn
|
||||
)]
|
||||
);
|
||||
|
||||
|
@ -1713,10 +1707,10 @@ else:
|
|||
let expr = Expr::parse(contents, "<filename>")?;
|
||||
let locator = Locator::new(contents);
|
||||
assert_eq!(
|
||||
locate_cmpops(&expr, &locator),
|
||||
vec![LocatedCmpop::new(
|
||||
locate_cmp_ops(&expr, &locator),
|
||||
vec![LocatedCmpOp::new(
|
||||
TextSize::from(2)..TextSize::from(4),
|
||||
Cmpop::NotEq
|
||||
CmpOp::NotEq
|
||||
)]
|
||||
);
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ use std::ops::{Add, Sub};
|
|||
use std::str::Chars;
|
||||
|
||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||
use rustpython_ast::{Alias, Arg, Pattern};
|
||||
use rustpython_parser::ast::{self, Excepthandler, Ranged, Stmt};
|
||||
use rustpython_ast::{Alias, Arg, ArgWithDefault, Pattern};
|
||||
use rustpython_parser::ast::{self, ExceptHandler, Ranged, Stmt};
|
||||
|
||||
use ruff_python_whitespace::is_python_whitespace;
|
||||
|
||||
|
@ -94,7 +94,7 @@ impl Identifier for Arg {
|
|||
///
|
||||
/// For example, return the range of `x` in:
|
||||
/// ```python
|
||||
/// def f(x: int = 0):
|
||||
/// def f(x: int):
|
||||
/// ...
|
||||
/// ```
|
||||
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 {
|
||||
/// Return the [`TextRange`] for the identifier defining an [`Alias`].
|
||||
///
|
||||
|
@ -239,8 +252,8 @@ impl TryIdentifier for Pattern {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryIdentifier for Excepthandler {
|
||||
/// Return the [`TextRange`] of a named exception in an [`Excepthandler`].
|
||||
impl TryIdentifier for ExceptHandler {
|
||||
/// Return the [`TextRange`] of a named exception in an [`ExceptHandler`].
|
||||
///
|
||||
/// For example, return the range of `e` in:
|
||||
/// ```python
|
||||
|
@ -250,7 +263,7 @@ impl TryIdentifier for Excepthandler {
|
|||
/// ...
|
||||
/// ```
|
||||
fn try_identifier(&self, locator: &Locator) -> Option<TextRange> {
|
||||
let Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, name, .. }) =
|
||||
let ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, name, .. }) =
|
||||
self;
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
/// Return the [`TextRange`] of the `except` token in an [`Excepthandler`].
|
||||
pub fn except(handler: &Excepthandler, locator: &Locator) -> TextRange {
|
||||
/// Return the [`TextRange`] of the `except` token in an [`ExceptHandler`].
|
||||
pub fn except(handler: &ExceptHandler, locator: &Locator) -> TextRange {
|
||||
IdentifierTokenizer::new(locator.contents(), handler.range())
|
||||
.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.
|
||||
|
|
|
@ -75,7 +75,7 @@ pub enum AnyNode {
|
|||
ExprList(ExprList<TextRange>),
|
||||
ExprTuple(ExprTuple<TextRange>),
|
||||
ExprSlice(ExprSlice<TextRange>),
|
||||
ExcepthandlerExceptHandler(ExcepthandlerExceptHandler<TextRange>),
|
||||
ExceptHandlerExceptHandler(ExceptHandlerExceptHandler<TextRange>),
|
||||
PatternMatchValue(PatternMatchValue<TextRange>),
|
||||
PatternMatchSingleton(PatternMatchSingleton<TextRange>),
|
||||
PatternMatchSequence(PatternMatchSequence<TextRange>),
|
||||
|
@ -88,9 +88,10 @@ pub enum AnyNode {
|
|||
Comprehension(Comprehension<TextRange>),
|
||||
Arguments(Arguments<TextRange>),
|
||||
Arg(Arg<TextRange>),
|
||||
ArgWithDefault(ArgWithDefault<TextRange>),
|
||||
Keyword(Keyword<TextRange>),
|
||||
Alias(Alias<TextRange>),
|
||||
Withitem(Withitem<TextRange>),
|
||||
WithItem(WithItem<TextRange>),
|
||||
MatchCase(MatchCase<TextRange>),
|
||||
Decorator(Decorator<TextRange>),
|
||||
}
|
||||
|
@ -157,7 +158,7 @@ impl AnyNode {
|
|||
| AnyNode::ExprList(_)
|
||||
| AnyNode::ExprTuple(_)
|
||||
| AnyNode::ExprSlice(_)
|
||||
| AnyNode::ExcepthandlerExceptHandler(_)
|
||||
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||
| AnyNode::PatternMatchValue(_)
|
||||
| AnyNode::PatternMatchSingleton(_)
|
||||
| AnyNode::PatternMatchSequence(_)
|
||||
|
@ -170,9 +171,10 @@ impl AnyNode {
|
|||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Arg(_)
|
||||
| AnyNode::ArgWithDefault(_)
|
||||
| AnyNode::Keyword(_)
|
||||
| AnyNode::Alias(_)
|
||||
| AnyNode::Withitem(_)
|
||||
| AnyNode::WithItem(_)
|
||||
| AnyNode::MatchCase(_)
|
||||
| AnyNode::Decorator(_) => None,
|
||||
}
|
||||
|
@ -239,7 +241,7 @@ impl AnyNode {
|
|||
| AnyNode::StmtPass(_)
|
||||
| AnyNode::StmtBreak(_)
|
||||
| AnyNode::StmtContinue(_)
|
||||
| AnyNode::ExcepthandlerExceptHandler(_)
|
||||
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||
| AnyNode::PatternMatchValue(_)
|
||||
| AnyNode::PatternMatchSingleton(_)
|
||||
| AnyNode::PatternMatchSequence(_)
|
||||
|
@ -252,9 +254,10 @@ impl AnyNode {
|
|||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Arg(_)
|
||||
| AnyNode::ArgWithDefault(_)
|
||||
| AnyNode::Keyword(_)
|
||||
| AnyNode::Alias(_)
|
||||
| AnyNode::Withitem(_)
|
||||
| AnyNode::WithItem(_)
|
||||
| AnyNode::MatchCase(_)
|
||||
| AnyNode::Decorator(_) => None,
|
||||
}
|
||||
|
@ -321,7 +324,7 @@ impl AnyNode {
|
|||
| AnyNode::ExprList(_)
|
||||
| AnyNode::ExprTuple(_)
|
||||
| AnyNode::ExprSlice(_)
|
||||
| AnyNode::ExcepthandlerExceptHandler(_)
|
||||
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||
| AnyNode::PatternMatchValue(_)
|
||||
| AnyNode::PatternMatchSingleton(_)
|
||||
| AnyNode::PatternMatchSequence(_)
|
||||
|
@ -334,9 +337,10 @@ impl AnyNode {
|
|||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Arg(_)
|
||||
| AnyNode::ArgWithDefault(_)
|
||||
| AnyNode::Keyword(_)
|
||||
| AnyNode::Alias(_)
|
||||
| AnyNode::Withitem(_)
|
||||
| AnyNode::WithItem(_)
|
||||
| AnyNode::MatchCase(_)
|
||||
| AnyNode::Decorator(_) => None,
|
||||
}
|
||||
|
@ -411,22 +415,23 @@ impl AnyNode {
|
|||
| AnyNode::ExprList(_)
|
||||
| AnyNode::ExprTuple(_)
|
||||
| AnyNode::ExprSlice(_)
|
||||
| AnyNode::ExcepthandlerExceptHandler(_)
|
||||
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||
| AnyNode::TypeIgnoreTypeIgnore(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Arg(_)
|
||||
| AnyNode::ArgWithDefault(_)
|
||||
| AnyNode::Keyword(_)
|
||||
| AnyNode::Alias(_)
|
||||
| AnyNode::Withitem(_)
|
||||
| AnyNode::WithItem(_)
|
||||
| AnyNode::MatchCase(_)
|
||||
| AnyNode::Decorator(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn except_handler(self) -> Option<Excepthandler> {
|
||||
pub fn except_handler(self) -> Option<ExceptHandler> {
|
||||
match self {
|
||||
AnyNode::ExcepthandlerExceptHandler(node) => Some(Excepthandler::ExceptHandler(node)),
|
||||
AnyNode::ExceptHandlerExceptHandler(node) => Some(ExceptHandler::ExceptHandler(node)),
|
||||
|
||||
AnyNode::ModModule(_)
|
||||
| AnyNode::ModInteractive(_)
|
||||
|
@ -498,9 +503,10 @@ impl AnyNode {
|
|||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Arg(_)
|
||||
| AnyNode::ArgWithDefault(_)
|
||||
| AnyNode::Keyword(_)
|
||||
| AnyNode::Alias(_)
|
||||
| AnyNode::Withitem(_)
|
||||
| AnyNode::WithItem(_)
|
||||
| AnyNode::MatchCase(_)
|
||||
| AnyNode::Decorator(_) => None,
|
||||
}
|
||||
|
@ -576,13 +582,14 @@ impl AnyNode {
|
|||
| AnyNode::PatternMatchStar(_)
|
||||
| AnyNode::PatternMatchAs(_)
|
||||
| AnyNode::PatternMatchOr(_)
|
||||
| AnyNode::ExcepthandlerExceptHandler(_)
|
||||
| AnyNode::ExceptHandlerExceptHandler(_)
|
||||
| AnyNode::Comprehension(_)
|
||||
| AnyNode::Arguments(_)
|
||||
| AnyNode::Arg(_)
|
||||
| AnyNode::ArgWithDefault(_)
|
||||
| AnyNode::Keyword(_)
|
||||
| AnyNode::Alias(_)
|
||||
| AnyNode::Withitem(_)
|
||||
| AnyNode::WithItem(_)
|
||||
| AnyNode::MatchCase(_)
|
||||
| AnyNode::Decorator(_) => None,
|
||||
}
|
||||
|
@ -672,7 +679,7 @@ impl AnyNode {
|
|||
Self::ExprList(node) => AnyNodeRef::ExprList(node),
|
||||
Self::ExprTuple(node) => AnyNodeRef::ExprTuple(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::PatternMatchSingleton(node) => AnyNodeRef::PatternMatchSingleton(node),
|
||||
Self::PatternMatchSequence(node) => AnyNodeRef::PatternMatchSequence(node),
|
||||
|
@ -685,9 +692,10 @@ impl AnyNode {
|
|||
Self::Comprehension(node) => AnyNodeRef::Comprehension(node),
|
||||
Self::Arguments(node) => AnyNodeRef::Arguments(node),
|
||||
Self::Arg(node) => AnyNodeRef::Arg(node),
|
||||
Self::ArgWithDefault(node) => AnyNodeRef::ArgWithDefault(node),
|
||||
Self::Keyword(node) => AnyNodeRef::Keyword(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::Decorator(node) => AnyNodeRef::Decorator(node),
|
||||
}
|
||||
|
@ -2323,12 +2331,12 @@ impl AstNode for ExprSlice<TextRange> {
|
|||
AnyNode::from(self)
|
||||
}
|
||||
}
|
||||
impl AstNode for ExcepthandlerExceptHandler<TextRange> {
|
||||
impl AstNode for ExceptHandlerExceptHandler<TextRange> {
|
||||
fn cast(kind: AnyNode) -> Option<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
if let AnyNode::ExcepthandlerExceptHandler(node) = kind {
|
||||
if let AnyNode::ExceptHandlerExceptHandler(node) = kind {
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
|
@ -2336,7 +2344,7 @@ impl AstNode for ExcepthandlerExceptHandler<TextRange> {
|
|||
}
|
||||
|
||||
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
|
||||
if let AnyNodeRef::ExcepthandlerExceptHandler(node) = kind {
|
||||
if let AnyNodeRef::ExceptHandlerExceptHandler(node) = kind {
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
|
@ -2688,6 +2696,34 @@ impl AstNode for Arg<TextRange> {
|
|||
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> {
|
||||
fn cast(kind: AnyNode) -> Option<Self>
|
||||
where
|
||||
|
@ -2744,12 +2780,12 @@ impl AstNode for Alias<TextRange> {
|
|||
AnyNode::from(self)
|
||||
}
|
||||
}
|
||||
impl AstNode for Withitem<TextRange> {
|
||||
impl AstNode for WithItem<TextRange> {
|
||||
fn cast(kind: AnyNode) -> Option<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
if let AnyNode::Withitem(node) = kind {
|
||||
if let AnyNode::WithItem(node) = kind {
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
|
@ -2757,7 +2793,7 @@ impl AstNode for Withitem<TextRange> {
|
|||
}
|
||||
|
||||
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
|
||||
if let AnyNodeRef::Withitem(node) = kind {
|
||||
if let AnyNodeRef::WithItem(node) = kind {
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
|
@ -2924,10 +2960,10 @@ impl From<Pattern> for AnyNode {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<Excepthandler> for AnyNode {
|
||||
fn from(handler: Excepthandler) -> Self {
|
||||
impl From<ExceptHandler> for AnyNode {
|
||||
fn from(handler: ExceptHandler) -> Self {
|
||||
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 {
|
||||
fn from(node: ExcepthandlerExceptHandler) -> Self {
|
||||
AnyNode::ExcepthandlerExceptHandler(node)
|
||||
impl From<ExceptHandlerExceptHandler> for AnyNode {
|
||||
fn from(node: ExceptHandlerExceptHandler) -> Self {
|
||||
AnyNode::ExceptHandlerExceptHandler(node)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3363,6 +3399,11 @@ impl From<Arg> for AnyNode {
|
|||
AnyNode::Arg(node)
|
||||
}
|
||||
}
|
||||
impl From<ArgWithDefault> for AnyNode {
|
||||
fn from(node: ArgWithDefault) -> Self {
|
||||
AnyNode::ArgWithDefault(node)
|
||||
}
|
||||
}
|
||||
impl From<Keyword> for AnyNode {
|
||||
fn from(node: Keyword) -> Self {
|
||||
AnyNode::Keyword(node)
|
||||
|
@ -3373,9 +3414,9 @@ impl From<Alias> for AnyNode {
|
|||
AnyNode::Alias(node)
|
||||
}
|
||||
}
|
||||
impl From<Withitem> for AnyNode {
|
||||
fn from(node: Withitem) -> Self {
|
||||
AnyNode::Withitem(node)
|
||||
impl From<WithItem> for AnyNode {
|
||||
fn from(node: WithItem) -> Self {
|
||||
AnyNode::WithItem(node)
|
||||
}
|
||||
}
|
||||
impl From<MatchCase> for AnyNode {
|
||||
|
@ -3450,7 +3491,7 @@ impl Ranged for AnyNode {
|
|||
AnyNode::ExprList(node) => node.range(),
|
||||
AnyNode::ExprTuple(node) => node.range(),
|
||||
AnyNode::ExprSlice(node) => node.range(),
|
||||
AnyNode::ExcepthandlerExceptHandler(node) => node.range(),
|
||||
AnyNode::ExceptHandlerExceptHandler(node) => node.range(),
|
||||
AnyNode::PatternMatchValue(node) => node.range(),
|
||||
AnyNode::PatternMatchSingleton(node) => node.range(),
|
||||
AnyNode::PatternMatchSequence(node) => node.range(),
|
||||
|
@ -3463,9 +3504,10 @@ impl Ranged for AnyNode {
|
|||
AnyNode::Comprehension(node) => node.range(),
|
||||
AnyNode::Arguments(node) => node.range(),
|
||||
AnyNode::Arg(node) => node.range(),
|
||||
AnyNode::ArgWithDefault(node) => node.range(),
|
||||
AnyNode::Keyword(node) => node.range(),
|
||||
AnyNode::Alias(node) => node.range(),
|
||||
AnyNode::Withitem(node) => node.range(),
|
||||
AnyNode::WithItem(node) => node.range(),
|
||||
AnyNode::MatchCase(node) => node.range(),
|
||||
AnyNode::Decorator(node) => node.range(),
|
||||
}
|
||||
|
@ -3532,7 +3574,7 @@ pub enum AnyNodeRef<'a> {
|
|||
ExprList(&'a ExprList<TextRange>),
|
||||
ExprTuple(&'a ExprTuple<TextRange>),
|
||||
ExprSlice(&'a ExprSlice<TextRange>),
|
||||
ExcepthandlerExceptHandler(&'a ExcepthandlerExceptHandler<TextRange>),
|
||||
ExceptHandlerExceptHandler(&'a ExceptHandlerExceptHandler<TextRange>),
|
||||
PatternMatchValue(&'a PatternMatchValue<TextRange>),
|
||||
PatternMatchSingleton(&'a PatternMatchSingleton<TextRange>),
|
||||
PatternMatchSequence(&'a PatternMatchSequence<TextRange>),
|
||||
|
@ -3545,9 +3587,10 @@ pub enum AnyNodeRef<'a> {
|
|||
Comprehension(&'a Comprehension<TextRange>),
|
||||
Arguments(&'a Arguments<TextRange>),
|
||||
Arg(&'a Arg<TextRange>),
|
||||
ArgWithDefault(&'a ArgWithDefault<TextRange>),
|
||||
Keyword(&'a Keyword<TextRange>),
|
||||
Alias(&'a Alias<TextRange>),
|
||||
Withitem(&'a Withitem<TextRange>),
|
||||
WithItem(&'a WithItem<TextRange>),
|
||||
MatchCase(&'a MatchCase<TextRange>),
|
||||
Decorator(&'a Decorator<TextRange>),
|
||||
}
|
||||
|
@ -3613,7 +3656,7 @@ impl AnyNodeRef<'_> {
|
|||
AnyNodeRef::ExprList(node) => NonNull::from(*node).cast(),
|
||||
AnyNodeRef::ExprTuple(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::PatternMatchSingleton(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::Arguments(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::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::Decorator(node) => NonNull::from(*node).cast(),
|
||||
}
|
||||
|
@ -3700,7 +3744,7 @@ impl AnyNodeRef<'_> {
|
|||
AnyNodeRef::ExprList(_) => NodeKind::ExprList,
|
||||
AnyNodeRef::ExprTuple(_) => NodeKind::ExprTuple,
|
||||
AnyNodeRef::ExprSlice(_) => NodeKind::ExprSlice,
|
||||
AnyNodeRef::ExcepthandlerExceptHandler(_) => NodeKind::ExcepthandlerExceptHandler,
|
||||
AnyNodeRef::ExceptHandlerExceptHandler(_) => NodeKind::ExceptHandlerExceptHandler,
|
||||
AnyNodeRef::PatternMatchValue(_) => NodeKind::PatternMatchValue,
|
||||
AnyNodeRef::PatternMatchSingleton(_) => NodeKind::PatternMatchSingleton,
|
||||
AnyNodeRef::PatternMatchSequence(_) => NodeKind::PatternMatchSequence,
|
||||
|
@ -3713,9 +3757,10 @@ impl AnyNodeRef<'_> {
|
|||
AnyNodeRef::Comprehension(_) => NodeKind::Comprehension,
|
||||
AnyNodeRef::Arguments(_) => NodeKind::Arguments,
|
||||
AnyNodeRef::Arg(_) => NodeKind::Arg,
|
||||
AnyNodeRef::ArgWithDefault(_) => NodeKind::ArgWithDefault,
|
||||
AnyNodeRef::Keyword(_) => NodeKind::Keyword,
|
||||
AnyNodeRef::Alias(_) => NodeKind::Alias,
|
||||
AnyNodeRef::Withitem(_) => NodeKind::Withitem,
|
||||
AnyNodeRef::WithItem(_) => NodeKind::WithItem,
|
||||
AnyNodeRef::MatchCase(_) => NodeKind::MatchCase,
|
||||
AnyNodeRef::Decorator(_) => NodeKind::Decorator,
|
||||
}
|
||||
|
@ -3782,7 +3827,7 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::ExprList(_)
|
||||
| AnyNodeRef::ExprTuple(_)
|
||||
| AnyNodeRef::ExprSlice(_)
|
||||
| AnyNodeRef::ExcepthandlerExceptHandler(_)
|
||||
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||
| AnyNodeRef::PatternMatchValue(_)
|
||||
| AnyNodeRef::PatternMatchSingleton(_)
|
||||
| AnyNodeRef::PatternMatchSequence(_)
|
||||
|
@ -3795,9 +3840,10 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Arg(_)
|
||||
| AnyNodeRef::ArgWithDefault(_)
|
||||
| AnyNodeRef::Keyword(_)
|
||||
| AnyNodeRef::Alias(_)
|
||||
| AnyNodeRef::Withitem(_)
|
||||
| AnyNodeRef::WithItem(_)
|
||||
| AnyNodeRef::MatchCase(_)
|
||||
| AnyNodeRef::Decorator(_) => false,
|
||||
}
|
||||
|
@ -3864,7 +3910,7 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::StmtPass(_)
|
||||
| AnyNodeRef::StmtBreak(_)
|
||||
| AnyNodeRef::StmtContinue(_)
|
||||
| AnyNodeRef::ExcepthandlerExceptHandler(_)
|
||||
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||
| AnyNodeRef::PatternMatchValue(_)
|
||||
| AnyNodeRef::PatternMatchSingleton(_)
|
||||
| AnyNodeRef::PatternMatchSequence(_)
|
||||
|
@ -3877,9 +3923,10 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Arg(_)
|
||||
| AnyNodeRef::ArgWithDefault(_)
|
||||
| AnyNodeRef::Keyword(_)
|
||||
| AnyNodeRef::Alias(_)
|
||||
| AnyNodeRef::Withitem(_)
|
||||
| AnyNodeRef::WithItem(_)
|
||||
| AnyNodeRef::MatchCase(_)
|
||||
| AnyNodeRef::Decorator(_) => false,
|
||||
}
|
||||
|
@ -3946,7 +3993,7 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::ExprList(_)
|
||||
| AnyNodeRef::ExprTuple(_)
|
||||
| AnyNodeRef::ExprSlice(_)
|
||||
| AnyNodeRef::ExcepthandlerExceptHandler(_)
|
||||
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||
| AnyNodeRef::PatternMatchValue(_)
|
||||
| AnyNodeRef::PatternMatchSingleton(_)
|
||||
| AnyNodeRef::PatternMatchSequence(_)
|
||||
|
@ -3959,9 +4006,10 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Arg(_)
|
||||
| AnyNodeRef::ArgWithDefault(_)
|
||||
| AnyNodeRef::Keyword(_)
|
||||
| AnyNodeRef::Alias(_)
|
||||
| AnyNodeRef::Withitem(_)
|
||||
| AnyNodeRef::WithItem(_)
|
||||
| AnyNodeRef::MatchCase(_)
|
||||
| AnyNodeRef::Decorator(_) => false,
|
||||
}
|
||||
|
@ -4036,14 +4084,15 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::ExprList(_)
|
||||
| AnyNodeRef::ExprTuple(_)
|
||||
| AnyNodeRef::ExprSlice(_)
|
||||
| AnyNodeRef::ExcepthandlerExceptHandler(_)
|
||||
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||
| AnyNodeRef::TypeIgnoreTypeIgnore(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Arg(_)
|
||||
| AnyNodeRef::ArgWithDefault(_)
|
||||
| AnyNodeRef::Keyword(_)
|
||||
| AnyNodeRef::Alias(_)
|
||||
| AnyNodeRef::Withitem(_)
|
||||
| AnyNodeRef::WithItem(_)
|
||||
| AnyNodeRef::MatchCase(_)
|
||||
| AnyNodeRef::Decorator(_) => false,
|
||||
}
|
||||
|
@ -4051,7 +4100,7 @@ impl AnyNodeRef<'_> {
|
|||
|
||||
pub const fn is_except_handler(self) -> bool {
|
||||
match self {
|
||||
AnyNodeRef::ExcepthandlerExceptHandler(_) => true,
|
||||
AnyNodeRef::ExceptHandlerExceptHandler(_) => true,
|
||||
|
||||
AnyNodeRef::ModModule(_)
|
||||
| AnyNodeRef::ModInteractive(_)
|
||||
|
@ -4123,9 +4172,10 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Arg(_)
|
||||
| AnyNodeRef::ArgWithDefault(_)
|
||||
| AnyNodeRef::Keyword(_)
|
||||
| AnyNodeRef::Alias(_)
|
||||
| AnyNodeRef::Withitem(_)
|
||||
| AnyNodeRef::WithItem(_)
|
||||
| AnyNodeRef::MatchCase(_)
|
||||
| AnyNodeRef::Decorator(_) => false,
|
||||
}
|
||||
|
@ -4201,13 +4251,14 @@ impl AnyNodeRef<'_> {
|
|||
| AnyNodeRef::PatternMatchStar(_)
|
||||
| AnyNodeRef::PatternMatchAs(_)
|
||||
| AnyNodeRef::PatternMatchOr(_)
|
||||
| AnyNodeRef::ExcepthandlerExceptHandler(_)
|
||||
| AnyNodeRef::ExceptHandlerExceptHandler(_)
|
||||
| AnyNodeRef::Comprehension(_)
|
||||
| AnyNodeRef::Arguments(_)
|
||||
| AnyNodeRef::Arg(_)
|
||||
| AnyNodeRef::ArgWithDefault(_)
|
||||
| AnyNodeRef::Keyword(_)
|
||||
| AnyNodeRef::Alias(_)
|
||||
| AnyNodeRef::Withitem(_)
|
||||
| AnyNodeRef::WithItem(_)
|
||||
| AnyNodeRef::MatchCase(_)
|
||||
| AnyNodeRef::Decorator(_) => false,
|
||||
}
|
||||
|
@ -4578,9 +4629,9 @@ impl<'a> From<&'a ExprSlice> for AnyNodeRef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a ExcepthandlerExceptHandler> for AnyNodeRef<'a> {
|
||||
fn from(node: &'a ExcepthandlerExceptHandler) -> Self {
|
||||
AnyNodeRef::ExcepthandlerExceptHandler(node)
|
||||
impl<'a> From<&'a ExceptHandlerExceptHandler> for AnyNodeRef<'a> {
|
||||
fn from(node: &'a ExceptHandlerExceptHandler) -> Self {
|
||||
AnyNodeRef::ExceptHandlerExceptHandler(node)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4738,11 +4789,11 @@ impl<'a> From<&'a Pattern> for AnyNodeRef<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Excepthandler> for AnyNodeRef<'a> {
|
||||
fn from(handler: &'a Excepthandler) -> Self {
|
||||
impl<'a> From<&'a ExceptHandler> for AnyNodeRef<'a> {
|
||||
fn from(handler: &'a ExceptHandler) -> Self {
|
||||
match handler {
|
||||
Excepthandler::ExceptHandler(handler) => {
|
||||
AnyNodeRef::ExcepthandlerExceptHandler(handler)
|
||||
ExceptHandler::ExceptHandler(handler) => {
|
||||
AnyNodeRef::ExceptHandlerExceptHandler(handler)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4771,6 +4822,11 @@ impl<'a> From<&'a Arg> for AnyNodeRef<'a> {
|
|||
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> {
|
||||
fn from(node: &'a Keyword) -> Self {
|
||||
AnyNodeRef::Keyword(node)
|
||||
|
@ -4781,9 +4837,9 @@ impl<'a> From<&'a Alias> for AnyNodeRef<'a> {
|
|||
AnyNodeRef::Alias(node)
|
||||
}
|
||||
}
|
||||
impl<'a> From<&'a Withitem> for AnyNodeRef<'a> {
|
||||
fn from(node: &'a Withitem) -> Self {
|
||||
AnyNodeRef::Withitem(node)
|
||||
impl<'a> From<&'a WithItem> for AnyNodeRef<'a> {
|
||||
fn from(node: &'a WithItem) -> Self {
|
||||
AnyNodeRef::WithItem(node)
|
||||
}
|
||||
}
|
||||
impl<'a> From<&'a MatchCase> for AnyNodeRef<'a> {
|
||||
|
@ -4853,7 +4909,7 @@ impl Ranged for AnyNodeRef<'_> {
|
|||
AnyNodeRef::ExprList(node) => node.range(),
|
||||
AnyNodeRef::ExprTuple(node) => node.range(),
|
||||
AnyNodeRef::ExprSlice(node) => node.range(),
|
||||
AnyNodeRef::ExcepthandlerExceptHandler(node) => node.range(),
|
||||
AnyNodeRef::ExceptHandlerExceptHandler(node) => node.range(),
|
||||
AnyNodeRef::PatternMatchValue(node) => node.range(),
|
||||
AnyNodeRef::PatternMatchSingleton(node) => node.range(),
|
||||
AnyNodeRef::PatternMatchSequence(node) => node.range(),
|
||||
|
@ -4866,9 +4922,10 @@ impl Ranged for AnyNodeRef<'_> {
|
|||
AnyNodeRef::Comprehension(node) => node.range(),
|
||||
AnyNodeRef::Arguments(node) => node.range(),
|
||||
AnyNodeRef::Arg(node) => node.range(),
|
||||
AnyNodeRef::ArgWithDefault(node) => node.range(),
|
||||
AnyNodeRef::Keyword(node) => node.range(),
|
||||
AnyNodeRef::Alias(node) => node.range(),
|
||||
AnyNodeRef::Withitem(node) => node.range(),
|
||||
AnyNodeRef::WithItem(node) => node.range(),
|
||||
AnyNodeRef::MatchCase(node) => node.range(),
|
||||
AnyNodeRef::Decorator(node) => node.range(),
|
||||
}
|
||||
|
@ -4935,7 +4992,7 @@ pub enum NodeKind {
|
|||
ExprList,
|
||||
ExprTuple,
|
||||
ExprSlice,
|
||||
ExcepthandlerExceptHandler,
|
||||
ExceptHandlerExceptHandler,
|
||||
PatternMatchValue,
|
||||
PatternMatchSingleton,
|
||||
PatternMatchSequence,
|
||||
|
@ -4948,9 +5005,10 @@ pub enum NodeKind {
|
|||
Comprehension,
|
||||
Arguments,
|
||||
Arg,
|
||||
ArgWithDefault,
|
||||
Keyword,
|
||||
Alias,
|
||||
Withitem,
|
||||
WithItem,
|
||||
MatchCase,
|
||||
Decorator,
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
//! Generate Python source code from an abstract syntax tree (AST).
|
||||
|
||||
use rustpython_ast::ArgWithDefault;
|
||||
use std::ops::Deref;
|
||||
|
||||
use rustpython_literal::escape::{AsciiEscape, Escape, UnicodeEscape};
|
||||
use rustpython_parser::ast::{
|
||||
self, Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant, ConversionFlag,
|
||||
Excepthandler, Expr, Identifier, MatchCase, Operator, Pattern, Stmt, Suite, Withitem,
|
||||
self, Alias, Arg, Arguments, BoolOp, CmpOp, Comprehension, Constant, ConversionFlag,
|
||||
ExceptHandler, Expr, Identifier, MatchCase, Operator, Pattern, Stmt, Suite, WithItem,
|
||||
};
|
||||
|
||||
use ruff_python_whitespace::LineEnding;
|
||||
|
@ -501,7 +502,7 @@ impl<'a> Generator<'a> {
|
|||
let mut first = true;
|
||||
for item in items {
|
||||
self.p_delim(&mut first, ", ");
|
||||
self.unparse_withitem(item);
|
||||
self.unparse_with_item(item);
|
||||
}
|
||||
self.p(":");
|
||||
});
|
||||
|
@ -513,7 +514,7 @@ impl<'a> Generator<'a> {
|
|||
let mut first = true;
|
||||
for item in items {
|
||||
self.p_delim(&mut first, ", ");
|
||||
self.unparse_withitem(item);
|
||||
self.unparse_with_item(item);
|
||||
}
|
||||
self.p(":");
|
||||
});
|
||||
|
@ -568,7 +569,7 @@ impl<'a> Generator<'a> {
|
|||
|
||||
for handler in handlers {
|
||||
statement!({
|
||||
self.unparse_excepthandler(handler, false);
|
||||
self.unparse_except_handler(handler, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -599,7 +600,7 @@ impl<'a> Generator<'a> {
|
|||
|
||||
for handler in handlers {
|
||||
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 {
|
||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler {
|
||||
type_,
|
||||
name,
|
||||
body,
|
||||
|
@ -870,7 +871,7 @@ impl<'a> Generator<'a> {
|
|||
values,
|
||||
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, {
|
||||
let mut first = true;
|
||||
for val in values {
|
||||
|
@ -929,7 +930,7 @@ impl<'a> Generator<'a> {
|
|||
let (op, prec) = opprec!(
|
||||
un,
|
||||
op,
|
||||
rustpython_parser::ast::Unaryop,
|
||||
rustpython_parser::ast::UnaryOp,
|
||||
Invert("~", INVERT),
|
||||
Not("not ", NOT),
|
||||
UAdd("+", UADD),
|
||||
|
@ -1087,16 +1088,16 @@ impl<'a> Generator<'a> {
|
|||
self.unparse_expr(left, new_lvl);
|
||||
for (op, cmp) in ops.iter().zip(comparators) {
|
||||
let op = match op {
|
||||
Cmpop::Eq => " == ",
|
||||
Cmpop::NotEq => " != ",
|
||||
Cmpop::Lt => " < ",
|
||||
Cmpop::LtE => " <= ",
|
||||
Cmpop::Gt => " > ",
|
||||
Cmpop::GtE => " >= ",
|
||||
Cmpop::Is => " is ",
|
||||
Cmpop::IsNot => " is not ",
|
||||
Cmpop::In => " in ",
|
||||
Cmpop::NotIn => " not in ",
|
||||
CmpOp::Eq => " == ",
|
||||
CmpOp::NotEq => " != ",
|
||||
CmpOp::Lt => " < ",
|
||||
CmpOp::LtE => " <= ",
|
||||
CmpOp::Gt => " > ",
|
||||
CmpOp::GtE => " >= ",
|
||||
CmpOp::Is => " is ",
|
||||
CmpOp::IsNot => " is not ",
|
||||
CmpOp::In => " in ",
|
||||
CmpOp::NotIn => " not in ",
|
||||
};
|
||||
self.p(op);
|
||||
self.unparse_expr(cmp, new_lvl);
|
||||
|
@ -1290,14 +1291,9 @@ impl<'a> Generator<'a> {
|
|||
|
||||
fn unparse_args<U>(&mut self, args: &Arguments<U>) {
|
||||
let mut first = true;
|
||||
let defaults_start = args.posonlyargs.len() + args.args.len() - args.defaults.len();
|
||||
for (i, arg) in args.posonlyargs.iter().chain(&args.args).enumerate() {
|
||||
for (i, arg_with_default) in args.posonlyargs.iter().chain(&args.args).enumerate() {
|
||||
self.p_delim(&mut first, ", ");
|
||||
self.unparse_arg(arg);
|
||||
if let Some(i) = i.checked_sub(defaults_start) {
|
||||
self.p("=");
|
||||
self.unparse_expr(&args.defaults[i], precedence::COMMA);
|
||||
}
|
||||
self.unparse_arg_with_default(arg_with_default);
|
||||
self.p_if(i + 1 == args.posonlyargs.len(), ", /");
|
||||
}
|
||||
if args.vararg.is_some() || !args.kwonlyargs.is_empty() {
|
||||
|
@ -1307,17 +1303,9 @@ impl<'a> Generator<'a> {
|
|||
if let Some(vararg) = &args.vararg {
|
||||
self.unparse_arg(vararg);
|
||||
}
|
||||
let defaults_start = args.kwonlyargs.len() - args.kw_defaults.len();
|
||||
for (i, kwarg) in args.kwonlyargs.iter().enumerate() {
|
||||
for kwarg in &args.kwonlyargs {
|
||||
self.p_delim(&mut first, ", ");
|
||||
self.unparse_arg(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);
|
||||
}
|
||||
self.unparse_arg_with_default(kwarg);
|
||||
}
|
||||
if let Some(kwarg) = &args.kwarg {
|
||||
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>]) {
|
||||
for comp in generators {
|
||||
self.p(if comp.is_async {
|
||||
|
@ -1445,9 +1441,9 @@ impl<'a> Generator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn unparse_withitem<U>(&mut self, withitem: &Withitem<U>) {
|
||||
self.unparse_expr(&withitem.context_expr, precedence::MAX);
|
||||
if let Some(optional_vars) = &withitem.optional_vars {
|
||||
fn unparse_with_item<U>(&mut self, with_item: &WithItem<U>) {
|
||||
self.unparse_expr(&with_item.context_expr, precedence::MAX);
|
||||
if let Some(optional_vars) = &with_item.optional_vars {
|
||||
self.p(" as ");
|
||||
self.unparse_expr(optional_vars, precedence::MAX);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! 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.
|
||||
pub trait StatementVisitor<'a> {
|
||||
|
@ -10,8 +10,8 @@ pub trait StatementVisitor<'a> {
|
|||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||
walk_stmt(self, stmt);
|
||||
}
|
||||
fn visit_excepthandler(&mut self, excepthandler: &'a Excepthandler) {
|
||||
walk_excepthandler(self, excepthandler);
|
||||
fn visit_except_handler(&mut self, except_handler: &'a ExceptHandler) {
|
||||
walk_except_handler(self, except_handler);
|
||||
}
|
||||
fn visit_match_case(&mut self, match_case: &'a MatchCase) {
|
||||
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,
|
||||
}) => {
|
||||
visitor.visit_body(body);
|
||||
for excepthandler in handlers {
|
||||
visitor.visit_excepthandler(excepthandler);
|
||||
for except_handler in handlers {
|
||||
visitor.visit_except_handler(except_handler);
|
||||
}
|
||||
visitor.visit_body(orelse);
|
||||
visitor.visit_body(finalbody);
|
||||
|
@ -84,8 +84,8 @@ pub fn walk_stmt<'a, V: StatementVisitor<'a> + ?Sized>(visitor: &mut V, stmt: &'
|
|||
range: _range,
|
||||
}) => {
|
||||
visitor.visit_body(body);
|
||||
for excepthandler in handlers {
|
||||
visitor.visit_excepthandler(excepthandler);
|
||||
for except_handler in handlers {
|
||||
visitor.visit_except_handler(except_handler);
|
||||
}
|
||||
visitor.visit_body(orelse);
|
||||
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,
|
||||
excepthandler: &'a Excepthandler,
|
||||
except_handler: &'a ExceptHandler,
|
||||
) {
|
||||
match excepthandler {
|
||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { body, .. }) => {
|
||||
match except_handler {
|
||||
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { body, .. }) => {
|
||||
visitor.visit_body(body);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
pub mod preorder;
|
||||
|
||||
use rustpython_ast::Decorator;
|
||||
use rustpython_ast::{ArgWithDefault, Decorator};
|
||||
use rustpython_parser::ast::{
|
||||
self, Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant, Excepthandler, Expr,
|
||||
ExprContext, Keyword, MatchCase, Operator, Pattern, Stmt, Unaryop, Withitem,
|
||||
self, Alias, Arg, Arguments, BoolOp, CmpOp, Comprehension, Constant, ExceptHandler, Expr,
|
||||
ExprContext, Keyword, MatchCase, Operator, Pattern, Stmt, UnaryOp, WithItem,
|
||||
};
|
||||
|
||||
/// 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) {
|
||||
walk_expr_context(self, expr_context);
|
||||
}
|
||||
fn visit_boolop(&mut self, boolop: &'a Boolop) {
|
||||
walk_boolop(self, boolop);
|
||||
fn visit_bool_op(&mut self, bool_op: &'a BoolOp) {
|
||||
walk_bool_op(self, bool_op);
|
||||
}
|
||||
fn visit_operator(&mut self, operator: &'a Operator) {
|
||||
walk_operator(self, operator);
|
||||
}
|
||||
fn visit_unaryop(&mut self, unaryop: &'a Unaryop) {
|
||||
walk_unaryop(self, unaryop);
|
||||
fn visit_unary_op(&mut self, unary_op: &'a UnaryOp) {
|
||||
walk_unary_op(self, unary_op);
|
||||
}
|
||||
fn visit_cmpop(&mut self, cmpop: &'a Cmpop) {
|
||||
walk_cmpop(self, cmpop);
|
||||
fn visit_cmp_op(&mut self, cmp_op: &'a CmpOp) {
|
||||
walk_cmp_op(self, cmp_op);
|
||||
}
|
||||
fn visit_comprehension(&mut self, comprehension: &'a Comprehension) {
|
||||
walk_comprehension(self, comprehension);
|
||||
}
|
||||
fn visit_excepthandler(&mut self, excepthandler: &'a Excepthandler) {
|
||||
walk_excepthandler(self, excepthandler);
|
||||
fn visit_except_handler(&mut self, except_handler: &'a ExceptHandler) {
|
||||
walk_except_handler(self, except_handler);
|
||||
}
|
||||
fn visit_format_spec(&mut self, format_spec: &'a Expr) {
|
||||
walk_expr(self, format_spec);
|
||||
|
@ -61,14 +61,17 @@ pub trait Visitor<'a> {
|
|||
fn visit_arg(&mut self, arg: &'a 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) {
|
||||
walk_keyword(self, keyword);
|
||||
}
|
||||
fn visit_alias(&mut self, alias: &'a Alias) {
|
||||
walk_alias(self, alias);
|
||||
}
|
||||
fn visit_withitem(&mut self, withitem: &'a Withitem) {
|
||||
walk_withitem(self, withitem);
|
||||
fn visit_with_item(&mut self, with_item: &'a WithItem) {
|
||||
walk_with_item(self, with_item);
|
||||
}
|
||||
fn visit_match_case(&mut self, match_case: &'a MatchCase) {
|
||||
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);
|
||||
}
|
||||
Stmt::With(ast::StmtWith { items, body, .. }) => {
|
||||
for withitem in items {
|
||||
visitor.visit_withitem(withitem);
|
||||
for with_item in items {
|
||||
visitor.visit_with_item(with_item);
|
||||
}
|
||||
visitor.visit_body(body);
|
||||
}
|
||||
Stmt::AsyncWith(ast::StmtAsyncWith { items, body, .. }) => {
|
||||
for withitem in items {
|
||||
visitor.visit_withitem(withitem);
|
||||
for with_item in items {
|
||||
visitor.visit_with_item(with_item);
|
||||
}
|
||||
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,
|
||||
}) => {
|
||||
visitor.visit_body(body);
|
||||
for excepthandler in handlers {
|
||||
visitor.visit_excepthandler(excepthandler);
|
||||
for except_handler in handlers {
|
||||
visitor.visit_except_handler(except_handler);
|
||||
}
|
||||
visitor.visit_body(orelse);
|
||||
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,
|
||||
}) => {
|
||||
visitor.visit_body(body);
|
||||
for excepthandler in handlers {
|
||||
visitor.visit_excepthandler(excepthandler);
|
||||
for except_handler in handlers {
|
||||
visitor.visit_except_handler(except_handler);
|
||||
}
|
||||
visitor.visit_body(orelse);
|
||||
visitor.visit_body(finalbody);
|
||||
|
@ -333,7 +336,7 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) {
|
|||
values,
|
||||
range: _range,
|
||||
}) => {
|
||||
visitor.visit_boolop(op);
|
||||
visitor.visit_bool_op(op);
|
||||
for expr in values {
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
|
@ -361,7 +364,7 @@ pub fn walk_expr<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, expr: &'a Expr) {
|
|||
operand,
|
||||
range: _range,
|
||||
}) => {
|
||||
visitor.visit_unaryop(op);
|
||||
visitor.visit_unary_op(op);
|
||||
visitor.visit_expr(operand);
|
||||
}
|
||||
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,
|
||||
}) => {
|
||||
visitor.visit_expr(left);
|
||||
for cmpop in ops {
|
||||
visitor.visit_cmpop(cmpop);
|
||||
for cmp_op in ops {
|
||||
visitor.visit_cmp_op(cmp_op);
|
||||
}
|
||||
for expr in comparators {
|
||||
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,
|
||||
excepthandler: &'a Excepthandler,
|
||||
except_handler: &'a ExceptHandler,
|
||||
) {
|
||||
match excepthandler {
|
||||
Excepthandler::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, body, .. }) => {
|
||||
match except_handler {
|
||||
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, body, .. }) => {
|
||||
if let Some(expr) = type_ {
|
||||
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) {
|
||||
for arg in &arguments.posonlyargs {
|
||||
visitor.visit_arg(arg);
|
||||
visitor.visit_arg_with_default(arg);
|
||||
}
|
||||
for arg in &arguments.args {
|
||||
visitor.visit_arg(arg);
|
||||
visitor.visit_arg_with_default(arg);
|
||||
}
|
||||
if let Some(arg) = &arguments.vararg {
|
||||
visitor.visit_arg(arg);
|
||||
}
|
||||
for arg in &arguments.kwonlyargs {
|
||||
visitor.visit_arg(arg);
|
||||
}
|
||||
for expr in &arguments.kw_defaults {
|
||||
visitor.visit_expr(expr);
|
||||
visitor.visit_arg_with_default(arg);
|
||||
}
|
||||
if let Some(arg) = &arguments.kwarg {
|
||||
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) {
|
||||
|
@ -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) {
|
||||
visitor.visit_expr(&keyword.value);
|
||||
}
|
||||
|
||||
pub fn walk_withitem<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, withitem: &'a Withitem) {
|
||||
visitor.visit_expr(&withitem.context_expr);
|
||||
if let Some(expr) = &withitem.optional_vars {
|
||||
pub fn walk_with_item<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, with_item: &'a WithItem) {
|
||||
visitor.visit_expr(&with_item.context_expr);
|
||||
if let Some(expr) = &with_item.optional_vars {
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
}
|
||||
|
@ -719,16 +726,16 @@ pub fn walk_expr_context<'a, V: Visitor<'a> + ?Sized>(
|
|||
}
|
||||
|
||||
#[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)]
|
||||
pub fn walk_operator<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, operator: &'a Operator) {}
|
||||
|
||||
#[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)]
|
||||
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)]
|
||||
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);
|
||||
}
|
||||
|
||||
fn visit_boolop(&mut self, boolop: &'a Boolop) {
|
||||
walk_boolop(self, boolop);
|
||||
fn visit_bool_op(&mut self, bool_op: &'a BoolOp) {
|
||||
walk_bool_op(self, bool_op);
|
||||
}
|
||||
|
||||
fn visit_operator(&mut self, operator: &'a Operator) {
|
||||
walk_operator(self, operator);
|
||||
}
|
||||
|
||||
fn visit_unaryop(&mut self, unaryop: &'a Unaryop) {
|
||||
walk_unaryop(self, unaryop);
|
||||
fn visit_unary_op(&mut self, unary_op: &'a UnaryOp) {
|
||||
walk_unary_op(self, unary_op);
|
||||
}
|
||||
|
||||
fn visit_cmpop(&mut self, cmpop: &'a Cmpop) {
|
||||
walk_cmpop(self, cmpop);
|
||||
fn visit_cmp_op(&mut self, cmp_op: &'a CmpOp) {
|
||||
walk_cmp_op(self, cmp_op);
|
||||
}
|
||||
|
||||
fn visit_comprehension(&mut self, comprehension: &'a Comprehension) {
|
||||
walk_comprehension(self, comprehension);
|
||||
}
|
||||
|
||||
fn visit_excepthandler(&mut self, excepthandler: &'a Excepthandler) {
|
||||
walk_excepthandler(self, excepthandler);
|
||||
fn visit_except_handler(&mut self, except_handler: &'a ExceptHandler) {
|
||||
walk_except_handler(self, except_handler);
|
||||
}
|
||||
|
||||
fn visit_format_spec(&mut self, format_spec: &'a Expr) {
|
||||
|
@ -62,6 +62,10 @@ pub trait PreorderVisitor<'a> {
|
|||
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) {
|
||||
walk_keyword(self, keyword);
|
||||
}
|
||||
|
@ -70,8 +74,8 @@ pub trait PreorderVisitor<'a> {
|
|||
walk_alias(self, alias);
|
||||
}
|
||||
|
||||
fn visit_withitem(&mut self, withitem: &'a Withitem) {
|
||||
walk_withitem(self, withitem);
|
||||
fn visit_with_item(&mut self, with_item: &'a WithItem) {
|
||||
walk_with_item(self, with_item);
|
||||
}
|
||||
|
||||
fn visit_match_case(&mut self, match_case: &'a MatchCase) {
|
||||
|
@ -300,8 +304,8 @@ where
|
|||
type_comment: _,
|
||||
range: _,
|
||||
}) => {
|
||||
for withitem in items {
|
||||
visitor.visit_withitem(withitem);
|
||||
for with_item in items {
|
||||
visitor.visit_with_item(with_item);
|
||||
}
|
||||
visitor.visit_body(body);
|
||||
}
|
||||
|
@ -345,8 +349,8 @@ where
|
|||
range: _range,
|
||||
}) => {
|
||||
visitor.visit_body(body);
|
||||
for excepthandler in handlers {
|
||||
visitor.visit_excepthandler(excepthandler);
|
||||
for except_handler in handlers {
|
||||
visitor.visit_except_handler(except_handler);
|
||||
}
|
||||
visitor.visit_body(orelse);
|
||||
visitor.visit_body(finalbody);
|
||||
|
@ -410,13 +414,13 @@ where
|
|||
}) => match values.as_slice() {
|
||||
[left, rest @ ..] => {
|
||||
visitor.visit_expr(left);
|
||||
visitor.visit_boolop(op);
|
||||
visitor.visit_bool_op(op);
|
||||
for expr in rest {
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
}
|
||||
[] => {
|
||||
visitor.visit_boolop(op);
|
||||
visitor.visit_bool_op(op);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -445,7 +449,7 @@ where
|
|||
operand,
|
||||
range: _range,
|
||||
}) => {
|
||||
visitor.visit_unaryop(op);
|
||||
visitor.visit_unary_op(op);
|
||||
visitor.visit_expr(operand);
|
||||
}
|
||||
|
||||
|
@ -565,7 +569,7 @@ where
|
|||
visitor.visit_expr(left);
|
||||
|
||||
for (op, comparator) in ops.iter().zip(comparators) {
|
||||
visitor.visit_cmpop(op);
|
||||
visitor.visit_cmp_op(op);
|
||||
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
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
{
|
||||
match excepthandler {
|
||||
Excepthandler::ExceptHandler(ExcepthandlerExceptHandler {
|
||||
match except_handler {
|
||||
ExceptHandler::ExceptHandler(ExceptHandlerExceptHandler {
|
||||
range: _,
|
||||
type_,
|
||||
name: _,
|
||||
|
@ -726,34 +730,16 @@ pub fn walk_arguments<'a, V>(visitor: &mut V, arguments: &'a Arguments)
|
|||
where
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
{
|
||||
let non_default_args_len =
|
||||
arguments.posonlyargs.len() + arguments.args.len() - arguments.defaults.len();
|
||||
|
||||
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);
|
||||
for arg in arguments.posonlyargs.iter().chain(&arguments.args) {
|
||||
visitor.visit_arg_with_default(arg);
|
||||
}
|
||||
|
||||
if let Some(arg) = &arguments.vararg {
|
||||
visitor.visit_arg(arg);
|
||||
}
|
||||
|
||||
let non_default_kwargs_len = arguments.kwonlyargs.len() - arguments.kw_defaults.len();
|
||||
let mut kwargsonly_iter = arguments.kwonlyargs.iter();
|
||||
|
||||
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);
|
||||
for arg in &arguments.kwonlyargs {
|
||||
visitor.visit_arg_with_default(arg);
|
||||
}
|
||||
|
||||
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]
|
||||
pub fn walk_keyword<'a, V>(visitor: &mut V, keyword: &'a Keyword)
|
||||
where
|
||||
|
@ -778,13 +774,13 @@ where
|
|||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
{
|
||||
|
@ -899,14 +895,14 @@ where
|
|||
}
|
||||
|
||||
#[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
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
{
|
||||
}
|
||||
|
||||
#[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
|
||||
V: PreorderVisitor<'a> + ?Sized,
|
||||
{
|
||||
|
@ -923,11 +919,11 @@ where
|
|||
mod tests {
|
||||
use crate::node::AnyNodeRef;
|
||||
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_withitem, Alias, Arg, Arguments, Boolop, Cmpop, Comprehension, Constant,
|
||||
Excepthandler, Expr, Keyword, MatchCase, Mod, Operator, Pattern, PreorderVisitor, Stmt,
|
||||
String, TypeIgnore, Unaryop, Withitem,
|
||||
walk_with_item, Alias, Arg, Arguments, BoolOp, CmpOp, Comprehension, Constant,
|
||||
ExceptHandler, Expr, Keyword, MatchCase, Mod, Operator, Pattern, PreorderVisitor, Stmt,
|
||||
String, TypeIgnore, UnaryOp, WithItem,
|
||||
};
|
||||
use insta::assert_snapshot;
|
||||
use rustpython_parser::lexer::lex;
|
||||
|
@ -1089,20 +1085,20 @@ class A:
|
|||
self.emit(&constant);
|
||||
}
|
||||
|
||||
fn visit_boolop(&mut self, boolop: &Boolop) {
|
||||
self.emit(&boolop);
|
||||
fn visit_bool_op(&mut self, bool_op: &BoolOp) {
|
||||
self.emit(&bool_op);
|
||||
}
|
||||
|
||||
fn visit_operator(&mut self, operator: &Operator) {
|
||||
self.emit(&operator);
|
||||
}
|
||||
|
||||
fn visit_unaryop(&mut self, unaryop: &Unaryop) {
|
||||
self.emit(&unaryop);
|
||||
fn visit_unary_op(&mut self, unary_op: &UnaryOp) {
|
||||
self.emit(&unary_op);
|
||||
}
|
||||
|
||||
fn visit_cmpop(&mut self, cmpop: &Cmpop) {
|
||||
self.emit(&cmpop);
|
||||
fn visit_cmp_op(&mut self, cmp_op: &CmpOp) {
|
||||
self.emit(&cmp_op);
|
||||
}
|
||||
|
||||
fn visit_comprehension(&mut self, comprehension: &Comprehension) {
|
||||
|
@ -1111,9 +1107,9 @@ class A:
|
|||
self.exit_node();
|
||||
}
|
||||
|
||||
fn visit_excepthandler(&mut self, excepthandler: &Excepthandler) {
|
||||
self.enter_node(excepthandler);
|
||||
walk_excepthandler(self, excepthandler);
|
||||
fn visit_except_handler(&mut self, except_handler: &ExceptHandler) {
|
||||
self.enter_node(except_handler);
|
||||
walk_except_handler(self, except_handler);
|
||||
self.exit_node();
|
||||
}
|
||||
|
||||
|
@ -1147,9 +1143,9 @@ class A:
|
|||
self.exit_node();
|
||||
}
|
||||
|
||||
fn visit_withitem(&mut self, withitem: &Withitem) {
|
||||
self.enter_node(withitem);
|
||||
walk_withitem(self, withitem);
|
||||
fn visit_with_item(&mut self, with_item: &WithItem) {
|
||||
self.enter_node(with_item);
|
||||
walk_with_item(self, with_item);
|
||||
self.exit_node();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,21 +14,21 @@ pub(super) fn place_comment<'a>(
|
|||
comment: DecoratedComment<'a>,
|
||||
locator: &Locator,
|
||||
) -> CommentPlacement<'a> {
|
||||
handle_in_between_excepthandlers_or_except_handler_and_else_or_finally_comment(comment, locator)
|
||||
.or_else(|comment| handle_match_comment(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_trailing_body_comment(comment, locator))
|
||||
.or_else(handle_trailing_end_of_line_body_comment)
|
||||
.or_else(|comment| handle_trailing_end_of_line_condition_comment(comment, locator))
|
||||
.or_else(|comment| {
|
||||
handle_module_level_own_line_comment_before_class_or_function_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)
|
||||
handle_in_between_except_handlers_or_except_handler_and_else_or_finally_comment(
|
||||
comment, locator,
|
||||
)
|
||||
.or_else(|comment| handle_match_comment(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_trailing_body_comment(comment, locator))
|
||||
.or_else(handle_trailing_end_of_line_body_comment)
|
||||
.or_else(|comment| handle_trailing_end_of_line_condition_comment(comment, locator))
|
||||
.or_else(|comment| {
|
||||
handle_module_level_own_line_comment_before_class_or_function_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)
|
||||
}
|
||||
|
||||
/// 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.
|
||||
fn handle_in_between_excepthandlers_or_except_handler_and_else_or_finally_comment<'a>(
|
||||
/// Handles comments between except handlers and between the last except handler and any following `else` or `finally` block.
|
||||
fn handle_in_between_except_handlers_or_except_handler_and_else_or_finally_comment<'a>(
|
||||
comment: DecoratedComment<'a>,
|
||||
locator: &Locator,
|
||||
) -> CommentPlacement<'a> {
|
||||
|
@ -147,7 +147,7 @@ fn handle_in_between_excepthandlers_or_except_handler_and_else_or_finally_commen
|
|||
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.
|
||||
// the following `elif` or indeed a trailing comment of the previous body's last statement.
|
||||
let comment_indentation =
|
||||
|
@ -627,11 +627,8 @@ fn handle_positional_only_arguments_separator_comment<'a>(
|
|||
// ```python
|
||||
// def test(a=10, /, b): pass
|
||||
// ```
|
||||
|| arguments
|
||||
.defaults
|
||||
.iter()
|
||||
.position(|default| AnyNodeRef::from(default).ptr_eq(last_argument_or_default))
|
||||
== Some(arguments.posonlyargs.len().saturating_sub(1));
|
||||
|| are_same_optional(last_argument_or_default, arguments
|
||||
.posonlyargs.last().and_then(|arg| arg.default.as_deref()));
|
||||
|
||||
if !is_last_positional_argument {
|
||||
return CommentPlacement::Default(comment);
|
||||
|
@ -906,7 +903,7 @@ fn last_child_in_body(node: AnyNodeRef) -> Option<AnyNodeRef> {
|
|||
| AnyNodeRef::StmtWith(StmtWith { body, .. })
|
||||
| AnyNodeRef::StmtAsyncWith(StmtAsyncWith { body, .. })
|
||||
| AnyNodeRef::MatchCase(MatchCase { body, .. })
|
||||
| AnyNodeRef::ExcepthandlerExceptHandler(ExcepthandlerExceptHandler { body, .. }) => body,
|
||||
| AnyNodeRef::ExceptHandlerExceptHandler(ExceptHandlerExceptHandler { body, .. }) => body,
|
||||
|
||||
AnyNodeRef::StmtIf(StmtIf { 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())
|
||||
// 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() || !orelse.is_empty())
|
||||
&& are_same_optional(following, finalbody.first())
|
||||
|
|
|
@ -34,7 +34,7 @@ expression: comments.debug(test_case.source_code)
|
|||
],
|
||||
},
|
||||
Node {
|
||||
kind: ExcepthandlerExceptHandler,
|
||||
kind: ExceptHandlerExceptHandler,
|
||||
range: 100..136,
|
||||
source: `except Exception as ex:⏎`,
|
||||
}: {
|
||||
|
|
|
@ -39,7 +39,7 @@ expression: comments.debug(test_case.source_code)
|
|||
],
|
||||
},
|
||||
Node {
|
||||
kind: ExcepthandlerExceptHandler,
|
||||
kind: ExceptHandlerExceptHandler,
|
||||
range: 68..100,
|
||||
source: `except Exception as ex:⏎`,
|
||||
}: {
|
||||
|
|
|
@ -208,11 +208,11 @@ impl<'ast> PreorderVisitor<'ast> for CommentsVisitor<'ast> {
|
|||
self.finish_node(comprehension);
|
||||
}
|
||||
|
||||
fn visit_excepthandler(&mut self, excepthandler: &'ast Excepthandler) {
|
||||
if self.start_node(excepthandler).is_traverse() {
|
||||
walk_excepthandler(self, excepthandler);
|
||||
fn visit_except_handler(&mut self, except_handler: &'ast ExceptHandler) {
|
||||
if self.start_node(except_handler).is_traverse() {
|
||||
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) {
|
||||
|
@ -250,12 +250,12 @@ impl<'ast> PreorderVisitor<'ast> for CommentsVisitor<'ast> {
|
|||
self.finish_node(alias);
|
||||
}
|
||||
|
||||
fn visit_withitem(&mut self, withitem: &'ast Withitem) {
|
||||
if self.start_node(withitem).is_traverse() {
|
||||
walk_withitem(self, withitem);
|
||||
fn visit_with_item(&mut self, with_item: &'ast WithItem) {
|
||||
if self.start_node(with_item).is_traverse() {
|
||||
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) {
|
||||
|
|
|
@ -10,7 +10,7 @@ use ruff_formatter::{
|
|||
};
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use rustpython_parser::ast::{
|
||||
Constant, Expr, ExprAttribute, ExprBinOp, ExprConstant, ExprUnaryOp, Operator, Unaryop,
|
||||
Constant, Expr, ExprAttribute, ExprBinOp, ExprConstant, ExprUnaryOp, Operator, UnaryOp,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -116,7 +116,7 @@ const fn is_simple_power_expression(expr: &ExprBinOp) -> bool {
|
|||
const fn is_simple_power_operand(expr: &Expr) -> bool {
|
||||
match expr {
|
||||
Expr::UnaryOp(ExprUnaryOp {
|
||||
op: Unaryop::Not, ..
|
||||
op: UnaryOp::Not, ..
|
||||
}) => false,
|
||||
Expr::Constant(ExprConstant {
|
||||
value: Constant::Complex { .. } | Constant::Float(_) | Constant::Int(_),
|
||||
|
|
|
@ -2253,42 +2253,44 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::ExprSlice {
|
|||
}
|
||||
}
|
||||
|
||||
impl FormatRule<ast::ExcepthandlerExceptHandler, PyFormatContext<'_>>
|
||||
for crate::other::excepthandler_except_handler::FormatExcepthandlerExceptHandler
|
||||
impl FormatRule<ast::ExceptHandlerExceptHandler, PyFormatContext<'_>>
|
||||
for crate::other::except_handler_except_handler::FormatExceptHandlerExceptHandler
|
||||
{
|
||||
#[inline]
|
||||
fn fmt(
|
||||
&self,
|
||||
node: &ast::ExcepthandlerExceptHandler,
|
||||
node: &ast::ExceptHandlerExceptHandler,
|
||||
f: &mut Formatter<PyFormatContext<'_>>,
|
||||
) -> 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<
|
||||
'a,
|
||||
ast::ExcepthandlerExceptHandler,
|
||||
crate::other::excepthandler_except_handler::FormatExcepthandlerExceptHandler,
|
||||
ast::ExceptHandlerExceptHandler,
|
||||
crate::other::except_handler_except_handler::FormatExceptHandlerExceptHandler,
|
||||
PyFormatContext<'ast>,
|
||||
>;
|
||||
fn format(&self) -> Self::Format<'_> {
|
||||
FormatRefWithRule::new(
|
||||
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<
|
||||
ast::ExcepthandlerExceptHandler,
|
||||
crate::other::excepthandler_except_handler::FormatExcepthandlerExceptHandler,
|
||||
ast::ExceptHandlerExceptHandler,
|
||||
crate::other::except_handler_except_handler::FormatExceptHandlerExceptHandler,
|
||||
PyFormatContext<'ast>,
|
||||
>;
|
||||
fn into_format(self) -> Self::Format {
|
||||
FormatOwnedWithRule::new(
|
||||
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 {
|
||||
#[inline]
|
||||
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]
|
||||
fn fmt(
|
||||
&self,
|
||||
node: &ast::Withitem,
|
||||
node: &ast::WithItem,
|
||||
f: &mut Formatter<PyFormatContext<'_>>,
|
||||
) -> 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<
|
||||
'a,
|
||||
ast::Withitem,
|
||||
crate::other::withitem::FormatWithitem,
|
||||
ast::WithItem,
|
||||
crate::other::with_item::FormatWithItem,
|
||||
PyFormatContext<'ast>,
|
||||
>;
|
||||
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<
|
||||
ast::Withitem,
|
||||
crate::other::withitem::FormatWithitem,
|
||||
ast::WithItem,
|
||||
crate::other::with_item::FormatWithItem,
|
||||
PyFormatContext<'ast>,
|
||||
>;
|
||||
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::context::NodeLevel;
|
||||
use crate::prelude::*;
|
||||
use crate::trivia::{first_non_trivia_token, SimpleTokenizer, Token, TokenKind};
|
||||
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)]
|
||||
pub struct FormatArguments;
|
||||
|
@ -17,10 +20,8 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
|||
range: _,
|
||||
posonlyargs,
|
||||
args,
|
||||
defaults,
|
||||
vararg,
|
||||
kwonlyargs,
|
||||
kw_defaults,
|
||||
kwarg,
|
||||
} = item;
|
||||
|
||||
|
@ -32,30 +33,30 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
|||
let mut joiner = f.join_with(separator);
|
||||
let mut last_node: Option<AnyNodeRef> = None;
|
||||
|
||||
let mut defaults = std::iter::repeat(None)
|
||||
.take(posonlyargs.len() + args.len() - defaults.len())
|
||||
.chain(defaults.iter().map(Some));
|
||||
for arg_with_default in posonlyargs {
|
||||
joiner.entry(&arg_with_default.into_format());
|
||||
|
||||
for positional in posonlyargs {
|
||||
let default = defaults.next().ok_or(FormatError::SyntaxError)?;
|
||||
joiner.entry(&ArgumentWithDefault {
|
||||
argument: positional,
|
||||
default,
|
||||
});
|
||||
|
||||
last_node = Some(default.map_or_else(|| positional.into(), AnyNodeRef::from));
|
||||
last_node = Some(
|
||||
arg_with_default
|
||||
.default
|
||||
.as_deref()
|
||||
.map_or_else(|| (&arg_with_default.def).into(), AnyNodeRef::from),
|
||||
);
|
||||
}
|
||||
|
||||
if !posonlyargs.is_empty() {
|
||||
joiner.entry(&text("/"));
|
||||
}
|
||||
|
||||
for argument in args {
|
||||
let default = defaults.next().ok_or(FormatError::SyntaxError)?;
|
||||
for arg_with_default in args {
|
||||
joiner.entry(&arg_with_default.into_format());
|
||||
|
||||
joiner.entry(&ArgumentWithDefault { argument, default });
|
||||
|
||||
last_node = Some(default.map_or_else(|| argument.into(), AnyNodeRef::from));
|
||||
last_node = Some(
|
||||
arg_with_default
|
||||
.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 `*`
|
||||
|
@ -72,24 +73,17 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
|||
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)
|
||||
.take(kwonlyargs.len() - kw_defaults.len())
|
||||
.chain(kw_defaults.iter().map(Some));
|
||||
|
||||
for keyword_argument in kwonlyargs {
|
||||
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));
|
||||
last_node = Some(
|
||||
arg_with_default
|
||||
.default
|
||||
.as_deref()
|
||||
.map_or_else(|| (&arg_with_default.def).into(), AnyNodeRef::from),
|
||||
);
|
||||
}
|
||||
|
||||
debug_assert!(defaults.next().is_none());
|
||||
|
||||
if let Some(kwarg) = kwarg {
|
||||
joiner.entry(&format_args![
|
||||
leading_node_comments(kwarg.as_ref()),
|
||||
|
@ -173,21 +167,3 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
|||
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 ruff_formatter::{write, Buffer, FormatResult};
|
||||
use rustpython_parser::ast::ExcepthandlerExceptHandler;
|
||||
use rustpython_parser::ast::ExceptHandlerExceptHandler;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatExcepthandlerExceptHandler;
|
||||
pub struct FormatExceptHandlerExceptHandler;
|
||||
|
||||
impl FormatNodeRule<ExcepthandlerExceptHandler> for FormatExcepthandlerExceptHandler {
|
||||
impl FormatNodeRule<ExceptHandlerExceptHandler> for FormatExceptHandlerExceptHandler {
|
||||
fn fmt_fields(
|
||||
&self,
|
||||
item: &ExcepthandlerExceptHandler,
|
||||
item: &ExceptHandlerExceptHandler,
|
||||
f: &mut PyFormatter,
|
||||
) -> FormatResult<()> {
|
||||
write!(f, [not_yet_implemented(item)])
|
|
@ -1,10 +1,11 @@
|
|||
pub(crate) mod alias;
|
||||
pub(crate) mod arg;
|
||||
pub(crate) mod arg_with_default;
|
||||
pub(crate) mod arguments;
|
||||
pub(crate) mod comprehension;
|
||||
pub(crate) mod decorator;
|
||||
pub(crate) mod excepthandler_except_handler;
|
||||
pub(crate) mod except_handler_except_handler;
|
||||
pub(crate) mod keyword;
|
||||
pub(crate) mod match_case;
|
||||
pub(crate) mod type_ignore_type_ignore;
|
||||
pub(crate) mod withitem;
|
||||
pub(crate) mod with_item;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use rustpython_parser::ast::Withitem;
|
||||
use rustpython_parser::ast::WithItem;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatWithitem;
|
||||
pub struct FormatWithItem;
|
||||
|
||||
impl FormatNodeRule<Withitem> for FormatWithitem {
|
||||
fn fmt_fields(&self, item: &Withitem, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
impl FormatNodeRule<WithItem> for FormatWithItem {
|
||||
fn fmt_fields(&self, item: &WithItem, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
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