New submission from Dutcho <dut...@ziggo.nl>:

>From Python 3.7, `functools.singledispatch` makes the `register()` attribute 
>of the generic function infer the type of the first argument automatically for 
>functions annotated with types. That's great for DRY.
However, in 3.7 and 3.8, no check is made that the *first* parameter of the 
registered function is actually annotated; *any* annotation suffices, even the 
*return* one.

Example:
    ```
    >>> @functools.singledispatch
    ... def func(arg):...
    >>> @func.register
    ... def _int(arg) -> int:...
    >>> @func.register
    ... def _str(arg) -> str:...
```
No errors happen, although the return type, *not* `arg`, is annotated.
This results in:
    ```
    >>> func.registry
    mappingproxy({<class 'object'>: <function func>, <class 'int'>: <function 
_int>, <class 'str'>: <function _str>})

    ```
Obviously, that doesn't dispatch correctly.

Note that un-annotated functions *are* caught:
    ```
    >>> @func.register
    ... def _no_annotation(arg): ...
    Traceback (most recent call last):
    ...
    TypeError: Invalid first argument to `register()`: <function _no_annotation 
at 0x000001D769A43D30>. Use either `@register(some_class)` or plain `@register` 
on an annotated function.
    ```

----------
components: Library (Lib)
messages: 367824
nosy: Dutcho
priority: normal
severity: normal
status: open
title: functools.singledispatch doesn't verify annotation is on FIRST parameter
type: behavior
versions: Python 3.7

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue40464>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to