Currently, type checkers distinguish between “implemented” abstract methods and unimplemented ones using logic particular to each one. See Calling abstract methods for background.
To make this difference explicit, would it be possible to:
- add
implemented_abstractmethodfor this very rare case, and - deprecate the use of
abstractmethodfor that case.
Thus, we might have:
class X:
@abstractmethod
def f(self) -> int:
raise NotImplementedError # Should always raise this?
@implemented_abstractmethod
def g(self) -> int:
return 2 # Free to do whatever it wants.
class Y(X):
def f(self) -> int:
super().f() # Type checkers can know that this is an error
def g(self) -> int:
super().g() # Just fine.
There is a note for abstractmethod:
Note: Unlike Java abstract methods, these abstract methods may have an implementation. This implementation can be called via the
super()mechanism from the class that overrides it. This could be useful as an end-point for a super-call in a framework that uses cooperative multiple-inheritance.
This could be removed and made into the docs for implemented_abstractmethod.
This change would also resolve confusion that linters have, e.g., Useless super delegation in method when overriding abstract methods. · Issue #1594 · pylint-dev/pylint · GitHub