Skip to content

Commit

Permalink
Tweak example
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jan 2, 2024
1 parent 797b9ba commit 515d055
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
class Soup:
class Animal:
@staticmethod
def temp() -> None:
print("Soup is hot!")
def speak():
return f"This animal says something."


class TomatoSoup(Soup):
class BadDog(Animal):
@staticmethod
def temp() -> None:
super.temp() # PLW0245
print("But tomato soup is even hotter!")
def speak():
original_speak = super.speak() # PLW0245
return f"{original_speak} But as a dog, it barks!"

class ProperTomatoSoup(Soup):

class GoodDog(Animal):
@staticmethod
def temp() -> None:
super().temp() # OK
print("But tomato soup is even hotter!")
def speak():
original_speak = super().speak() # OK
return f"{original_speak} But as a dog, it barks!"


class SuperSoup(Soup):
class FineDog(Animal):
@staticmethod
def temp() -> None:
# override the super builtin
def speak():
super = "super"
super.temp() # OK (according to this rule, at least)
print(f"But super soup is {super}!")
original_speak = super.speak() # OK
return f"{original_speak} But as a dog, it barks!"


def super_without_class() -> None:
super.blah() # OK


super.blah() # OK
91 changes: 45 additions & 46 deletions crates/ruff_linter/src/rules/pylint/rules/super_without_brackets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,43 @@ use crate::checkers::ast::Checker;
/// Checks for `super` calls without parentheses.
///
/// ## Why is this bad?
/// When `super` is used without parentheses, it is not an actual call.
/// When `super` is used without parentheses, it is not an actual call, and
/// thus has no effect.
///
/// ## Example
/// ```python
/// class Soup:
/// class Animal:
/// @staticmethod
/// def temp():
/// print("Soup is hot!")
/// def speak():
/// return "This animal says something."
///
///
/// class TomatoSoup(Soup):
/// class Dog(Animal):
/// @staticmethod
/// def temp():
/// super.temp() # [super-without-brackets]
/// print("But tomato soup is even hotter!")
/// def speak():
/// original_speak = super.speak()
/// return f"{original_speak} But as a dog, it barks!"
/// ```
///
/// Use instead:
/// ```python
/// class Soup:
/// class Animal:
/// @staticmethod
/// def temp():
/// print("Soup is hot!")
///
/// def speak():
/// return "This animal says something."
///
/// class TomatoSoup(Soup):
/// class Dog(Animal):
/// @staticmethod
/// def temp():
/// super().temp()
/// print("But tomato soup is even hotter!")
/// def speak():
/// original_speak = super().speak()
/// return f"{original_speak} But as a dog, it barks!"
/// ```
#[violation]
pub struct SuperWithoutBrackets;

impl AlwaysFixableViolation for SuperWithoutBrackets {
#[derive_message_formats]
fn message(&self) -> String {
format!("`super` call without parentheses")
format!("`super` call is missing parentheses")
}

fn fix_title(&self) -> String {
Expand All @@ -58,49 +57,49 @@ impl AlwaysFixableViolation for SuperWithoutBrackets {

/// PLW0245
pub(crate) fn super_without_brackets(checker: &mut Checker, func: &Expr) {
let ScopeKind::Function(ast::StmtFunctionDef {
name,
decorator_list,
..
}) = checker.semantic().current_scope().kind
else {
// The call must be to `super` (without parentheses).
let Expr::Attribute(ast::ExprAttribute { value, .. }) = func else {
return;
};

let Some(parent) = &checker
.semantic()
.first_non_type_parent_scope(checker.semantic().current_scope())
else {
let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() else {
return;
};

match function_type::classify(
name,
decorator_list,
parent,
checker.semantic(),
&checker.settings.pep8_naming.classmethod_decorators,
&checker.settings.pep8_naming.staticmethod_decorators,
) {
function_type::FunctionType::Method { .. }
| function_type::FunctionType::ClassMethod { .. }
| function_type::FunctionType::StaticMethod { .. } => {}
function_type::FunctionType::Function { .. } => return,
if id.as_str() != "super" {
return;
}

let Expr::Attribute(ast::ExprAttribute { value, .. }) = func else {
if !checker.semantic().is_builtin(id.as_str()) {
return;
};
}

let Expr::Name(ast::ExprName { id, .. }) = value.as_ref() else {
let scope = checker.semantic().current_scope();

// The current scope _must_ be a function.
let ScopeKind::Function(function_def) = scope.kind else {
return;
};

if id.as_str() != "super" {
let Some(parent) = &checker.semantic().first_non_type_parent_scope(scope) else {
return;
}
};

if !checker.semantic().is_builtin(id.as_str()) {
// The function must be a method, class method, or static method.
let classification = function_type::classify(
&function_def.name,
&function_def.decorator_list,
parent,
checker.semantic(),
&checker.settings.pep8_naming.classmethod_decorators,
&checker.settings.pep8_naming.staticmethod_decorators,
);
if !matches!(
classification,
function_type::FunctionType::Method { .. }
| function_type::FunctionType::ClassMethod { .. }
| function_type::FunctionType::StaticMethod { .. }
) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
---
source: crates/ruff_linter/src/rules/pylint/mod.rs
---
super_without_brackets.py:10:9: PLW0245 [*] `super` call without parentheses
super_without_brackets.py:10:26: PLW0245 [*] `super` call is missing parentheses
|
8 | @staticmethod
9 | def temp() -> None:
10 | super.temp() # PLW0245
| ^^^^^ PLW0245
11 | print("But tomato soup is even hotter!")
9 | def speak():
10 | original_speak = super.speak() # PLW0245
| ^^^^^ PLW0245
11 | return f"{original_speak} But as a dog, it barks!"
|
= help: Add parentheses to `super` call

Safe fix
7 7 | class TomatoSoup(Soup):
7 7 | class BadDog(Animal):
8 8 | @staticmethod
9 9 | def temp() -> None:
10 |- super.temp() # PLW0245
10 |+ super().temp() # PLW0245
11 11 | print("But tomato soup is even hotter!")
9 9 | def speak():
10 |- original_speak = super.speak() # PLW0245
10 |+ original_speak = super().speak() # PLW0245
11 11 | return f"{original_speak} But as a dog, it barks!"
12 12 |
13 13 | class ProperTomatoSoup(Soup):
13 13 |


0 comments on commit 515d055

Please sign in to comment.