mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 14:21:24 +00:00
[pylint
] Omit stubs from invalid-bool
and invalid-str-return-type
(#11008)
## Summary Reflecting some improvements that were made in https://github.com/astral-sh/ruff/pull/10959.
This commit is contained in:
parent
9f01ac3f87
commit
4d8890eef5
5 changed files with 65 additions and 34 deletions
|
@ -1,36 +1,49 @@
|
||||||
# These testcases should raise errors
|
# These testcases should raise errors
|
||||||
|
|
||||||
|
|
||||||
class Float:
|
class Float:
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 3.05
|
return 3.05
|
||||||
|
|
||||||
|
|
||||||
class Int:
|
class Int:
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
class Int2:
|
class Int2:
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
class Bool:
|
class Bool:
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
# TODO: Once Ruff has better type checking
|
# TODO: Once Ruff has better type checking
|
||||||
def return_int():
|
def return_int():
|
||||||
return 3
|
return 3
|
||||||
|
|
||||||
|
|
||||||
class ComplexReturn:
|
class ComplexReturn:
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return return_int()
|
return return_int()
|
||||||
|
|
||||||
|
|
||||||
# These testcases should NOT raise errors
|
# These testcases should NOT raise errors
|
||||||
|
|
||||||
|
|
||||||
class Str:
|
class Str:
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "ruff"
|
return "ruff"
|
||||||
|
|
||||||
|
|
||||||
class Str2:
|
class Str2:
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
x = "ruff"
|
x = "ruff"
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
class Str3:
|
||||||
|
def __str__(self): ...
|
||||||
|
|
|
@ -95,7 +95,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::InvalidBoolReturnType) {
|
if checker.enabled(Rule::InvalidBoolReturnType) {
|
||||||
pylint::rules::invalid_bool_return(checker, name, body);
|
pylint::rules::invalid_bool_return(checker, function_def);
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::InvalidLengthReturnType) {
|
if checker.enabled(Rule::InvalidLengthReturnType) {
|
||||||
pylint::rules::invalid_length_return(checker, function_def);
|
pylint::rules::invalid_length_return(checker, function_def);
|
||||||
|
@ -104,7 +104,7 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) {
|
||||||
pylint::rules::invalid_bytes_return(checker, function_def);
|
pylint::rules::invalid_bytes_return(checker, function_def);
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::InvalidStrReturnType) {
|
if checker.enabled(Rule::InvalidStrReturnType) {
|
||||||
pylint::rules::invalid_str_return(checker, name, body);
|
pylint::rules::invalid_str_return(checker, function_def);
|
||||||
}
|
}
|
||||||
if checker.enabled(Rule::InvalidFunctionName) {
|
if checker.enabled(Rule::InvalidFunctionName) {
|
||||||
if let Some(diagnostic) = pep8_naming::rules::invalid_function_name(
|
if let Some(diagnostic) = pep8_naming::rules::invalid_function_name(
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::helpers::ReturnStatementVisitor;
|
use ruff_python_ast::helpers::ReturnStatementVisitor;
|
||||||
|
use ruff_python_ast::identifier::Identifier;
|
||||||
use ruff_python_ast::visitor::Visitor;
|
use ruff_python_ast::visitor::Visitor;
|
||||||
use ruff_python_ast::Stmt;
|
use ruff_python_ast::{self as ast};
|
||||||
|
use ruff_python_semantic::analyze::function_type::is_stub;
|
||||||
use ruff_python_semantic::analyze::type_inference::{NumberLike, PythonType, ResolvedPythonType};
|
use ruff_python_semantic::analyze::type_inference::{NumberLike, PythonType, ResolvedPythonType};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
|
@ -42,8 +44,8 @@ impl Violation for InvalidBoolReturnType {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// E0307
|
/// E0307
|
||||||
pub(crate) fn invalid_bool_return(checker: &mut Checker, name: &str, body: &[Stmt]) {
|
pub(crate) fn invalid_bool_return(checker: &mut Checker, function_def: &ast::StmtFunctionDef) {
|
||||||
if name != "__bool__" {
|
if function_def.name.as_str() != "__bool__" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,12 +53,23 @@ pub(crate) fn invalid_bool_return(checker: &mut Checker, name: &str, body: &[Stm
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if is_stub(function_def, checker.semantic()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let returns = {
|
let returns = {
|
||||||
let mut visitor = ReturnStatementVisitor::default();
|
let mut visitor = ReturnStatementVisitor::default();
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(&function_def.body);
|
||||||
visitor.returns
|
visitor.returns
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if returns.is_empty() {
|
||||||
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
|
InvalidBoolReturnType,
|
||||||
|
function_def.identifier(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
for stmt in returns {
|
for stmt in returns {
|
||||||
if let Some(value) = stmt.value.as_deref() {
|
if let Some(value) = stmt.value.as_deref() {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::helpers::ReturnStatementVisitor;
|
use ruff_python_ast::helpers::ReturnStatementVisitor;
|
||||||
|
use ruff_python_ast::identifier::Identifier;
|
||||||
use ruff_python_ast::visitor::Visitor;
|
use ruff_python_ast::visitor::Visitor;
|
||||||
use ruff_python_ast::Stmt;
|
use ruff_python_ast::{self as ast};
|
||||||
|
use ruff_python_semantic::analyze::function_type::is_stub;
|
||||||
use ruff_python_semantic::analyze::type_inference::{PythonType, ResolvedPythonType};
|
use ruff_python_semantic::analyze::type_inference::{PythonType, ResolvedPythonType};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
|
@ -42,8 +44,8 @@ impl Violation for InvalidStrReturnType {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// E0307
|
/// E0307
|
||||||
pub(crate) fn invalid_str_return(checker: &mut Checker, name: &str, body: &[Stmt]) {
|
pub(crate) fn invalid_str_return(checker: &mut Checker, function_def: &ast::StmtFunctionDef) {
|
||||||
if name != "__str__" {
|
if function_def.name.as_str() != "__str__" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,12 +53,23 @@ pub(crate) fn invalid_str_return(checker: &mut Checker, name: &str, body: &[Stmt
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if is_stub(function_def, checker.semantic()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let returns = {
|
let returns = {
|
||||||
let mut visitor = ReturnStatementVisitor::default();
|
let mut visitor = ReturnStatementVisitor::default();
|
||||||
visitor.visit_body(body);
|
visitor.visit_body(&function_def.body);
|
||||||
visitor.returns
|
visitor.returns
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if returns.is_empty() {
|
||||||
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
|
InvalidStrReturnType,
|
||||||
|
function_def.identifier(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
for stmt in returns {
|
for stmt in returns {
|
||||||
if let Some(value) = stmt.value.as_deref() {
|
if let Some(value) = stmt.value.as_deref() {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
|
|
|
@ -1,42 +1,34 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
source: crates/ruff_linter/src/rules/pylint/mod.rs
|
||||||
---
|
---
|
||||||
invalid_return_type_str.py:5:16: PLE0307 `__str__` does not return `str`
|
invalid_return_type_str.py:6:16: PLE0307 `__str__` does not return `str`
|
||||||
|
|
|
|
||||||
3 | class Float:
|
4 | class Float:
|
||||||
4 | def __str__(self):
|
5 | def __str__(self):
|
||||||
5 | return 3.05
|
6 | return 3.05
|
||||||
| ^^^^ PLE0307
|
| ^^^^ PLE0307
|
||||||
6 |
|
|
||||||
7 | class Int:
|
|
||||||
|
|
|
|
||||||
|
|
||||||
invalid_return_type_str.py:9:16: PLE0307 `__str__` does not return `str`
|
invalid_return_type_str.py:11:16: PLE0307 `__str__` does not return `str`
|
||||||
|
|
|
|
||||||
7 | class Int:
|
9 | class Int:
|
||||||
8 | def __str__(self):
|
10 | def __str__(self):
|
||||||
9 | return 1
|
11 | return 1
|
||||||
| ^ PLE0307
|
| ^ PLE0307
|
||||||
10 |
|
|
||||||
11 | class Int2:
|
|
||||||
|
|
|
|
||||||
|
|
||||||
invalid_return_type_str.py:13:16: PLE0307 `__str__` does not return `str`
|
invalid_return_type_str.py:16:16: PLE0307 `__str__` does not return `str`
|
||||||
|
|
|
|
||||||
11 | class Int2:
|
14 | class Int2:
|
||||||
12 | def __str__(self):
|
15 | def __str__(self):
|
||||||
13 | return 0
|
16 | return 0
|
||||||
| ^ PLE0307
|
| ^ PLE0307
|
||||||
14 |
|
|
||||||
15 | class Bool:
|
|
||||||
|
|
|
|
||||||
|
|
||||||
invalid_return_type_str.py:17:16: PLE0307 `__str__` does not return `str`
|
invalid_return_type_str.py:21:16: PLE0307 `__str__` does not return `str`
|
||||||
|
|
|
|
||||||
15 | class Bool:
|
19 | class Bool:
|
||||||
16 | def __str__(self):
|
20 | def __str__(self):
|
||||||
17 | return False
|
21 | return False
|
||||||
| ^^^^^ PLE0307
|
| ^^^^^ PLE0307
|
||||||
18 |
|
|
||||||
19 | # TODO: Once Ruff has better type checking
|
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue