Ian Juma
Ian Juma

Reputation: 107

Why does Python3.5 have generator based co-routines?

If at all, there's no functional differences (besides syntax) between native and generator based co-routines; why does Python3 have both? I understand what a generator based co-routine is.

Was there a particular design decision or thought that made sense to have both?

Also, I'm a bit confused here; the diff between a generator and a co-routine is that I can't write into a generator; this PEP added the ability to do that. I guess there's no diff between the two in python? (I'm also assuming that writing into a co-routine and sending a value to a co-routine is the same thing)

Why does asyncio support the use of both?

Upvotes: 1

Views: 93

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121724

Before 3.5, there was no real difference between a generator and a co-routine. A generator is a co-routine purely by using yield as an expression and expecting data via send().

This sort-of changed with the new async syntax added to Python 3.5. The async syntax is both syntactic sugar (turning generators into async coroutines visually in your code) and an extension to the language to make it possible to use coroutines as context managers and iterables (async with and async for).

Quoting the PEP:

It is proposed to make coroutines a proper standalone concept in Python, and introduce new supporting syntax. The ultimate goal is to help establish a common, easily approachable, mental model of asynchronous programming in Python and make it as close to synchronous programming as possible.

Under the hood, co-routines are basically still generators and generators support most of the same functionality. Co-routines are now a distinct type however to make it possible to explicitly test for awaitable objects, see issue 24400 for the motivation (initially this was a per-instance flag, not a distinct type).

To be clear, you can still use .send() an a generator. But a generator is not awaitable, it is not expected to cooperate.

asyncio must support both because the library aims to be compatible with Python versions < 3.5 and thus can't rely on the new language constructs to be available.

Upvotes: 4

Related Questions