I extended the example at https://docs.python.org/3/library/functools.html#functools.singledispatch by adding a registration for generator type
JavaScript
x
28
28
1
from functools import singledispatch
2
from typing import Generator
3
4
@singledispatch
5
def fun(arg, verbose):
6
if verbose:
7
print("Let me just say,", end=" ")
8
print(arg)
9
10
@fun.register
11
def _(arg: list, verbose):
12
if verbose:
13
print("Enumerate this:")
14
for i, elem in enumerate(arg):
15
print(i, elem)
16
17
# NEW CODE BELOW
18
19
@fun.register
20
def _(arg: Generator, verbose):
21
if verbose:
22
print("Enumerate this:")
23
for i, elem in enumerate(arg):
24
print(i, elem)
25
26
fun([3,4,5], verbose=True)
27
fun((i for i in range(6, 10)), verbose=True)
28
while it works with list, it doesn’t seem to work with generator with error like
JavaScript
1
3
1
raise TypeError(
2
TypeError: Invalid annotation for 'arg'. typing.Generator is not a class.
3
Is it expected that singledispatch
does not work with generator?
Advertisement
Answer
typing.Generator
is a type hint, not a type. You need types.GeneratorType
.
JavaScript
1
8
1
from types import GeneratorType
2
3
@fun.register
4
def _(arg: GeneratorType, verbose):
5
if verbose:
6
print("Enumerate this:")
7
for i, elem in enumerate(arg):
8
print(i, elem)
Objects are not considered instances of type hints according to isinstance
, which is what singledispatch
uses to decide which function to use for a given argument. With this change, you’ll get the expected output
JavaScript
1
11
11
1
$ python3 tmp.py
2
Enumerate this:
3
0 3
4
1 4
5
2 5
6
Enumerate this:
7
0 6
8
1 7
9
2 8
10
3 9
11