classification
Title: functools.singledispatchfunction has confusing error message if no positional arguments are passed in
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: markgrandi
Priority: normal Keywords:

Created on 2020-06-26 03:29 by markgrandi, last changed 2020-06-26 03:32 by markgrandi.

Messages (1)
msg372406 - (view) Author: Mark Grandi (markgrandi) * Date: 2020-06-26 03:29
this is with python 3.8:

```plaintext
PS C:\Users\mark> py -3 --version --version
Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 23:03:10) [MSC v.1916 64 bit (AMD64)]
```

So when using functools.singledispatch or functools.singledispatchmethod, you need to provide at least 1 positional argument so it can dispatch based on the type of said argument

however, with `functools.singledispatchmethod`, you get an error message that is confusing and not obvious what the problem is.

Example with `functools.singledispatchmethod`: 

```
class NegatorTwo:
    @singledispatchmethod
    def neg(arg):
        raise NotImplementedError("Cannot negate a")

    @neg.register
    def _(self, arg: int):
        return -arg

    @neg.register
    def _test(self, arg: bool):
        return not arg


if __name__ == "__main__":

    n = NegatorTwo()
    print(n.neg(0))
    print(n.neg(False))
    print(n.neg(arg=0))

```

you end up getting: 

```plaintext
PS C:\Users\mark> py -3 C:\Users\mark\Temp\singledisp.py
0
True
Traceback (most recent call last):
  File "C:\Users\mark\Temp\singledisp.py", line 58, in <module>
    print(n.neg(arg=0))
  File "C:\Python38\lib\functools.py", line 910, in _method
    method = self.dispatcher.dispatch(args[0].__class__)
IndexError: tuple index out of range

```


but with just regular `functools.singledispatch`:


```plaintext

@functools.singledispatch
def negate_func(arg):
    raise NotImplementedError("can't negate")

@negate_func.register
def negate_int_func(arg:int):
    return -arg

@negate_func.register
def negate_bool_func(arg:bool):
    return not arg


if __name__ == "__main__":


    print(negate_func(0))
    print(negate_func(False))
    print(negate_func(arg=0))

```

you get an error that tells you what actually is wrong:

```plaintext

PS C:\Users\mark> py -3 C:\Users\mark\Temp\singledisp.py
0
True
Traceback (most recent call last):
  File "C:\Users\mark\Temp\singledisp.py", line 63, in <module>
    print(negate_func(arg=0))
  File "C:\Python38\lib\functools.py", line 871, in wrapper
    raise TypeError(f'{funcname} requires at least '
TypeError: negate_func requires at least 1 positional argument

```

it seems that the code in `functools.singledispatchmethod` needs to check to see if `args` is empty, and throw a similar (if not the same) exception as `functools.singledispatch`
History
Date User Action Args
2020-06-26 03:32:46markgrandisettitle: functools.singledispatchfunction has confusing error message if no position arguments are passed in -> functools.singledispatchfunction has confusing error message if no positional arguments are passed in
2020-06-26 03:29:31markgrandicreate