coady / multimethod

Multiple argument dispatching.
https://coady.github.io/multimethod
Other
277 stars 24 forks source link

2 bugs #47

Closed WiwilZ closed 3 years ago

WiwilZ commented 3 years ago
  1. If a method is decorated with staticmethod, classmethod or abstractmethod, the program will not execute correctly.
  2. The argument (1, 1) can not match the generic type Collection[Real], but [2, 3] and np.array([5, 5]) can. [2, '3'] can also match but np.array([5, '5']) and ['2', '3'] can't. (Real from numbers, Collection from typing )
coady commented 3 years ago

Let's split these out with examples if there are any issues here, but I'll try to address them. Thanks.

  1. {static,class}methods should work. Try using multimethod first (inner decorator).
  2. Tuples match collections now in main. I'm hesitant to call that a supported feature because tuples are typically used as heterogeneous collections with all members checked. But it does "work" now.
  3. np.array([5, '5']) and ['2', '3'] don't match because their values are strings, which don't match reals.
WiwilZ commented 3 years ago

Thank you for your reply.

adam-urbanczyk commented 3 years ago

By coincidence I was trying classmethods:

from multimethod import multimethod

class Foo:

    @classmethod
    @multimethod
    def bar(cls, x: str):

        print(x)

    @bar.register
    def bar(cls, x: int):

        print(x+1)

and I get:

AttributeError: 'classmethod' object has no attribute 'register'
> <ipython-input-14-29978b83a6fb>(11)Foo()
      9         print(x)
     10 
---> 11     @bar.register
     12     def bar(cls, x: int):

Am I doing something wrong or is this a possible bug?

coady commented 3 years ago

Wrapping it as a classmethod last works:

class Foo:
    @multimethod
    def bar(cls, x: str):
        print(x)

    @classmethod
    @bar.register
    def bar(cls, x: int):
        print(x+1)
adam-urbanczyk commented 3 years ago

Thanks!

fedorpashin commented 3 years ago

@coady I think it's better to clarify this moment in the documentation, because it's not quite obvious. I've tried these two options and none of them worked:

class Foo:
    @classmethod
    @multimethod
    def bar(cls, x: str):
        print(x)

    @classmethod
    @bar.register
    def bar(cls, x: int, y: int):
        print(x+1)
class Foo:
    @multimethod
    def bar(cls, x: str):
        print(x)

    @classmethod
    @bar.register(int, int)
    def bar(cls, x: int, y: int):
        print(x+1)