I extended the example at https://docs.python.org/3/library/functools.html#functools.singledispatch by adding a registration for generator type
from functools import singledispatch from typing import Generator @singledispatch def fun(arg, verbose): if verbose: print("Let me just say,", end=" ") print(arg) @fun.register def _(arg: list, verbose): if verbose: print("Enumerate this:") for i, elem in enumerate(arg): print(i, elem) # NEW CODE BELOW @fun.register def _(arg: Generator, verbose): if verbose: print("Enumerate this:") for i, elem in enumerate(arg): print(i, elem) fun([3,4,5], verbose=True) fun((i for i in range(6, 10)), verbose=True)
while it works with list, it doesn’t seem to work with generator with error like
raise TypeError( TypeError: Invalid annotation for 'arg'. typing.Generator is not a class.
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
.
from types import GeneratorType @fun.register def _(arg: GeneratorType, verbose): if verbose: print("Enumerate this:") for i, elem in enumerate(arg): 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
$ python3 tmp.py Enumerate this: 0 3 1 4 2 5 Enumerate this: 0 6 1 7 2 8 3 9