If a API lets you provide subclasses of a certain class and calls your (legally) overridden methods, but also other API methods of that class with simple names like "add", accidentally overriding those methods could lead to hard-to-track-down bugs. It's better to at least warn the user.
The cases where a user wants/needs to override a method that will completely break the API is practically zero. The cases where a user accidentally overrides something that he shouldn't and needs hours to find the culprit are far more frequent. Debugging faulty behaviour caused by this can be cumbersome.
This is how I use to warn or protect attributes from being accidentally overridden:
def protect(*protected):
"""Returns a metaclass that protects all attributes given as strings"""
class Protect(type):
has_base = False
def __new__(meta, name, bases, attrs):
if meta.has_base:
for attribute in attrs:
if attribute in protected:
raise AttributeError('Overriding of attribute "%s" not allowed.'%attribute)
meta.has_base = True
klass = super().__new__(meta, name, bases, attrs)
return klass
return Protect
You can use it like this:
class Parent(metaclass=protect("do_something", "do_something_else")):
def do_something(self):
'''This is where some seriously important stuff goes on'''
pass
class Child(Parent):
def do_something(self):
'''This will raise an error during class creation.'''
pass