1
0
Эх сурвалжийг харах

fix: `put_buttons`,`toast`'s callback can't use coroutine in coroutine-based session

wangweimin 4 жил өмнө
parent
commit
e64d4de97b

+ 5 - 2
pywebio/output.py

@@ -512,8 +512,9 @@ def put_buttons(buttons, onclick, small=None, link_style=False, scope=Scope.Curr
 
        ``onclick`` 为列表时,列表内函数的签名为 ``func()``. 此时,回调函数与 ``buttons`` 一一对应
 
-       | Tip: 可以使用 ``functools.partial`` 来在 ``onclick`` 中保存更多上下文信息.
-       | Note: 当使用 :ref:`基于协程的会话实现 <coroutine_based_session>` 时,回调函数可以使用协程函数.
+       Tip: 可以使用 ``functools.partial`` 来在 ``onclick`` 中保存更多上下文信息.
+
+       Note: 当使用 :ref:`基于协程的会话实现 <coroutine_based_session>` 时,回调函数可以为协程函数.
     :param bool small: 是否显示小号按钮,默认为False
     :param bool link_style: 是否将按钮显示为链接样式,默认为False
     :param int scope, position: 与 `put_text` 函数的同名参数含义一致
@@ -1158,6 +1159,8 @@ def toast(content, duration=2, position='center', color='info', onclick=None):
     :param str color: 通知消息的背景颜色,可以为 `'info'` / `'error'` / `'warn'` / `'success'` 或以 `'#'` 开始的十六进制颜色值
     :param callable onclick: 点击通知消息时的回调函数,回调函数不接受任何参数。
 
+        Note: 当使用 :ref:`基于协程的会话实现 <coroutine_based_session>` 时,回调函数可以为协程函数.
+
     Example::
 
         def show_msg():

+ 6 - 2
pywebio/session/coroutinebased.py

@@ -162,7 +162,7 @@ class CoroutineBasedSession(Session):
 
         :type callback: Callable or Coroutine
         :param callback: 回调函数. 函数签名为 ``callback(data)``. ``data`` 参数为回调事件的值
-        :param bool mutex_mode: 互斥模式。若为 ``True`` ,则在运行回调函数过程中,无法响应同一组件的新点击事件,仅当 ``callback`` 为协程函数时有效
+        :param bool mutex_mode: 互斥模式。若为 ``True`` ,则在运行回调函数过程中,无法响应同一组件(callback_id相同)的新点击事件,仅当 ``callback`` 为协程函数时有效
         :return str: 回调id.
         """
 
@@ -181,7 +181,11 @@ class CoroutineBasedSession(Session):
                     coro = asyncio.coroutine(callback)(event['data'])
                 else:
                     try:
-                        callback(event['data'])
+                        res = callback(event['data'])
+                        if asyncio.iscoroutine(res):
+                            coro = res
+                        else:
+                            del res  # `res` maybe pywebio.io_ctrl.Output, so need release `res`
                     except Exception:
                         self.on_task_exception()