|
1 | 1 | use ruff_diagnostics::{Diagnostic, Violation};
|
2 | 2 | use ruff_macros::{derive_message_formats, violation};
|
3 | 3 | use ruff_python_ast::helpers::ReturnStatementVisitor;
|
| 4 | +use ruff_python_ast::identifier::Identifier; |
4 | 5 | use ruff_python_ast::visitor::Visitor;
|
5 |
| -use ruff_python_ast::Stmt; |
| 6 | +use ruff_python_ast::{self as ast}; |
| 7 | +use ruff_python_semantic::analyze::function_type::is_stub; |
6 | 8 | use ruff_python_semantic::analyze::type_inference::{NumberLike, PythonType, ResolvedPythonType};
|
7 | 9 | use ruff_text_size::Ranged;
|
8 | 10 |
|
@@ -42,21 +44,32 @@ impl Violation for InvalidBoolReturnType {
|
42 | 44 | }
|
43 | 45 |
|
44 | 46 | /// E0307
|
45 |
| -pub(crate) fn invalid_bool_return(checker: &mut Checker, name: &str, body: &[Stmt]) { |
46 |
| - if name != "__bool__" { |
| 47 | +pub(crate) fn invalid_bool_return(checker: &mut Checker, function_def: &ast::StmtFunctionDef) { |
| 48 | + if function_def.name.as_str() != "__bool__" { |
47 | 49 | return;
|
48 | 50 | }
|
49 | 51 |
|
50 | 52 | if !checker.semantic().current_scope().kind.is_class() {
|
51 | 53 | return;
|
52 | 54 | }
|
53 | 55 |
|
| 56 | + if is_stub(function_def, checker.semantic()) { |
| 57 | + return; |
| 58 | + } |
| 59 | + |
54 | 60 | let returns = {
|
55 | 61 | let mut visitor = ReturnStatementVisitor::default();
|
56 |
| - visitor.visit_body(body); |
| 62 | + visitor.visit_body(&function_def.body); |
57 | 63 | visitor.returns
|
58 | 64 | };
|
59 | 65 |
|
| 66 | + if returns.is_empty() { |
| 67 | + checker.diagnostics.push(Diagnostic::new( |
| 68 | + InvalidBoolReturnType, |
| 69 | + function_def.identifier(), |
| 70 | + )); |
| 71 | + } |
| 72 | + |
60 | 73 | for stmt in returns {
|
61 | 74 | if let Some(value) = stmt.value.as_deref() {
|
62 | 75 | if !matches!(
|
|
0 commit comments