[New-bugs-announce] [issue46014] functools.singledispatch does not support Union types

Dave Evans report at bugs.python.org
Wed Dec 8 08:34:12 EST 2021


New submission from Dave Evans <dave at evans.io>:

It's not currently possible to use `singledispatch` with a function annotated with a Union type, although the desired behaviour is clear.

Example:
```
    from functools import singledispatch
    from typing import Union

    @singledispatch
    def test(arg):
        raise ValueError(arg)

    @test.register
    def _(arg: Union[int, float]):
        print(f"{arg} is a number")

    test(1)
```

This dies with:

    TypeError: Invalid annotation for 'arg'. typing.Union[int, float] is not a class.

I've implemented a workaround which digs the types out of the union and registers them one-by-one:
```
    from functools import singledispatch
    from typing import Union, get_type_hints

    def register_for_union_type(target_fn):
        def decorator(fn):
            arg_type = list(get_type_hints(fn).values())[0]
            assert arg_type.__origin__ is Union
            for type_ in arg_type.__args__:
                fn = target_fn.register(type_)(fn)
            return fn

        return decorator

    @singledispatch
    def test(arg):
        raise ValueError(arg)

    @register_for_union_type(test)
    def _(arg: Union[int, float]):
        print(f"{arg} is a number")

    test(1)

```

Looking at the source for `singledispatch` is doesn't look like it would *too* difficult to add support for something like this, though of course there may be subtleties I've missed. Would you be open to a patch?

The only other mentions I've found of this online are:
https://mail.python.org/archives/list/python-ideas@python.org/thread/HF5HDXQ2SXZHO3TWODIRQATTE4TCAWPL/
https://stackoverflow.com/questions/61721761/type-hints-and-singledispatch-how-do-i-include-union-in-an-extensible-w

----------
components: Library (Lib)
messages: 408018
nosy: evansd
priority: normal
severity: normal
status: open
title: functools.singledispatch does not support Union types
type: enhancement
versions: Python 3.10, Python 3.11, Python 3.7, Python 3.8, Python 3.9

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue46014>
_______________________________________


More information about the New-bugs-announce mailing list