Skip to content

Commit 26f736b

Browse files
[pep8_naming] Avoid false positives on standard library functions with uppercase names (N802) (#18907)
Co-authored-by: Micha Reiser <micha@reiser.io>
1 parent c9f95e8 commit 26f736b

File tree

3 files changed

+88
-4
lines changed

3 files changed

+88
-4
lines changed

crates/ruff_linter/resources/test/fixtures/pep8_naming/N802.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,39 @@ def testTest(self):
4848
def BAD_FUNC():
4949
pass
5050

51+
5152
@overload
5253
def BAD_FUNC():
5354
pass
55+
56+
57+
import ast
58+
from ast import NodeTransformer
59+
60+
61+
class Visitor(ast.NodeVisitor):
62+
def visit_Constant(self, node):
63+
pass
64+
65+
def bad_Name(self):
66+
pass
67+
68+
class ExtendsVisitor(Visitor):
69+
def visit_Constant(self, node):
70+
pass
71+
72+
class Transformer(NodeTransformer):
73+
def visit_Constant(self, node):
74+
pass
75+
76+
77+
from http.server import BaseHTTPRequestHandler
78+
79+
80+
class MyRequestHandler(BaseHTTPRequestHandler):
81+
def do_GET(self):
82+
pass
83+
84+
def dont_GET(self):
85+
pass
86+

crates/ruff_linter/src/rules/pep8_naming/rules/invalid_function_name.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
use ruff_python_ast::{Decorator, Stmt};
2-
31
use ruff_macros::{ViolationMetadata, derive_message_formats};
4-
use ruff_python_ast::identifier::Identifier;
2+
use ruff_python_ast::{Decorator, Stmt, identifier::Identifier};
53
use ruff_python_semantic::SemanticModel;
6-
use ruff_python_semantic::analyze::visibility;
4+
use ruff_python_semantic::analyze::{class::any_base_class, visibility};
75
use ruff_python_stdlib::str;
86

97
use crate::Violation;
@@ -84,6 +82,41 @@ pub(crate) fn invalid_function_name(
8482
return;
8583
}
8684

85+
let parent_class = semantic
86+
.current_statement_parent()
87+
.and_then(|parent| parent.as_class_def_stmt());
88+
89+
// Ignore the visit_* methods of the ast.NodeVisitor and ast.NodeTransformer classes.
90+
if name.starts_with("visit_")
91+
&& parent_class.is_some_and(|class| {
92+
any_base_class(class, semantic, &mut |superclass| {
93+
let qualified = semantic.resolve_qualified_name(superclass);
94+
qualified.is_some_and(|name| {
95+
matches!(name.segments(), ["ast", "NodeVisitor" | "NodeTransformer"])
96+
})
97+
})
98+
})
99+
{
100+
return;
101+
}
102+
103+
// Ignore the do_* methods of the http.server.BaseHTTPRequestHandler class
104+
if name.starts_with("do_")
105+
&& parent_class.is_some_and(|class| {
106+
any_base_class(class, semantic, &mut |superclass| {
107+
let qualified = semantic.resolve_qualified_name(superclass);
108+
qualified.is_some_and(|name| {
109+
matches!(
110+
name.segments(),
111+
["http", "server", "BaseHTTPRequestHandler"]
112+
)
113+
})
114+
})
115+
})
116+
{
117+
return;
118+
}
119+
87120
checker.report_diagnostic(
88121
InvalidFunctionName {
89122
name: name.to_string(),

crates/ruff_linter/src/rules/pep8_naming/snapshots/ruff_linter__rules__pep8_naming__tests__N802_N802.py.snap

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,21 @@ N802.py:40:9: N802 Function name `testTest` should be lowercase
3737
| ^^^^^^^^ N802
3838
41 | assert True
3939
|
40+
41+
N802.py:65:9: N802 Function name `bad_Name` should be lowercase
42+
|
43+
63 | pass
44+
64 |
45+
65 | def bad_Name(self):
46+
| ^^^^^^^^ N802
47+
66 | pass
48+
|
49+
50+
N802.py:84:9: N802 Function name `dont_GET` should be lowercase
51+
|
52+
82 | pass
53+
83 |
54+
84 | def dont_GET(self):
55+
| ^^^^^^^^ N802
56+
85 | pass
57+
|

0 commit comments

Comments
 (0)