Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Multiple dispatch – "function requires at least 1 positional argument"

In a multiple dispatch situation I don’t understand why I constantly run into an error saying: TypeError: some_func requires at least 1 positional argument.

For example, we have a following function:

from functools import singledispatch

@singledispatch
def some_func(a, b):
    ...
    
@some_func.register
def _(a: str, b: int):
    print(f'{a=}, {b=}')
    
@some_func.register
def _(a: str, b: bool):
    print(f'{b=}, {a=}')

If I try to run:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

some_func(a='a', b=10)

I get the error message:

    872 def wrapper(*args, **kw):
    873     if not args:
--> 874         raise TypeError(f'{funcname} requires at least '
    875                         '1 positional argument')
    877     return dispatch(args[0].__class__)(*args, **kw)

TypeError: some_func requires at least 1 positional argument

But it works fine if I make the first argument positional:

some_func('a', b=10)   # Out: a='a', b=10

Ok, then I’ll try making them keyword-only…

@singledispatch
def some_func(*, a, b):
    ...
    
@some_func.register
def _(*, a: str, b: int):
    print(f'{a=}, {b=}')
    
@some_func.register
def _(*, a: str, b: bool):
    print(f'{b=}, {a=}')

Now if I try to run with keyword arguments I get the same result, but with this change if I try to make the first argument as positional I get a more expected error:

----> 1 some_func('a', b=10)

File C:\Python39\lib\functools.py:877, in singledispatch..wrapper(*args, **kw)
    873 if not args:
    874     raise TypeError(f'{funcname} requires at least '
    875                     '1 positional argument')
--> 877 return dispatch(args[0].__class__)(*args, **kw)

TypeError: _() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given

So now the function simultaneously: requires a positional-only argument and takes no positional arguments.

I don’t understand why this is happening? What is the reason for needing a positional-only arguments?

>Solution :

This seems to be an open python bug – the underlying wrapper expects at least one positional argument, otherwise an error is automatically raised (see definition of wrapper).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading