mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 10:48:32 +00:00
Handle multiple receiver decorators in receiver-decorator (#2858)
This commit is contained in:
parent
15f65fa8d6
commit
1705574e75
4 changed files with 51 additions and 18 deletions
|
@ -15,3 +15,23 @@ def correct_pre_save_handler():
|
|||
@receiver(pre_save, sender=MyModel)
|
||||
def incorrect_pre_save_handler():
|
||||
pass
|
||||
|
||||
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
@test_decorator
|
||||
def correct_multiple():
|
||||
pass
|
||||
|
||||
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
def correct_multiple():
|
||||
pass
|
||||
|
||||
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
@test_decorator
|
||||
@receiver(pre_save, sender=MyModel)
|
||||
def incorrect_multiple():
|
||||
pass
|
||||
|
|
|
@ -465,13 +465,11 @@ where
|
|||
..
|
||||
} => {
|
||||
if self.settings.rules.enabled(&Rule::ReceiverDecoratorChecker) {
|
||||
if let Some(diagnostic) =
|
||||
flake8_django::rules::receiver_decorator_checker(decorator_list, |expr| {
|
||||
self.resolve_call_path(expr)
|
||||
})
|
||||
{
|
||||
self.diagnostics.push(diagnostic);
|
||||
}
|
||||
self.diagnostics
|
||||
.extend(flake8_django::rules::receiver_decorator_checker(
|
||||
decorator_list,
|
||||
|expr| self.resolve_call_path(expr),
|
||||
));
|
||||
}
|
||||
if self.settings.rules.enabled(&Rule::AmbiguousFunctionName) {
|
||||
if let Some(diagnostic) =
|
||||
|
|
|
@ -51,25 +51,30 @@ impl Violation for ReceiverDecoratorChecker {
|
|||
pub fn receiver_decorator_checker<'a, F>(
|
||||
decorator_list: &'a [Expr],
|
||||
resolve_call_path: F,
|
||||
) -> Option<Diagnostic>
|
||||
) -> Vec<Diagnostic>
|
||||
where
|
||||
F: Fn(&'a Expr) -> Option<CallPath<'a>>,
|
||||
{
|
||||
let mut diagnostics = vec![];
|
||||
let mut seen_receiver = false;
|
||||
for (i, decorator) in decorator_list.iter().enumerate() {
|
||||
if i == 0 {
|
||||
continue;
|
||||
}
|
||||
let ExprKind::Call{ func, ..} = &decorator.node else {
|
||||
continue;
|
||||
let is_receiver = match &decorator.node {
|
||||
ExprKind::Call { func, .. } => resolve_call_path(func).map_or(false, |call_path| {
|
||||
call_path.as_slice() == ["django", "dispatch", "receiver"]
|
||||
}),
|
||||
_ => false,
|
||||
};
|
||||
if resolve_call_path(func).map_or(false, |call_path| {
|
||||
call_path.as_slice() == ["django", "dispatch", "receiver"]
|
||||
}) {
|
||||
return Some(Diagnostic::new(
|
||||
if i > 0 && is_receiver && !seen_receiver {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
ReceiverDecoratorChecker,
|
||||
Range::from_located(decorator),
|
||||
));
|
||||
}
|
||||
if !is_receiver && seen_receiver {
|
||||
seen_receiver = false;
|
||||
} else if is_receiver {
|
||||
seen_receiver = true;
|
||||
}
|
||||
}
|
||||
None
|
||||
diagnostics
|
||||
}
|
||||
|
|
|
@ -12,4 +12,14 @@ expression: diagnostics
|
|||
column: 35
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
ReceiverDecoratorChecker: ~
|
||||
location:
|
||||
row: 35
|
||||
column: 1
|
||||
end_location:
|
||||
row: 35
|
||||
column: 35
|
||||
fix: ~
|
||||
parent: ~
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue