mirror of https://github.com/astral-sh/ruff
[`pyupgrade`] Keyword arguments in `super` should suppress the `UP008` fix (#19131)
## Summary Fixes #19096
This commit is contained in:
parent
beb98dae7c
commit
221edcba5c
|
|
@ -125,3 +125,19 @@ class ClassForCommentEnthusiasts(BaseClass):
|
||||||
self
|
self
|
||||||
# also a comment
|
# also a comment
|
||||||
).f()
|
).f()
|
||||||
|
|
||||||
|
|
||||||
|
# Issue #19096: super calls with keyword arguments should emit diagnostic but not be fixed
|
||||||
|
class Ord(int):
|
||||||
|
def __len__(self):
|
||||||
|
return super(Ord, self, uhoh=True, **{"error": True}).bit_length()
|
||||||
|
|
||||||
|
class ExampleWithKeywords:
|
||||||
|
def method1(self):
|
||||||
|
super(ExampleWithKeywords, self, invalid=True).some_method() # Should emit diagnostic but NOT be fixed
|
||||||
|
|
||||||
|
def method2(self):
|
||||||
|
super(ExampleWithKeywords, self, **{"kwarg": "value"}).some_method() # Should emit diagnostic but NOT be fixed
|
||||||
|
|
||||||
|
def method3(self):
|
||||||
|
super(ExampleWithKeywords, self).some_method() # Should be fixed - no keywords
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use ruff_text_size::{Ranged, TextSize};
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
use crate::preview::is_safe_super_call_with_parameters_fix_enabled;
|
use crate::preview::is_safe_super_call_with_parameters_fix_enabled;
|
||||||
use crate::{AlwaysFixableViolation, Edit, Fix};
|
use crate::{Edit, Fix, FixAvailability, Violation};
|
||||||
|
|
||||||
/// ## What it does
|
/// ## What it does
|
||||||
/// Checks for `super` calls that pass redundant arguments.
|
/// Checks for `super` calls that pass redundant arguments.
|
||||||
|
|
@ -57,14 +57,16 @@ use crate::{AlwaysFixableViolation, Edit, Fix};
|
||||||
#[derive(ViolationMetadata)]
|
#[derive(ViolationMetadata)]
|
||||||
pub(crate) struct SuperCallWithParameters;
|
pub(crate) struct SuperCallWithParameters;
|
||||||
|
|
||||||
impl AlwaysFixableViolation for SuperCallWithParameters {
|
impl Violation for SuperCallWithParameters {
|
||||||
|
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
|
||||||
|
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
"Use `super()` instead of `super(__class__, self)`".to_string()
|
"Use `super()` instead of `super(__class__, self)`".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fix_title(&self) -> String {
|
fn fix_title(&self) -> Option<String> {
|
||||||
"Remove `super()` parameters".to_string()
|
Some("Remove `super()` parameters".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,6 +167,10 @@ pub(crate) fn super_call_with_parameters(checker: &Checker, call: &ast::ExprCall
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut diagnostic = checker.report_diagnostic(SuperCallWithParameters, call.arguments.range());
|
||||||
|
|
||||||
|
// Only provide a fix if there are no keyword arguments, since super() doesn't accept keyword arguments
|
||||||
|
if call.arguments.keywords.is_empty() {
|
||||||
let applicability = if !checker.comment_ranges().intersects(call.arguments.range())
|
let applicability = if !checker.comment_ranges().intersects(call.arguments.range())
|
||||||
&& is_safe_super_call_with_parameters_fix_enabled(checker.settings())
|
&& is_safe_super_call_with_parameters_fix_enabled(checker.settings())
|
||||||
{
|
{
|
||||||
|
|
@ -173,7 +179,6 @@ pub(crate) fn super_call_with_parameters(checker: &Checker, call: &ast::ExprCall
|
||||||
Applicability::Unsafe
|
Applicability::Unsafe
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut diagnostic = checker.report_diagnostic(SuperCallWithParameters, call.arguments.range());
|
|
||||||
diagnostic.set_fix(Fix::applicable_edit(
|
diagnostic.set_fix(Fix::applicable_edit(
|
||||||
Edit::deletion(
|
Edit::deletion(
|
||||||
call.arguments.start() + TextSize::new(1),
|
call.arguments.start() + TextSize::new(1),
|
||||||
|
|
@ -182,6 +187,7 @@ pub(crate) fn super_call_with_parameters(checker: &Checker, call: &ast::ExprCall
|
||||||
applicability,
|
applicability,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if a call is an argumented `super` invocation.
|
/// Returns `true` if a call is an argumented `super` invocation.
|
||||||
fn is_super_call_with_arguments(call: &ast::ExprCall, checker: &Checker) -> bool {
|
fn is_super_call_with_arguments(call: &ast::ExprCall, checker: &Checker) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -249,3 +249,53 @@ UP008.py:123:14: UP008 [*] Use `super()` instead of `super(__class__, self)`
|
||||||
126 |- # also a comment
|
126 |- # also a comment
|
||||||
127 |- ).f()
|
127 |- ).f()
|
||||||
123 |+ super().f()
|
123 |+ super().f()
|
||||||
|
128 124 |
|
||||||
|
129 125 |
|
||||||
|
130 126 | # Issue #19096: super calls with keyword arguments should emit diagnostic but not be fixed
|
||||||
|
|
||||||
|
UP008.py:133:21: UP008 Use `super()` instead of `super(__class__, self)`
|
||||||
|
|
|
||||||
|
131 | class Ord(int):
|
||||||
|
132 | def __len__(self):
|
||||||
|
133 | return super(Ord, self, uhoh=True, **{"error": True}).bit_length()
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP008
|
||||||
|
134 |
|
||||||
|
135 | class ExampleWithKeywords:
|
||||||
|
|
|
||||||
|
= help: Remove `super()` parameters
|
||||||
|
|
||||||
|
UP008.py:137:14: UP008 Use `super()` instead of `super(__class__, self)`
|
||||||
|
|
|
||||||
|
135 | class ExampleWithKeywords:
|
||||||
|
136 | def method1(self):
|
||||||
|
137 | super(ExampleWithKeywords, self, invalid=True).some_method() # Should emit diagnostic but NOT be fixed
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP008
|
||||||
|
138 |
|
||||||
|
139 | def method2(self):
|
||||||
|
|
|
||||||
|
= help: Remove `super()` parameters
|
||||||
|
|
||||||
|
UP008.py:140:14: UP008 Use `super()` instead of `super(__class__, self)`
|
||||||
|
|
|
||||||
|
139 | def method2(self):
|
||||||
|
140 | super(ExampleWithKeywords, self, **{"kwarg": "value"}).some_method() # Should emit diagnostic but NOT be fixed
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP008
|
||||||
|
141 |
|
||||||
|
142 | def method3(self):
|
||||||
|
|
|
||||||
|
= help: Remove `super()` parameters
|
||||||
|
|
||||||
|
UP008.py:143:14: UP008 [*] Use `super()` instead of `super(__class__, self)`
|
||||||
|
|
|
||||||
|
142 | def method3(self):
|
||||||
|
143 | super(ExampleWithKeywords, self).some_method() # Should be fixed - no keywords
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP008
|
||||||
|
|
|
||||||
|
= help: Remove `super()` parameters
|
||||||
|
|
||||||
|
ℹ Unsafe fix
|
||||||
|
140 140 | super(ExampleWithKeywords, self, **{"kwarg": "value"}).some_method() # Should emit diagnostic but NOT be fixed
|
||||||
|
141 141 |
|
||||||
|
142 142 | def method3(self):
|
||||||
|
143 |- super(ExampleWithKeywords, self).some_method() # Should be fixed - no keywords
|
||||||
|
143 |+ super().some_method() # Should be fixed - no keywords
|
||||||
|
|
|
||||||
|
|
@ -249,3 +249,53 @@ UP008.py:123:14: UP008 [*] Use `super()` instead of `super(__class__, self)`
|
||||||
126 |- # also a comment
|
126 |- # also a comment
|
||||||
127 |- ).f()
|
127 |- ).f()
|
||||||
123 |+ super().f()
|
123 |+ super().f()
|
||||||
|
128 124 |
|
||||||
|
129 125 |
|
||||||
|
130 126 | # Issue #19096: super calls with keyword arguments should emit diagnostic but not be fixed
|
||||||
|
|
||||||
|
UP008.py:133:21: UP008 Use `super()` instead of `super(__class__, self)`
|
||||||
|
|
|
||||||
|
131 | class Ord(int):
|
||||||
|
132 | def __len__(self):
|
||||||
|
133 | return super(Ord, self, uhoh=True, **{"error": True}).bit_length()
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP008
|
||||||
|
134 |
|
||||||
|
135 | class ExampleWithKeywords:
|
||||||
|
|
|
||||||
|
= help: Remove `super()` parameters
|
||||||
|
|
||||||
|
UP008.py:137:14: UP008 Use `super()` instead of `super(__class__, self)`
|
||||||
|
|
|
||||||
|
135 | class ExampleWithKeywords:
|
||||||
|
136 | def method1(self):
|
||||||
|
137 | super(ExampleWithKeywords, self, invalid=True).some_method() # Should emit diagnostic but NOT be fixed
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP008
|
||||||
|
138 |
|
||||||
|
139 | def method2(self):
|
||||||
|
|
|
||||||
|
= help: Remove `super()` parameters
|
||||||
|
|
||||||
|
UP008.py:140:14: UP008 Use `super()` instead of `super(__class__, self)`
|
||||||
|
|
|
||||||
|
139 | def method2(self):
|
||||||
|
140 | super(ExampleWithKeywords, self, **{"kwarg": "value"}).some_method() # Should emit diagnostic but NOT be fixed
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP008
|
||||||
|
141 |
|
||||||
|
142 | def method3(self):
|
||||||
|
|
|
||||||
|
= help: Remove `super()` parameters
|
||||||
|
|
||||||
|
UP008.py:143:14: UP008 [*] Use `super()` instead of `super(__class__, self)`
|
||||||
|
|
|
||||||
|
142 | def method3(self):
|
||||||
|
143 | super(ExampleWithKeywords, self).some_method() # Should be fixed - no keywords
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP008
|
||||||
|
|
|
||||||
|
= help: Remove `super()` parameters
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
140 140 | super(ExampleWithKeywords, self, **{"kwarg": "value"}).some_method() # Should emit diagnostic but NOT be fixed
|
||||||
|
141 141 |
|
||||||
|
142 142 | def method3(self):
|
||||||
|
143 |- super(ExampleWithKeywords, self).some_method() # Should be fixed - no keywords
|
||||||
|
143 |+ super().some_method() # Should be fixed - no keywords
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue