Coroutines are extremely powerful constructs that are often confused with generators. Many authors inappropriately describe coroutines as generators with a bit of extra syntax. This is an easy mistake to make, as, way back in Python 2.5, when coroutines were introduced, they were presented as we added a send method to the generator syntax. The difference is actually a lot more nuanced and will make more sense after you've seen a few examples.
Coroutines are pretty hard to understand. Outside the asyncio module, which we'll cover in the chapter on concurrency, they are not used all that often in the wild. You can definitely skip this section and happily develop in Python for years without ever encountering coroutines. There are a couple of libraries that use coroutines extensively (mostly for concurrent or asynchronous programming), but they are normally written...