Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot explicitly dispatch to multipledispatch function #27

Open
pganssle opened this issue Mar 11, 2018 · 0 comments
Open

Cannot explicitly dispatch to multipledispatch function #27

pganssle opened this issue Mar 11, 2018 · 0 comments

Comments

@pganssle
Copy link
Member

pganssle commented Mar 11, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant