mirror of https://github.com/astral-sh/ruff
Run dunder method rule on methods directly (#9815)
This stood out in the flamegraph and I realized it requires us to traverse over all statements in the class (unnecessarily).
This commit is contained in:
parent
5c99967c4d
commit
ad0121660e
|
|
@ -1,13 +1,15 @@
|
|||
use ruff_python_ast::str::raw_contents_range;
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
use ruff_python_semantic::{BindingKind, ContextualizedDefinition, Export};
|
||||
use ruff_python_semantic::{
|
||||
BindingKind, ContextualizedDefinition, Definition, Export, Member, MemberKind,
|
||||
};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::codes::Rule;
|
||||
use crate::docstrings::Docstring;
|
||||
use crate::fs::relativize_path;
|
||||
use crate::rules::{flake8_annotations, flake8_pyi, pydocstyle};
|
||||
use crate::rules::{flake8_annotations, flake8_pyi, pydocstyle, pylint};
|
||||
use crate::{docstrings, warn_user};
|
||||
|
||||
/// Run lint rules over all [`Definition`] nodes in the [`SemanticModel`].
|
||||
|
|
@ -31,6 +33,7 @@ pub(crate) fn definitions(checker: &mut Checker) {
|
|||
]);
|
||||
let enforce_stubs = checker.source_type.is_stub() && checker.enabled(Rule::DocstringInStub);
|
||||
let enforce_stubs_and_runtime = checker.enabled(Rule::IterMethodReturnIterable);
|
||||
let enforce_dunder_method = checker.enabled(Rule::BadDunderMethodName);
|
||||
let enforce_docstrings = checker.any_enabled(&[
|
||||
Rule::BlankLineAfterLastSection,
|
||||
Rule::BlankLineAfterSummary,
|
||||
|
|
@ -80,7 +83,12 @@ pub(crate) fn definitions(checker: &mut Checker) {
|
|||
Rule::UndocumentedPublicPackage,
|
||||
]);
|
||||
|
||||
if !enforce_annotations && !enforce_docstrings && !enforce_stubs && !enforce_stubs_and_runtime {
|
||||
if !enforce_annotations
|
||||
&& !enforce_docstrings
|
||||
&& !enforce_stubs
|
||||
&& !enforce_stubs_and_runtime
|
||||
&& !enforce_dunder_method
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -147,6 +155,19 @@ pub(crate) fn definitions(checker: &mut Checker) {
|
|||
}
|
||||
}
|
||||
|
||||
// pylint
|
||||
if enforce_dunder_method {
|
||||
if checker.enabled(Rule::BadDunderMethodName) {
|
||||
if let Definition::Member(Member {
|
||||
kind: MemberKind::Method(method),
|
||||
..
|
||||
}) = definition
|
||||
{
|
||||
pylint::rules::bad_dunder_method_name(checker, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// pydocstyle
|
||||
if enforce_docstrings {
|
||||
if pydocstyle::helpers::should_ignore_definition(
|
||||
|
|
|
|||
|
|
@ -513,9 +513,6 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
|||
if checker.enabled(Rule::SingleStringSlots) {
|
||||
pylint::rules::single_string_slots(checker, class_def);
|
||||
}
|
||||
if checker.enabled(Rule::BadDunderMethodName) {
|
||||
pylint::rules::bad_dunder_method_name(checker, body);
|
||||
}
|
||||
if checker.enabled(Rule::MetaClassABCMeta) {
|
||||
refurb::rules::metaclass_abcmeta(checker, class_def);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::identifier::Identifier;
|
||||
use ruff_python_ast::Stmt;
|
||||
use ruff_python_semantic::analyze::visibility;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
|
@ -56,11 +56,13 @@ impl Violation for BadDunderMethodName {
|
|||
}
|
||||
|
||||
/// PLW3201
|
||||
pub(crate) fn bad_dunder_method_name(checker: &mut Checker, class_body: &[Stmt]) {
|
||||
for method in class_body
|
||||
.iter()
|
||||
.filter_map(ruff_python_ast::Stmt::as_function_def_stmt)
|
||||
.filter(|method| {
|
||||
pub(crate) fn bad_dunder_method_name(checker: &mut Checker, method: &ast::StmtFunctionDef) {
|
||||
// If the name isn't a dunder, skip it.
|
||||
if !method.name.starts_with('_') || !method.name.ends_with('_') {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the name is explicitly allowed, skip it.
|
||||
if is_known_dunder_method(&method.name)
|
||||
|| checker
|
||||
.settings
|
||||
|
|
@ -69,14 +71,13 @@ pub(crate) fn bad_dunder_method_name(checker: &mut Checker, class_body: &[Stmt])
|
|||
.contains(method.name.as_str())
|
||||
|| matches!(method.name.as_str(), "_")
|
||||
{
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
method.name.starts_with('_') && method.name.ends_with('_')
|
||||
})
|
||||
{
|
||||
|
||||
if visibility::is_override(&method.decorator_list, checker.semantic()) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
BadDunderMethodName {
|
||||
name: method.name.to_string(),
|
||||
|
|
@ -84,4 +85,3 @@ pub(crate) fn bad_dunder_method_name(checker: &mut Checker, class_body: &[Stmt])
|
|||
method.identifier(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue