Repository navigation
fix: skip missing-super-call for abstract or protocol constructor overrides - #5474
Aayushyaash wants to merge 2 commits into
Conversation
|
This pull request has been imported. If you are a Meta employee, you can view this in D128855918. (Because this pull request was imported automatically, there will not be any future comments.) |
This comment has been minimized.
This comment has been minimized.
stroxler
left a comment
There was a problem hiding this comment.
Thanks! AI review caught an edge case plus a test it thinks could be strengthened. I think we should look at these before we merge:
Preserve the warning for __init_subclass__
Unlike constructors, __init_subclass__ executes automatically when subclasses are defined—even for abstract classes and protocols. A placeholder override can therefore break a concrete parent’s initialization chain:
registry: list[type] = []
class Registered(Protocol):
def __init_subclass__(cls) -> None:
super().__init_subclass__()
registry.append(cls)
class SubProto(Registered, Protocol):
def __init_subclass__(cls) -> None:
... # Keep missing-super-call here.
class Impl(SubProto):
passCPython registers SubProto, but not Impl. The base revision reports the useful warning on SubProto.__init_subclass__; this PR suppresses it.
Suggested fix: add field_name != &dunder::INIT_SUBCLASS to the new guard and cover this example with an expected diagnostic.
Strengthen the protocol regression test
This case already passes without the PR because the parent’s pass body triggers existing parent-side suppression. Give the parent a real implementation so the test exercises the new child-side rule.
962300a to
5840c38
Compare
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
|
Thanks for the review and pointing out the I've also updated the PR title, description and rebased cleanly onto the latest Following changes were made:
|
Summary
In an executable
.pyfile, when an abstract class or sub-protocol overrides a constructor method (__init__or__new__) to declare or refine a signature with a placeholder body (...,pass, orraise NotImplementedError), Pyrefly reported a false-positivemissing-super-callerror.While #5180 skipped
.pyistubs andif TYPE_CHECKING:blocks, overriding methods in runtime.pyfiles were still required to callsuper(), even when the overriding method itself was an abstract or protocol declaration without a runtime implementation.This PR updates
check_missing_super_call_for_field()to skip the check for__init__and__new__when the overriding method is abstract or belongs to aProtocoland its body kind isBodyKind::Ellipsis,BodyKind::Trivial, orBodyKind::RaiseNotImplementedError.Fixes #5431
Test Plan
Updated and added regression tests in
pyrefly/lib/test/class_overrides.rscovering:__init__with....__init__withpass.__init__withraise NotImplementedError.__init__with..., where the parent protocol method has a concrete implementation.missing-super-calldiagnostic when__init_subclass__is overridden with a placeholder body in aProtocolhierarchy.Validation: