coady / multimethod

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

Different names for the multimethod in a class does not work with staticmethod and classmethod decorators #93

Closed pradeepkrb86 closed 1 year ago

pradeepkrb86 commented 1 year ago

As per the documentation I have wrapped the last method in my class with staticmethod decorator but since the @add.register below returns the _ (the function) the staticmethod decorates that instead of add and calling the method through an object.add is still passing the object as the first argument and the dispatch fails. Temporarily 1)using same name for all methods or 2) returning always the add after register(in multimethod in my PC) is fixing this but I dont know if this can impact other functionality (As of now no impact seen).

The actual program details are below.

Class definition: from multimethod import multimethod class Mathematics:
@multimethod
def add(a,b): print(f"Cannot add non numeric types {type(a)} and {type(b)}")
@add.register def (a: int,b: int): return f"Integer addition is {a+b}" @staticmethod @add.register def (a: float,b: float): return f"float addition is {a+b}"

Program print(type(Mathematics._)) m=Mathematics() m.add(3,4)

Issue or error below: static method decorator not applied on add and as a result calling through the object fails error

<class 'function'>

TypeError Traceback (most recent call last) File ~\Desktop\pradeep\cpython\Lib\site-packages\multimethod__init.py:325, in multimethod.call__(self, *args, *kwargs) 324 try: --> 325 return func(args, **kwargs) 326 except TypeError as ex:

TypeError: Mathematics.add() takes 2 positional arguments but 3 were given

The above exception was the direct cause of the following exception:

DispatchError Traceback (most recent call last) Cell In[342], line 3 1 print(type(Mathematics._)) 2 m=Mathematics() ----> 3 m.add(3,4)

File ~\Desktop\pradeep\cpython\Lib\site-packages\multimethod__init.py:327, in multimethod.call(self, *args, *kwargs) 325 return func(args, **kwargs) 326 except TypeError as ex: --> 327 raise DispatchError(f"Function {func.code__}") from ex

DispatchError: Function <code object add at 0x000001CE5983D8F0, file "C:\Users\Pradeep\AppData\Local\Temp\ipykernel_26460\994284117.py", line 3>

coady commented 1 year ago

2) returning always the add after register(in multimethod in my PC) is fixing this but I dont know if this can impact other functionality (As of now no impact seen).

Yes, register returns the original function to match the behavior of functools.singledispatch. Which presumably does that to support stacking multiple registers, and therefore encourages renaming to_ to not overwrite the dispatch function.

So I don't think there is any way to support this, other than one of the two workarounds in the updated documentation: