validating a class against an ABC at definition time

Eric Snow ericsnowcurrently at gmail.com
Fri May 20 01:33:12 EDT 2011


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.

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).

Taking cues from abc.py and pyobject.c, here is a stab at a class decorator
that validates a class against another.

def validate(abc):
    if not isinstance(abc, type):
        raise TypeError("Can only validate against classes")
    def decorator(cls):
        if not __debug__:
            return cls
        if not isinstance(cls, type):
            raise TypeError("Can only validate classes")
        abstracts = set()
        for name in getattr(abc, "__abstractmethods__", set()):
            value = getattr(cls, name, None)
            if not value:
                abstracts.add(name)
            elif getattr(value, "__isabstractmethod__", False):
                abstracts.add(name)
        if abstracts:
            sorted_methods = sorted(abstracts)
            joined = ", ".join(sorted_methods)
            msg = "Class {} does not implement abstract methods {} of class
{}"
            raise TypeError(msg.format(cls.__name__, joined, abc.__name__))
        return cls
    return decorator

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.

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.

Does anyone know a better way to do ABC validation at definition time?

Thanks.

-eric
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20110519/392c2794/attachment.html>


More information about the Python-list mailing list