I have a generator that does not use send() values. Should I type its send_value as Any or None?
import typing as t
def pi_generator() -> t.Generator[int, ???, None]:
pi = "3141592"
for digit in pi:
yield int(digit)
pi_gen = pi_generator()
next(pi_gen) # 3
pi_gen.send('foo') # 1
pi_gen.send(pi_gen) # 4
Reasons I see for Any:
- The generator works perfectly fine with
send()for any type, so if somebody had a reason to use.send(1)with this generator, it’s totally fine. - Methods’ arguments’ types should be general, and
.send(x: Any)is more general than.send(x: None).
Reasons I see for None:
- Return types should be specific, and "Generator that never uses send" is a more specific type than "Any kind of generator".
- If someone is using
.send()to this generator, it’s likely they’re misunderstanding what it does and the type hint should inform them.
>Solution :
Quoting the docs for typing.Generator:
If your generator will only yield values, set the
SendTypeandReturnTypetoNone:def infinite_stream(start: int) -> Generator[int, None, None]: while True: yield start start += 1
Setting SendType to None is the correct way to communicate that the generator does not expect callees to send() values.