<div>Thinking about class APIs and validating a class against an API.  The abc module provides the tools to do some of this.  One thing I realized, that I hadn't noticed before, is that the abstractness of a class is measured when instances of the class are created.  This happens in object.__new__ (pyobject.c).  Validating thus when a class is defined would not be as helpful, since there is no guarantee that the class is not meant to be abstract as well.</div>
<div><br></div><div>However, I have found that it is sometimes nice to validate a class at definition time.  This is particularly true for a class that does not inherit from the abstract base class (but registers instead).</div>
<div><br></div><div>Taking cues from abc.py and pyobject.c, here is a stab at a class decorator that validates a class against another.</div><div><br></div><div>def validate(abc):</div><div>    if not isinstance(abc, type):</div>
<div>        raise TypeError("Can only validate against classes")</div><div>    def decorator(cls):</div><div>        if not __debug__:</div><div>            return cls</div><div>        if not isinstance(cls, type):</div>
<div>            raise TypeError("Can only validate classes")</div><div>        abstracts = set()</div><div>        for name in getattr(abc, "__abstractmethods__", set()):</div><div>            value = getattr(cls, name, None)</div>
<div>            if not value:</div><div>                abstracts.add(name)</div><div>            elif getattr(value, "__isabstractmethod__", False):</div><div>                abstracts.add(name)</div><div>        if abstracts:</div>
<div>            sorted_methods = sorted(abstracts)</div><div>            joined = ", ".join(sorted_methods)</div><div><div>            msg = "Class {} does not implement abstract methods {} of class {}"</div>
</div><div><div>            raise TypeError(msg.format(cls.__name__, joined, abc.__name__))</div></div><div>        return cls</div><div>    return decorator</div><div><br></div><div>Stack this with the ABCMeta.register method and you can ensure that your class is compliant with the ABC at the time you register it on that ABC.</div>
<div><br></div><div>Does anyone find this irrelevant or superfluous?  I know that it would be a good idea to stay on top of your class's implementation of an ABC's abstract methods.  However, this seems like a good way of doing that programmatically.</div>
<div><br></div><div>Does anyone know a better way to do ABC validation at definition time?</div><div><br></div><div>Thanks.</div><div><br></div><div>-eric</div><div><br></div><div><br></div><div><br></div><div><br></div>