coady / multimethod

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

@multimethod cannot access function from base class #22

Closed hzhangxyz closed 3 years ago

hzhangxyz commented 3 years ago
from multimethod import multimethod
class A:
    @multimethod
    def p(self, v: int):
        print("i")
class B(A):
    @multimethod
    def p(self, v: float):
        print("f")
B().p(233)

Currently @multimethod in derived class cannot access function defined in base class

A easy thought is directly add a copy in derived class like this:

from multimethod import multimethod
class A:
    @multimethod
    def p(self, v: int):
        print("i")
class B(A):
    p = A.p
    @multimethod
    def p(self, v: float):
        print("f")
B().p(233)

now the code work, but it also change A.p's behavior since I can now call A().p(2.333)

so is there any easy copy function for multimethod.multimethod?

hzhangxyz commented 3 years ago

It seems i can solve it by add a p |= A.p after define derived class function, it is great, but it is more clear if I can explicitly declare using base class function before all derived class function definition.

coady commented 3 years ago

multimethod does a namespace lookup, but you can always register explicitly.

class B(A):
    @A.p.register
    def p(self, v: float):
        print("f")

That does modify A.p as in your example, in that it's the same multimethod. I suppose multimethods could support a copy operation, though I think defining them in classes is confusing for these kinds of reasons.

coady commented 3 years ago

I'm not sure about this use case, but since multimethods already have an inherited copy method, it might as well work correctly.

mnieber commented 1 year ago

FIrst of all, thanks for creating this package, it's really useful.

Fortunately, the solution of @A.p.register already solves my use-case, but I wondered if a more general solution is possible by annotating the class with something like @register_base(A). This would have the effect that any multimethod in A is registered as a multimethod in B.