4

I'm overloading functions with default parameter using multipledispatch (based on this answer)

from multipledispatch import dispatch

class TestExampleTest(AbstractTest):
    @dispatch(ClassOne, bool, bool)
    def function(self, my_class, a=True, b=True):
        do_something()

    @dispatch(ClassTwo, bool)
    def function(self, my_class, a=True):
        do_something_else()

When I'm calling a function() without passing values to the bool item/s

self.function(ClassOne())

I get

NotImplementedError: Could not find signature for function

Complete stack trace:

ExampleTest.py:27 (TestExampleTest.test_example_test)
self = <ExampleTest.TestExampleTest object at 0x04326BB0>

    def test_example_test(self):
>       self.function(ClassOne())

ExampleTest.py:29: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <dispatched function>
args = (<ExampleTest.ClassOne object at 0x043262B0>,), kwargs = {}
types = (<class 'ExampleTest.ClassOne'>,), func = None

    def __call__(self, *args, **kwargs):
        types = tuple([type(arg) for arg in args])
        func = self.dispatch(*types)
        if not func:
            raise NotImplementedError('Could not find signature for %s: <%s>' %
>                                     (self.name, str_signature(types)))
E           NotImplementedError: Could not find signature for function: <ClassOne>

..\..\..\..\Automation\lib\site-packages\multipledispatch\dispatcher.py:434: NotImplementedError

Note: I know I can drop @dispatch all together and do something like

def function(self, my_class_one=None, my_class_two=None, a=True, b=True):
    if my_class_one:
        do_something()
    elif my_class_two:
        do_something_else()

But I'm wondering if I can keep the current structure.

How can I fix it?

Guy
  • 46,488
  • 10
  • 44
  • 88

2 Answers2

2

The default parameter should be declared as keyword parameter in @dispatch, then remember passing the keywords instead of relying postion if you want to modify the parameter value which has default value when you call these functions.

from multipledispatch import dispatch

class TestExampleTest(AbstractTest):
    @dispatch(ClassOne, a=bool, b=bool)
    def function(self, my_class, a=True, b=True):  # 1st function
        do_something()

    @dispatch(ClassTwo, a=bool)
    def function(self, my_class, a=True):          # 2nd function
        do_something_else()


test_ins = TestExampleTest()

# call 1st function
test_ins.function(class_one_ins) 
test_ins.function(class_one_ins, a=False)
test_ins.function(class_one_ins, a=False, b=False)

# call 2nd function
test_ins.function(class_two_ins)
test_ins.function(class_two_ins, a=False)

QooBee
  • 21
  • 5
-1
from multipledispatch import dispatch

# FOR hi(a: int, b: int = 3)

@dispatch(int, int)
def _hi(a: int, b: int):
    print(a, b)


@dispatch(int, int)
def hi(a: int, b: int = 3):
    _hi(a, b)


@dispatch(int, b=int)
def hi(a: int, *, b: int = 3):
    _hi(a, b)


# FOR hi(a: str, b: int = 3)
@dispatch(str, int)
def _hi(a: str, b: int):
    print(a, b, 'str!')


@dispatch(str, int)
def hi(a: str, b: int = 3):
    _hi(a, b)


@dispatch(str, b=int)
def hi(a: str, *, b: int = 3):
    _hi(a, b)

hi(2)
hi(2, 3)
hi(2, b=3)
hi('2')
hi('2', 3)
hi('2', b=3)

Output

2 3
2 3
2 3
2 3 str!
2 3 str!
2 3 str!
  • 1
    Thanks for demonstrating some uncommented code. What does this post have to do with the OP? How exactly does this answer the title question? Large chunks of code without context are rarely useful. – Daniil Fajnberg Aug 31 '22 at 11:17