[Python-Dev] Supporting functools.singledispatch with classes.

Ethan Smith ethan at ethanhs.me
Sun Dec 24 21:32:08 EST 2017


Hello all,

In https://bugs.python.org/issue32380 I was hoping to add support for
singledispatch with methods. Unfortunately, this cannot be achieved
internally without ugly attribute or stack hacks.

Therefore, I was thinking it would be nice if singledispatch supported a
keyword argument of the argument index to dispatch on, thus one can say:

class A:
    @singledispatch(arg=1)
    def method(self, a):
        return 'base'
    @method.register(int)
    def method(self, a):
        return 'int'

The other option that could work is to define a special decorator for
methods

def methodsingledispatch(func):
    """Single-dispatch generic method decorator."""
    wrapped = singledispatch(func)
    def wrapper(*args, **kw):
        return wrapped.dispatch(args[1].__class__)(*args, **kw)
    wrapper.register = wrapped.register
    update_wrapper(wrapper, func)
    return wrapper

Since this is an API change, Ivan said I should post here to get feedback.

I prefer the first design, as it is more generic and flexible.

There is also the issue of classmethod and staticmethod. Since these are
descriptors, I'm not sure they will work with singledispatch at all.

if you do

@classmethod
@singledispatch
def foo(cls, arg): ...

You lose register on foo, breaking everything. I believe this would require
changing classmethod thus is a non-starter.

If you do

@singledispatch
@classmethod
def foo(arg): ...

The wrapper in singledispatch needs to be called as the __func__ in
classmethod, but __func__ is readonly.

So at the moment, I don't think it is possible to implement singledispatch
on classmethod or staticmethod decorated functions.

I look forward to people's thoughts on these issues.

Cheers,

Ethan Smith
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20171224/669f43b0/attachment.html>


More information about the Python-Dev mailing list