gpt4 book ai didi

interop - 如何在 Twisted 的 asyncioreactor 之上运行 asyncio 库代码?

转载 作者:行者123 更新时间:2023-12-01 11:21:25 34 4
gpt4 key购买 nike

我已经成功导入/安装了 Twisted 的 asyncioreactor并执行一个简单的异步函数:

from twisted.internet import asyncioreactor
asyncioreactor.install()
from twisted.internet import task
from twisted.internet.defer import inlineCallbacks
from twisted.internet.defer import ensureDeferred

async def sleepy(reactor):
print("SLEEPING")
await task.deferLater(reactor, 3.0, lambda: None)
print("done sleep")
return 42

@task.react
def main(reactor):
d = ensureDeferred(sleepy(reactor))
d.addCallback(print)
return d

我想在上述代码中混合一个异步库,例如 asyncio.sleep .我尝试了以下方法:
from twisted.internet import asyncioreactor
asyncioreactor.install()
from twisted.internet import task
from twisted.internet.defer import inlineCallbacks
from twisted.internet.defer import ensureDeferred

import asyncio

async def sleepy(reactor):
print("SLEEPING")
await asyncio.sleep(3)
print("done sleep")
return 42

@task.react
def main(reactor):
d = ensureDeferred(sleepy(reactor))
d.addCallback(print)
return d

这会产生以下错误:
 $ python test.py
SLEEPING
main function encountered error
Traceback (most recent call last):
File "test.py", line 16, in <module>
@task.react
File "/Users/blz/.pyenv/versions/3.6.0/lib/python3.6/site-packages/twisted/internet/task.py", line 908, in react
finished = main(_reactor, *argv)
File "test.py", line 18, in main
d = ensureDeferred(sleepy(reactor))
File "/Users/blz/.pyenv/versions/3.6.0/lib/python3.6/site-packages/twisted/internet/defer.py", line 823, in ensureDeferred
return _inlineCallbacks(None, coro, Deferred())
--- <exception caught here> ---
File "/Users/blz/.pyenv/versions/3.6.0/lib/python3.6/site-packages/twisted/internet/defer.py", line 1301, in _inlineCallbacks
result = g.send(result)
File "test.py", line 11, in sleepy
await asyncio.sleep(3)
File "/Users/blz/.pyenv/versions/3.6.0/lib/python3.6/asyncio/tasks.py", line 476, in sleep
return (yield from future)
builtins.AssertionError: yield from wasn't used with future

很公平,我想,所以我尝试交换 await asyncio.sleep(3)await ensureDeferred(asyncio.sleep(3))await asyncio.ensure_future(asyncio.sleep(3)) ,但我得到完全相同的错误。

如何安排 aio 协程(和/或 Future)在与 asyncioreactor 使用的相同事件循环上运行?

最佳答案

哇,你遇到了一个有趣的角落案例!
通过使用 asyncio.sleep() 你触发了一些有趣的行为。

我想你可能已经发现了一个错误
Twisted 与 Python 3 asyncioreactor 和 async/await 的集成。
您可能希望在 Twisted 邮件列表上跟进 Twisted 开发人员。

我不是 100% 确定,但这是我的想法。

asyncio.sleep() 的实现与 Python 3 紧密耦合
异步实现。它使用 asyncio.Future(类似于 Twisted 的 deferred),并使用 get_event_loop()(类似于 Twisted 的 reactor)。

asyncio.sleep 是这样实现的:

@coroutine
def sleep(delay, result=None, *, loop=None):
"""Coroutine that completes after a given time (in seconds)."""
if delay == 0:
yield
return result

if loop is None:
loop = events.get_event_loop()
future = loop.create_future()
h = future._loop.call_later(delay,
futures._set_result_unless_cancelled,
future, result)
try:
return (yield from future)
finally:
h.cancel()

我稍微更改了您的代码示例以通过 Twisted 的
asyncioreactor 事件循环进入 asyncio.sleep():
from twisted.internet import asyncioreactor
asyncioreactor.install()
from twisted.internet import reactor
from twisted.internet import task
from twisted.internet.defer import inlineCallbacks
from twisted.internet.defer import ensureDeferred

import asyncio

async def sleepy(reactor):
print("SLEEPING")
await asyncio.sleep(3, loop=reactor._asyncioEventloop)
print("done sleep")
return 42

@task.react
def main(reactor):
d = ensureDeferred(sleepy(reactor))
d.addCallback(print)
return d

我还是和你一样的错误: builtins.AssertionError: yield from not used with future

堆栈跟踪如下所示:
main function encountered error
Traceback (most recent call last):
File "b.py", line 16, in <module>
@task.react
File "/Users/crodrigues/twisted8/src/twisted/internet/task.py", line 908, in react
finished = main(_reactor, *argv)
File "b.py", line 19, in main
d = ensureDeferred(sleepy(reactor))
File "/Users/crodrigues/twisted8/src/twisted/internet/defer.py", line 823, in ensureDeferred
return _inlineCallbacks(None, coro, Deferred())
--- <exception caught here> ---
File "/Users/crodrigues/twisted8/src/twisted/internet/defer.py", line 1301, in _inlineCallbacks
result = g.send(result)
File "b.py", line 12, in sleepy
await asyncio.sleep(3, loop=reactor._asyncioEventloop)
File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/tasks.py", line 478, in sleep
return (yield from future)
builtins.AssertionError: yield from wasn't used with future

我认为 asyncio.sleep() 是一个应该运行到完成的协程
在 asyncio 循环上,但这不会发生在这里,因此断言。

我认为问题是由 引入的结果 = g.send(result) .
我不确定你能不能 发送()到这样的协程,并期望它能够工作。

我建议您在 Twisted 邮件列表上询问以获得更详细的反馈。

关于interop - 如何在 Twisted 的 asyncioreactor 之上运行 asyncio 库代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42317477/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com