bilibili-api icon indicating copy to clipboard operation
bilibili-api copied to clipboard

sync函数近期更改,该如何调用?

Open TZFC opened this issue 11 months ago • 7 comments

Python 版本: 3.11.10

模块版本: 可用版本:16.1.1 报错版本:16.3.0

运行环境: Linux


我在16.1.1版本时可以这么使用sync:

sync(asyncio.gather(*[some_coroutine(), some_other_coroutine(), 
                        refresh_credentials_loop(credential_dict=credential_dict, database=mydb)
                        ))

更新到16.3.0之后会报错sync 22行: no running event loop

看起来16.1.1与16.3.0之间sync进行了比较大的改变。请问现在该如何正确使用呢?

TZFC avatar Dec 01 '24 04:12 TZFC

我改的。当时没有测试linux环境。这个应该是sync函数的bug。能看一下具体的报错信息吗?能不能把完整的报错信息截图发出来

LondonClass avatar Dec 24 '24 08:12 LondonClass

if __name__ == "__main__":
    sync(asyncio.gather(*[roomInfos[room_id]['live_danmaku'].connect() for room_id in ROOM_IDS],
                        refresh_credentials_loop(credential_dict=credential_dict, database=mydb)
                        ))

其中roomInfos[room_id]['live_danmaku'] 是一个LiveDanmaku类

TZFC avatar Dec 27 '24 02:12 TZFC

报错信息为:

Traceback (most recent call last):
  File "/home/ubuntu/BiliLiveManager/test/lib/python3.11/site-packages/bilibili_api/utils/sync.py", line 22, in sync
    asyncio.get_running_loop()
RuntimeError: no running event loop

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ubuntu/BiliLiveManager/master.py", line 168, in <module>
    sync(asyncio.gather(*[roomInfos[room_id]['live_danmaku'].connect() for room_id in ROOM_IDS],
  File "/home/ubuntu/BiliLiveManager/test/lib/python3.11/site-packages/bilibili_api/utils/sync.py", line 24, in sync
    return asyncio.run(coroutine)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/runners.py", line 89, in run
    raise ValueError("a coroutine was expected, got {!r}".format(coro))
ValueError: a coroutine was expected, got <_GatheringFuture pending>
sys:1: RuntimeWarning: coroutine 'refresh_credentials_loop' was never awaited
sys:1: RuntimeWarning: coroutine 'LiveDanmaku.connect' was never awaited

使用改之前的sync()版本就不会报错

TZFC avatar Dec 27 '24 02:12 TZFC

不是很懂为什么会这样。理论上这行代码引发错误会被捕获。 你可以研究研究为什么。

如果只想解决问题,可以试试使用asyncio.run(coroutine)代替sync(coroutine)

def sync(coroutine: Coroutine) -> Any:
    """
    同步执行异步函数,使用可参考 [同步执行异步代码](https://nemo2011.github.io/bilibili-api/#/sync-executor)

    Args:
        coroutine (Coroutine): 执行异步函数所创建的协程对象

    Returns:
        该协程对象的返回值
    """
    try:
        asyncio.get_running_loop()
    except RuntimeError:
        return asyncio.run(coroutine)
    else:
        with ThreadPoolExecutor() as executor:
            return executor.submit(asyncio.run, coroutine).result()

LondonClass avatar Dec 27 '24 12:12 LondonClass

很明显你自己试一下就知道,asyncio.run 不能跑 asyncio.tasks._GatheringFuture...

loop.run_until_complete 是可以的

z0z0r4 avatar Jan 07 '25 15:01 z0z0r4

很明显你自己试一下就知道,asyncio.run 不能跑 asyncio.tasks._GatheringFuture...

loop.run_until_complete 是可以的

https://github.com/Nemo2011/bilibili-api/commit/103f506c9491321f6e54d6cde64706cf3e18ccdf#diff-08987623f732733cf9ff6fc7cb33152b8a29dc805f517670957f2a1e5b60a621L33 这个修改

z0z0r4 avatar Jan 07 '25 15:01 z0z0r4

https://docs.python.org/zh-cn/3.13/library/asyncio-runner.html#asyncio.run

asyncio.gather 给的是 asyncio.tasks._GatheringFuture,而 asyncio.run 是不认的

z0z0r4 avatar Jan 07 '25 15:01 z0z0r4