The proposal is for a new decorator @typing.override that marks a method as overriding a method in some superclass. Having this decorator - inspired by similar constructs in Java, C++, Typescript, Kotlin, Scala, Swift, and C# - will enable static type checkers to detect potential bugs where a base class method is renamed but child classes were not modified.
Just curious, but why does it list this as a disadvantage?
“Adding or removing base class methods that impact overrides will require updating subclass code.”
Isn’t being forced to update subclass code one of the benefits of the decorator?
Also, I proposed something similar in the ipromise library. I allowed for the possibility of indicating from which base class the overridden base method comes from. In some situations, that can help readers of code know where to look for the method, and it’s a bit stricter (if one base class removes, say, the __call__ method, but another one adds it–and you meant to override the one from the first base class). If you’re so inclined, feel free to include this under rejected/considered ideas.
I think the disadvantages wording should be tweaked to emphasize a verbosity tradeoff - what we had intended to point out was that (as with static types in general) this introduces another tradeoff where code becomes more verbose in order to gain some safety.
As for specifying the parent class, my initial impression is that while it could be useful (especially making the overridden class explicit to help with code navigation), it probably isn’t worth including in PEP 698 for three reasons:
if in a single commit you move a method from one base to another, you as the author are likely aware of what you did, so the safety benefits are relatively small
I’m guessing there wouldn’t be too much use of this feature. Since it’s relatively easy to implement this capability using runtime logic in a library, that makes me thing we don’t need to bake it into typing.py all of the type checkers.
But I’d like to get opinions from others as well, I just posted a link to this discussion in typing-sig so we can see if there is a range of opinions.
If the consensus is not to include that functionality, we could add it under the considered ideas.
Yes, I completely agree with your reasons, and I figured you would probably have thought of this. I was just wondering if you should mention these reasons in the PEP under “rejected alternatives”? In a few years, this extension may be posted on python-ideas, and then it might be useful for that poster to see your rejection reasoning.
That said, @typing.override could support both usage with and without the base class. But I agree that use of the base class would happen extremely rarely (only in a very complicated inheritance hierarchy). But anyway, the use of a base class could always be added later if someone makes a compelling case for it.
If the consensus is not to include that functionality, we could add it under the considered ideas.
The first versions of ”runtime” overriding decorator actually contained the class name inheritance - In Python, how do I indicate I'm overriding a method? - Stack Overflow but that really did not bring any benefits. From my point of view it only made it harder to use. Big jump was to discover a way to leave that out.
Nobody has asked for explicitly naming the class in overrides lib in the past 10 years, so I would assume it is not needed.
Sorry for asking so late. (I’ve seen PEP 702, typing.deprecated, which isn’t on Discourse yet, and thought about a question that could also apply here.)
If a third-party library provides a different override decorator, is there a good way to tell type checkers that it should act like @typing.override?
One way of handling this kind of thing is to do a typing.TYPE_CHECKING shim, like so:
# module a.py
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import override as override
else:
def override(func):
# custom implementation here
And then from everywhere else in your codebase, you could just do from a import override. Type checkers will just think that a.override is a reexport of typing.override, but at runtime you can have any custom behaviour you like.
Hi, I’m coming from C++ so I could be a bit biased.
Should be any reference or relationship with @abstractmethod? For example, it would be nice, I think, some mode/flag where the override decorator is explicitly required when overriding an @abstractmethod.
I’m not sure there is much need for special treatment of abstract methods. The PEP recommends type checkers support a strict mode where all method overrides must be marked with the decorator, whether abstract or not.