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:
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?
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).