You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Provide guidance on PEP 698's strict enforcement feature of typing.override #1376
PEP 698 (typing.override) suggests that type-checkers provide a strict enforcement option that would mark method overrides. However, no guidance is provided about the methods __init__ and __new__. These methods are always implicit overrides (from object method). These method do not obey LSP (so their signature doesn't depend on any superclass), which means that override decoration only verifies that you haven't misspelled the method. Should they be exempt from this strict check?
(I'm not convinced one way or the other, but it would be nice to have some guidance on this.)
CC'ing @erictraut because we had a brief discussion about this.
In C, A.f overrides B.f (often by mistake). Should this implicit override be reported in strict mode?
Normally, if A and B both implement the same method (not just in the sense of same signature, but in the sense of behavior), then both A and B should inherit from an interface that defines that method:
I would very much favor that __new__ and __init__ be treated as special cases and exempt from strict @override checks - most type checkers (or at least Pyre) do not require compatibility of signatures for constructors, unlike on other methods.
I don't have as much of an opinion about multiple inheritance; that's a messy problem that I haven't thought too much about.
In many cases preexisting conventions (which vary a bit per type checker) about method signature type compatibility might detect the problem - for example if A.f and B.f had different signatures (they are the same here) then at least some type checkers would probably complain about C.f not satisfying the signature of B.f because of incompatible types for A.f, which comes first in method resolution.
That said, I'm not sure Pyre would catch this with compatibility checks- I suspect that we only verify compatibility on actual definitions in C, not on collisions produced through multiple inheritance.
Regardless, the idea certainly has merit.
One potential reason not to do that would be that normal strict-override-errors should be trivial to autofix by injecting an @override decorator, whereas the one on C is far from trivial - you have to control at least one of A and B and have the ability to refactor the whole class hierarchy.
We probably wouldn't include this in Pyre for that reason, since we need to be able to auto-apply @override to millions of lines of existing code.
I'm fine exempting __init__ and __new__. In my current implement of PEP 698, I didn't do this (for the reasons I noted here), but I will make that change.
As for the multiple inheritance example, I don't think that falls under the purview of PEP 698. Any class in Python can, in theory, be used as a base class for multiple inheritance. It would be unreasonable and inappropriate to expect that an author of a class anticipate the need to mark their methods with an @override descriptor to handle the (unlikely) case that it is overridden (obscured) by another "peer" class. See this issue for more details.
Activity
AlexWaygood commentedon Mar 22, 2023
Cc. @stroxler
NeilGirdhar commentedon Mar 22, 2023
On the same topic, consider this bad code
In
C,A.foverridesB.f(often by mistake). Should this implicit override be reported in strict mode?Normally, if
AandBboth implement the same method (not just in the sense of same signature, but in the sense of behavior), then bothAandBshould inherit from an interface that defines that method:stroxler commentedon Mar 31, 2023
I would very much favor that
__new__and__init__be treated as special cases and exempt from strict@overridechecks - most type checkers (or at least Pyre) do not require compatibility of signatures for constructors, unlike on other methods.stroxler commentedon Mar 31, 2023
I don't have as much of an opinion about multiple inheritance; that's a messy problem that I haven't thought too much about.
In many cases preexisting conventions (which vary a bit per type checker) about method signature type compatibility might detect the problem - for example if
A.fandB.fhad different signatures (they are the same here) then at least some type checkers would probably complain aboutC.fnot satisfying the signature ofB.fbecause of incompatible types forA.f, which comes first in method resolution.That said, I'm not sure Pyre would catch this with compatibility checks- I suspect that we only verify compatibility on actual definitions in
C, not on collisions produced through multiple inheritance.Regardless, the idea certainly has merit.
One potential reason not to do that would be that normal strict-override-errors should be trivial to autofix by injecting an
@overridedecorator, whereas the one onCis far from trivial - you have to control at least one ofAandBand have the ability to refactor the whole class hierarchy.We probably wouldn't include this in Pyre for that reason, since we need to be able to auto-apply
@overrideto millions of lines of existing code.erictraut commentedon Mar 31, 2023
I'm fine exempting
__init__and__new__. In my current implement of PEP 698, I didn't do this (for the reasons I noted here), but I will make that change.As for the multiple inheritance example, I don't think that falls under the purview of PEP 698. Any class in Python can, in theory, be used as a base class for multiple inheritance. It would be unreasonable and inappropriate to expect that an author of a class anticipate the need to mark their methods with an
@overridedescriptor to handle the (unlikely) case that it is overridden (obscured) by another "peer" class. See this issue for more details.