|
@@ -25,7 +25,7 @@ import uuid
|
|
|
import warnings
|
|
|
from importlib import metadata, util
|
|
|
from importlib.util import find_spec
|
|
|
-from inspect import currentframe, getabsfile, ismethod, ismodule
|
|
|
+from inspect import currentframe, getabsfile, iscoroutinefunction, ismethod, ismodule
|
|
|
from pathlib import Path
|
|
|
from threading import Thread, Timer
|
|
|
from types import FrameType, FunctionType, LambdaType, ModuleType, SimpleNamespace
|
|
@@ -73,7 +73,7 @@ from .extension.library import Element, ElementLibrary
|
|
|
from .page import Page
|
|
|
from .partial import Partial
|
|
|
from .server import _Server
|
|
|
-from .state import State, _GuiState
|
|
|
+from .state import State, _AsyncState, _GuiState
|
|
|
from .types import _WsType
|
|
|
from .utils import (
|
|
|
_delscopeattr,
|
|
@@ -115,6 +115,7 @@ from .utils._evaluator import _Evaluator
|
|
|
from .utils._variable_directory import _is_moduled_variable, _VariableDirectory
|
|
|
from .utils.chart_config_builder import _build_chart_config
|
|
|
from .utils.table_col_builder import _enhance_columns
|
|
|
+from .utils.threads import _invoke_async_callback
|
|
|
|
|
|
|
|
|
class Gui:
|
|
@@ -1143,7 +1144,6 @@ class Gui:
|
|
|
for var, val in state_context.items():
|
|
|
self._update_var(var, val, True, forward=False)
|
|
|
|
|
|
-
|
|
|
@staticmethod
|
|
|
def set_unsupported_data_converter(converter: t.Optional[t.Callable[[t.Any], t.Any]]) -> None:
|
|
|
"""Set a custom converter for unsupported data types.
|
|
@@ -1588,7 +1588,12 @@ class Gui:
|
|
|
|
|
|
def _call_function_with_state(self, user_function: t.Callable, args: t.Optional[t.List[t.Any]] = None) -> t.Any:
|
|
|
cp_args = [] if args is None else args.copy()
|
|
|
- cp_args.insert(0, self.__get_state())
|
|
|
+ cp_args.insert(
|
|
|
+ 0,
|
|
|
+ _AsyncState(t.cast(_GuiState, self.__get_state()))
|
|
|
+ if iscoroutinefunction(user_function)
|
|
|
+ else self.__get_state(),
|
|
|
+ )
|
|
|
argcount = user_function.__code__.co_argcount
|
|
|
if argcount > 0 and ismethod(user_function):
|
|
|
argcount -= 1
|
|
@@ -1597,7 +1602,10 @@ class Gui:
|
|
|
else:
|
|
|
cp_args = cp_args[:argcount]
|
|
|
with self.__event_manager:
|
|
|
- return user_function(*cp_args)
|
|
|
+ if iscoroutinefunction(user_function):
|
|
|
+ return _invoke_async_callback(user_function, cp_args)
|
|
|
+ else:
|
|
|
+ return user_function(*cp_args)
|
|
|
|
|
|
def _set_module_context(self, module_context: t.Optional[str]) -> t.ContextManager[None]:
|
|
|
return self._set_locals_context(module_context) if module_context is not None else contextlib.nullcontext()
|