[flake8-annotations] Don't suggest NoReturn for functions raising NotImplementedError (ANN201, ANN202, ANN205, ANN206)#21311
Conversation
|
|
Could you summarize the similarities/differences from #18927? I quickly skimmed both implementations and this looks similar to the earlier PR. Has @MichaReiser's concern in #18927 (comment) been addressed? |
Changes: - Add `Terminal::RaiseNotImplemented` enum variant - Modify `Terminal::from_function()` to accept `SemanticModel` and detect `NotImplementedError` during traversal - Update `and_then()` and `branch()` combination methods to handle the new variant - Remove `only_raises_not_implemented_error()` helper function - Update `auto_return_type()` to check for `Terminal::RaiseNotImplemented` directly - Update all call sites to pass `SemanticModel` to `Terminal::from_function()`
|
I missed that, thanks for bringing it back up. I just refactored the implementation:
The way I did it in the original PR is pretty similar, minus the logic that I just implemented |
ntBre
left a comment
There was a problem hiding this comment.
Thanks, this looks reasonable to me overall. I just think we can make the SemanticModel a required argument, and we should double check all of the existing uses of Terminal::Raise to be sure they handle Terminal::RaiseNotImplemented correctly.
ntBre
left a comment
There was a problem hiding this comment.
Thank you! I had one small question about NotImplemented, but this is otherwise good to go.
this is a common error (see F901) but not a valid exception to raise, so I don't think it's something we should detect here
Summary
Fix ANN201, ANN202, ANN205, and ANN206 to not automatically suggest
NoReturn/Neverreturn type annotations for functions that raiseNotImplementedError. These rules will still flag missing return type annotations but won't provide an auto-fix, allowing developers to manually specify the actual return type that implementations should return.Fixes #18886
Problem Analysis
The bug occurred because the
auto_return_typefunction inflake8_annotations/helpers.rsdetects when all control flow paths in a function raise an exception (Terminal::Raise) and automatically suggestsNoReturn/Neveras the return type. However,NotImplementedErroris semantically different from other exceptions - it's used to indicate abstract methods that should be implemented by subclasses, not methods that truly never return.When a function raises
NotImplementedError, it's typically an abstract method pattern where:NoReturnFor example, in Django's serializer pattern:
This method should have a return type annotation like
dictorAny, notNoReturn, because implementations will return actual values.Approach
The fix modifies the
auto_return_typefunction to:Added semantic analysis capability: Modified
auto_return_typeto accept aSemanticModelparameter, enabling it to analyze exception types in raise statements.Created detection helper: Implemented
only_raises_not_implemented_error()function that:raisestatementsNotImplementedError(orNotImplemented) using semantic analysistrueonly if all raises areNotImplementedErrorModified return type inference: When
Terminal::Raiseis detected, the function now:NotImplementedErrorNone(no auto-fix suggested, but diagnostic still emitted)AutoPythonType::Neveras before (suggestingNoReturn/Never)Updated all call sites: Updated all 4 call sites in
definition.rsto passchecker.semantic():The fix ensures that:
NotImplementedErrorstill get flagged for missing return type annotationsValueError) still correctly getNoReturn/Neversuggestions