This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: functools.singledispatchfunction has confusing error message if no positional arguments are passed in
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: AlexWaygood, ammar2, lukasz.langa, markgrandi, mental, rhettinger
Priority: normal Keywords: patch

Created on 2020-06-26 03:29 by markgrandi, last changed 2022-04-11 14:59 by admin.

Pull Requests
URL Status Linked Edit
PR 21471 open ammar2, 2020-07-14 07:16
PR 23212 closed mental, 2020-11-10 04:32
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
2022-04-11 14:59:32adminsetgithub: 85294
2021-11-05 16:40:42AlexWaygoodsetnosy: + rhettinger, lukasz.langa, AlexWaygood

versions: + Python 3.9, Python 3.10, Python 3.11, - Python 3.8
2020-11-10 04:32:06mentalsetnosy: + mental
pull_requests: + pull_request22111
2020-07-14 07:16:29ammar2setkeywords: + patch
nosy: + ammar2

pull_requests: + pull_request20615
stage: patch review
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