In Python 3.6, I am able to use yield
inside a coroutine. However I am not able to use yield from
.
Below is my code. On line 3 I await another coroutine. On line 4 I try to yield from
a file. Why won't Python 3.6 allow me to do that?
async def read_file(self, filename):
with tempfile.NamedTemporaryFile(mode='r', delete=True, dir='/tmp', prefix='sftp') as tmp_file:
await self.copy_file(filename, tmp_file)
yield from open(tmp_file)
Here's the exception Python 3.6 raises for the above code:
File "example.py", line 4
yield from open(tmp_file)
^
SyntaxError: 'yield from' inside async function
Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise. Note: Even though the return value of an async function behaves as if it's wrapped in a Promise.resolve , they are not equivalent.
async and await are both meta keywords that allow asynchronous code to be written in a way that looks synchronous. An async function tells the compiler ahead of time that the function will be returning a Promise and will not have a value resolved right away. To use await and not block the thread async must be used.
With that design, you call the asynchronous function, passing in your callback function. The function returns immediately and calls your callback when the operation is finished. With a promise-based API, the asynchronous function starts the operation and returns a Promise object.
The error "await expression is only allowed within an async function" occurs when the await keyword is used inside of a function that was not marked as async . To solve the error and use the await keyword, mark the directly enclosing function as async .
According to PEP 525, which introduces asyncronous generators in Python 3.6:
Asynchronous
yield from
While it is theoretically possible to implement
yield from
support for asynchronous generators, it would require a serious redesign of the generators implementation.
yield from
is also less critical for asynchronous generators, since there is no need provide a mechanism of implementing another coroutines protocol on top of coroutines. And to compose asynchronous generators a simpleasync for
loop can be used:async def g1(): yield 1 yield 2 async def g2(): async for v in g1(): yield v
As you can see, the answer boils down to "it would be too hard to implement, and you don't need it anyway".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With