diff --git a/crates/ruff/resources/test/fixtures/flake8_return/RET504.py b/crates/ruff/resources/test/fixtures/flake8_return/RET504.py index 92bd411d8d..ea156549cd 100644 --- a/crates/ruff/resources/test/fixtures/flake8_return/RET504.py +++ b/crates/ruff/resources/test/fixtures/flake8_return/RET504.py @@ -260,3 +260,23 @@ def nonlocal_assignment(): nonlocal X X = 1 return X + + +def decorator() -> Flask: + app = Flask(__name__) + + @app.route('/hello') + def hello() -> str: + """Hello endpoint.""" + return 'Hello, World!' + + return app + + +def default(): + y = 1 + + def f(x = y) -> X: + return x + + return y diff --git a/crates/ruff/src/rules/flake8_return/visitor.rs b/crates/ruff/src/rules/flake8_return/visitor.rs index d8be89bdb6..9750730901 100644 --- a/crates/ruff/src/rules/flake8_return/visitor.rs +++ b/crates/ruff/src/rules/flake8_return/visitor.rs @@ -66,8 +66,26 @@ impl<'a> Visitor<'a> for ReturnVisitor<'a> { .non_locals .extend(names.iter().map(String::as_str)); } - StmtKind::FunctionDef { .. } | StmtKind::AsyncFunctionDef { .. } => { - // Don't recurse. + StmtKind::FunctionDef { + decorator_list, + args, + returns, + .. + } + | StmtKind::AsyncFunctionDef { + decorator_list, + args, + returns, + .. + } => { + // Don't recurse into the body, but visit the decorators, etc. + for expr in decorator_list { + visitor::walk_expr(self, expr); + } + if let Some(returns) = returns { + visitor::walk_expr(self, returns); + } + visitor::walk_arguments(self, args); } StmtKind::Return { value } => { self.stack