[flake8-return] Exempt cached properties and other property-like decorators from explicit return rule (RET501)#12563
Conversation
CodSpeed Performance ReportMerging #12563 will not alter performanceComparing Summary
|
|
MichaReiser
left a comment
There was a problem hiding this comment.
LGTM. Thank you. I let @AlexWaygood merge to get the blessing of someone who actually understands Python ;)
20b13fd to
d5fb0cb
Compare
AlexWaygood
left a comment
There was a problem hiding this comment.
LGTM. I added support for other stdlib property-like decorators as well, such as @abc.abstractproperty, @enum.property, and @types.DynamicClassAttribute. I think the same rationale applies for special-casing these decorators as it does for special-casing @functools.cached_property.
crates/ruff_linter/resources/test/fixtures/flake8_return/RET501.py
Outdated
Show resolved
Hide resolved
| /// hardcoding these is a little hacky. | ||
| fn is_property_like_decorator(decorator: &Decorator, semantic: &SemanticModel) -> bool { | ||
| semantic | ||
| .resolve_qualified_name(&decorator.expression) |
There was a problem hiding this comment.
@epenet -- you had semantic.resolve_qualified_name(map_callable(&decorator.expression)) here. I think using map_callable would be incorrect in this instance. map_callable() is a convenience function for when we don't care whether e.g. a function is decorated with @functools.lru_cache or @functools.lru_cache() (whether the decorator is a call-expression or not is irrelevant). But for all of these property-like decorators, you can only use them as @property; it's invalid to use them as @property(). So for these decorators, we just want to call resolve_qualified_name directly on the expression, instead of passing it through map_callable first.
There was a problem hiding this comment.
I copied it from elsewhere in the code base.
I wonder if this applies there as well...
And would it make sense to move this function to a shared location?
There was a problem hiding this comment.
I copied it from elsewhere in the code base.
I wonder if this applies there as well...
It's hard to say in general. For a lot of decorators (like @lru_cache), you really don't care about whether it's been decorated with @lru_cache or @lru_cache(). So while there may be other places in the codebase where it's being used incorrectly, I'm pretty confident they're not all incorrect ;-)
And would it make sense to move this function to a shared location?
Possibly...
There was a problem hiding this comment.
Good that you asked. It seems we already have a general-purpose function for this:
ruff/crates/ruff_python_semantic/src/analyze/visibility.rs
Lines 63 to 83 in aaa56eb
We should just use that for now. I'll apply some fixes to it in a followup PR.
There was a problem hiding this comment.
For reference, I wonder if it might make sense to look at rules/pydoclint/rules/check_docstring.rs also:
ruff/crates/ruff_linter/src/rules/pydoclint/rules/check_docstring.rs
Lines 442 to 461 in 459c85b
flake8-return] Exempt cached properties from explicit return rule (RET501)flake8-return] Exempt cached properties and other property-like decorators from explicit return rule (RET501)
Summary
Follow-up to #12243, in which regular properties were exempted but not cached properties.
Still linked to home-assistant/core#115031
Test Plan