Message408018
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 |
|
Date |
User |
Action |
Args |
2021-12-08 13:34:12 | evansd | set | recipients:
+ evansd |
2021-12-08 13:34:12 | evansd | set | messageid: <1638970452.65.0.012237534186.issue46014@roundup.psfhosted.org> |
2021-12-08 13:34:12 | evansd | link | issue46014 messages |
2021-12-08 13:34:12 | evansd | create | |
|