I want to raise an exception if a user has mistyped an abstract class attribute name and a new class attribute is added instead of overriding one:

class FooAbstract:
    default_value = 'spam'  # This could be overriden

class MyFoo(FooAbstract):
    defualt_value = 'bar'  # A user mistyped the name and he should be notified

I guess difflib.SequenceMatcher could be used for validating newly added variable names:

from difflib import SequenceMatcher

orig_names = set([a for a in dir(FooAbstract) if not a.startswith('__')])
new_names = set(dir(MyFoo)) - set(dir(FooAbstract))

for orig_name in orig_names:
    for new_name in new_names:
        if 0.9 < SequenceMatcher(a=orig_name, b=new_name).ratio() < 1:
            message = f'You probably misstyped "{new_name}" (use "{orig_name}" instead)'
            raise AttributeError(message)

My question is where should I put this condition in order to execute it during loading of the subclass MyFoo?

1 Answers

1
VPfB On Best Solutions

Class FooAbstract should define __init_subclass__. This init subclas hook is the best place for tests like yours. It is as documented as a tool for class creation customization.

This method is called whenever the containing class is subclassed. cls is then the new subclass.