nonebot / nonebot2

跨平台 Python 异步聊天机器人框架 / Asynchronous multi-platform chatbot framework written in Python
https://nonebot.dev
MIT License
6.07k stars 564 forks source link

Feature: 正向驱动器 startup/shutdown hook 同步函数支持 #1101

Closed ssttkkl closed 2 years ago

ssttkkl commented 2 years ago

描述问题:

BlockDriver注册同步on_startup与on_shutdown钩子函数时启动崩溃

如何复现?

from nonebot import get_driver

@get_driver().on_startup
def i_will_crash():
    print("oops")

期望的结果

环境信息:

协议端信息:

截图或日志

07-12 23:56:09 [SUCCESS] nonebot | NoneBot is initializing...
07-12 23:56:09 [INFO] nonebot | Current Env: dev
07-12 23:56:09 [DEBUG] nonebot | Loaded Config: {'driver': '~httpx+~websockets', 'host': IPv4Address('127.0.0.1'), 'port': 8080, 'log_level': 'DEBUG', 'api_timeout': 30.0, 'superusers': set(), 'nickname': set(), 'command_start': {'/'}, 'command_sep': {'.'}, 'session_expire_timeout': datetime.timedelta(seconds=120)}
07-12 23:56:09 [DEBUG] nonebot | Succeeded to load adapter "Kaiheila"
07-12 23:56:09 [SUCCESS] nonebot | Succeeded to import "echo"
07-12 23:56:09 [SUCCESS] nonebot | Succeeded to import "nonebot_plugin_pixivbot_kook"
07-12 23:56:09 [SUCCESS] nonebot | Succeeded to import "test"
07-12 23:56:09 [WARNING] __main__ | Always use `nb run` to start the bot instead of manually running!
07-12 23:56:09 [SUCCESS] nonebot | Running NoneBot...
07-12 23:56:09 [DEBUG] nonebot | Loaded adapters: Kaiheila
oops
07-12 23:56:09 [ERROR] nonebot | Error when running startup function. Ignored!
Traceback (most recent call last):
  File "C:\Users\huang\PycharmProjects\kuraku-kook\bot.py", line 21, in <module>
    nonebot.run()
  File "C:\Users\huang\PycharmProjects\kuraku-kook\venv\lib\site-packages\nonebot\__init__.py", line 261, in run
    get_driver().run(*args, **kwargs)
  File "C:\Users\huang\PycharmProjects\kuraku-kook\venv\lib\site-packages\nonebot\drivers\_block_driver.py", line 60, in run
    loop.run_until_complete(self.serve())
  File "C:\Users\huang\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 628, in run_until_complete
    self.run_forever()
  File "C:\Users\huang\AppData\Local\Programs\Python\Python310\lib\asyncio\windows_events.py", line 321, in run_forever
    super().run_forever()
  File "C:\Users\huang\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 595, in run_forever
    self._run_once()
  File "C:\Users\huang\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 1881, in _run_once
    handle._run()
  File "C:\Users\huang\AppData\Local\Programs\Python\Python310\lib\asyncio\events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
  File "C:\Users\huang\PycharmProjects\kuraku-kook\venv\lib\site-packages\nonebot\drivers\_block_driver.py", line 64, in serve
    await self.startup()
> File "C:\Users\huang\PycharmProjects\kuraku-kook\venv\lib\site-packages\nonebot\drivers\_block_driver.py", line 75, in startup
    await asyncio.gather(*cors)
  File "C:\Users\huang\AppData\Local\Programs\Python\Python310\lib\asyncio\tasks.py", line 776, in gather
    fut = _ensure_future(arg, loop=loop)
  File "C:\Users\huang\AppData\Local\Programs\Python\Python310\lib\asyncio\tasks.py", line 629, in _ensure_future
    raise TypeError('An asyncio.Future, a coroutine or an awaitable '
TypeError: An asyncio.Future, a coroutine or an awaitable is required
07-12 23:56:09 [INFO] nonebot | Application startup completed.
Exception in callback gather.<locals>._done_callback(<Task finishe...> result=None>) at C:\Users\huang\AppData\Local\Programs\Python\Python310\lib\asyncio\tasks.py:714
handle: <Handle gather.<locals>._done_callback(<Task finishe...> result=None>) at C:\Users\huang\AppData\Local\Programs\Python\Python310\lib\asyncio\tasks.py:714>
Traceback (most recent call last):
  File "C:\Users\huang\AppData\Local\Programs\Python\Python310\lib\asyncio\events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
  File "C:\Users\huang\AppData\Local\Programs\Python\Python310\lib\asyncio\tasks.py", line 718, in _done_callback
    if outer.done():
NameError: free variable 'outer' referenced before assignment in enclosing scope
07-12 23:56:09 [DEBUG] nonebot | Kaiheila | WebSocket Connection to wss://ws.kaiheila.cn/gateway?compress=0&token=***************** established
07-12 23:56:09 [INFO] nonebot | Kaiheila | Bot ******** connected
07-12 23:56:09 [DEBUG] nonebot | Kaiheila | Bot ******** HeartBeat
07-12 23:56:35 [DEBUG] nonebot | Kaiheila | Bot ******** HeartBeat
07-12 23:57:01 [DEBUG] nonebot | Kaiheila | Bot ******** HeartBeat
ssttkkl commented 2 years ago

应该是这里处理钩子函数的时候同时有异步和非异步时,coros内有None元素导致await asyncio.gather(*cors)抛出异常 QQ截图20220713000201

yanyongyu commented 2 years ago

block driver不支持同步hook,类型都写在on_startup和shutdown函数里了

yanyongyu commented 2 years ago

可以考虑增加一下同步支持