<div dir="ltr">Marking a method M declared in C with abstractmethod indicates that M needs to be *implemented* in any subclass D of C for D to be instantiated.<div><br></div><div>We usually think of overriding a method N to mean replacing one implementation in some class E with another in some subclass of E, F.  Often, the subclass implementation calls super to add behavior rather than replace it.</div><div><br></div><div>I think that this concept of *implementing* is different than *overriding*.</div><div><br></div><div>However, abstract classes can have reasonable definition, and should sometimes be overridden in the sense that subclasses should call super.  For example, when inheriting from AbstractContextManager, you need to *override* the abstractmethod (!) __exit__, and if you want your class to work polymorphically, you should call super.</div><div><br></div><div>This is extremely weird.  Understandably, the pylint people are confused by it (https://github.com/PyCQA/pylint/issues/1594) and raise bad warnings.</div><div><br>It also makes it impossible for me to raise warnings in my ipromise (https://github.com/NeilGirdhar/ipromise) project.  See, for example, https://github.com/NeilGirdhar/ipromise/blob/master/ipromise/test/test_overrides.py classes Y and W, which ought to raise, but that would raise on reasonable code.</div><div><br></div><div>My suggestion is to add a rarely used flag to abstractmethod:</div><div><br></div><div>class AbstractContextManager:</div><div>    @abstractmethod(overrideable=True)</div><div>    def __exit__(self, exc_type, exc_value, traceback):</div><div>        pass</div><div><br></div><div>This would set a flag on the method like __abstractmethod_overrideable__, which could be checked by ipromise's @overrides decorator, pylint's call check, and anyone else that wants to know that a method should be overridden.</div><div><br></div><div>Best,</div><div><br></div><div>Neil</div></div>