[Python-Dev] ABCs and MRO

Paul Moore p.f.moore at gmail.com
Mon Mar 2 18:01:10 CET 2009


2009/3/2 P.J. Eby <pje at telecommunity.com>:
> By the way guys, are you aware of:
>
>  http://pypi.python.org/pypi/simplegeneric

Yes. It has been mentioned, and I am certainly aware of both it and
RuleDispatch.

> There might be a bit of name confusion by exposing pkgutils' internal
> simplegeneric there.  Perhaps it should be called "trivialgeneric", as it's
> even tinier than simplegeneric.  ;-)

:-)

The problem is that any discussion of more than the bare minimum
functionality regularly results in people's heads exploding. Most
specifically, Guido usually ends up hating the whole idea when it gets
too complex. I'd rather stick with the most basic (and frankly,
useful) aspects and avoid the headaches and messy explosions :-)

> This isn't really a new problem; if you base your generic function methods
> off of interfaces implemented by a type or instance, you have the same basic
> issues.
[...]

See? You just made my head hurt :-)

> Personally, I'd like to see some way to subscribe to changes in ABC
> registration, so that generic functions or other tools can update their
> caches.  With that feature, you might even be able to implement full ABC
> support for simplegeneric, by treating ABC registrations as equivalent to
> mass registration of the ABC's registrants.

But the issue is that the __subclasshook__ method allows things to be
virtual subclasses of an ABC without either being a real subclass,
*or* being explicitly registered. There simply is no way to answer the
question "which ABCs does this class implement" and get such ABCs
reported in the answer.

Consider:

class MyABC:
    __metaclass__ = ABCMeta
    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyABC:
            if any("foo" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

class C(object):
    def foo(self):
        pass

c = C()

Here, isinstance(c, MyABC) is True. But if f is a generic function
with a registered implementation for MyABC, the only way I can see of
ensuring that f(c) calls that implementation, would be to test
isinstance(c, ImlCls) for all ImplCls for which there is a registered
implementation. There'd need to be a cache of results of some form, to
avoid a serious performance penalty, and it's not entirely obvious
what the definition of "best fit" would be.

That may be what you just said. :-)

But regardless, this is getting beyond what I'd describe as "simple",
and certainly is beyond any remit of tweaking pkgutil.simplegeneric to
make it public.

So either pkgutil.simplegeneric is useful with current (ignoring ABC)
semantics, or it isn't suitable for exposure. If the latter, someone
will have to propose a more complete implementation for the stdlib,
which is something that traditionally is doomed to failure :-(

So I don't intend to extend the functionality of
pkgutil.simplegeneric, and I await a decision on whether or not the
patch as it stands can go in. If the decision is that the current
implementation isn't powerful enough to be of any use, I'd suggest
that you propose your simplegeneric implementation for the stdlib
(enhancing it to handle the ABC issue, if it doesn't already). Or we
continue managing without generic functions in the stdlib, and the
pprint rewrite which started all this off, goes ahead with an adhoc
approach to extensibility.

Paul.


More information about the Python-Dev mailing list