Skip to content

Cannot explicitly dispatch to multipledispatch function #27

@pganssle

Description

@pganssle

While I have not explicitly added support for multipledispatch, it seems to mostly just work at the moment. However, I have noticed that explicitly dispatching (with a variant) to a multipledispatch dispatched function will fall back to dispatching by type:

import variants
from multipledispatch import dispatch
from itertools import product

@variants.primary
@dispatch(int, int)
def add(x, y):
    return x + y

@add.variant('from_lists')
@dispatch(list, list)
def add(x, y):
    return list(map(sum, product(x, y)))

# These parts work OK
print(add(1, 2))
# 3
print(add([1, 2], [3, 4]))
# [4, 5, 5, 6]
print(add.from_lists([1, 2], [3, 4]))
# [4, 5, 5, 6]

# But add.from_lists still dispatches on type!
print(add.from_lists(3, 4))
7

I'm pretty sure the reason is that the @dispatch decorator in both cases returns the same object, so calling add.from_lists is the same thing as calling add.__main_form__:

>>> add.__main_form__ is add.from_lists`
True

One way you could imagine solving this is by reversing the order of the decorators, but @dispatch apparently can't wrap a VariantFunction object (and even if it could, I don't think it would preserve all the special methods, e.g. .variant and each of the variants).

Not sure if it's possible to solve this and if it is whether the change has to happen on our side or on the multipledispatch side. On the bright side, the one thing you can do with this is have some versions of add that are automatically dispatchable by type and some that are only accessible from variants, e.g.:

import variants
from multipledispatch import dispatch
from itertools import product

@variants.primary
@dispatch(int, int)
def add(x, y):
    return x + y

@add.variant('from_lists')
@dispatch(list, list)
def add(x, y):
    return list(map(sum, product(x, y)))

@add.variant('from_iterable')
def add(iterable):
    return sum(iterable)

print(add.from_iterable([1, 2, 3]))
#6

Not sure how useful this is, but it's better than nothing.

CC @mariusvniekerk @llllllllll @mrocklin

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions