Explorar el Código

Merge pull request #1914 from zauberzeug/refreshable-return

Support return values of refreshable function
Rodja Trappe hace 1 año
padre
commit
6dba0b4090
Se han modificado 2 ficheros con 20 adiciones y 8 borrados
  1. 7 8
      nicegui/functions/refreshable.py
  2. 13 0
      tests/test_refreshable.py

+ 7 - 8
nicegui/functions/refreshable.py

@@ -24,26 +24,25 @@ class RefreshableTarget:
     locals: List[Any] = field(default_factory=list)
     locals: List[Any] = field(default_factory=list)
     next_index: int = 0
     next_index: int = 0
 
 
-    def run(self, func: Callable[..., Any]) -> Union[None, Awaitable]:
+    def run(self, func: Callable[..., Any]) -> Union[Any, Awaitable]:
         """Run the function and return the result."""
         """Run the function and return the result."""
         RefreshableTarget.current_target = self
         RefreshableTarget.current_target = self
         self.next_index = 0
         self.next_index = 0
         # pylint: disable=no-else-return
         # pylint: disable=no-else-return
         if is_coroutine_function(func):
         if is_coroutine_function(func):
-            async def wait_for_result() -> None:
+            async def wait_for_result() -> Any:
                 with self.container:
                 with self.container:
                     if self.instance is None:
                     if self.instance is None:
-                        await func(*self.args, **self.kwargs)
+                        return await func(*self.args, **self.kwargs)
                     else:
                     else:
-                        await func(self.instance, *self.args, **self.kwargs)
+                        return await func(self.instance, *self.args, **self.kwargs)
             return wait_for_result()
             return wait_for_result()
         else:
         else:
             with self.container:
             with self.container:
                 if self.instance is None:
                 if self.instance is None:
-                    func(*self.args, **self.kwargs)
+                    return func(*self.args, **self.kwargs)
                 else:
                 else:
-                    func(self.instance, *self.args, **self.kwargs)
-            return None  # required by mypy
+                    return func(self.instance, *self.args, **self.kwargs)
 
 
 
 
 class RefreshableContainer(Element, component='refreshable.js'):
 class RefreshableContainer(Element, component='refreshable.js'):
@@ -75,7 +74,7 @@ class refreshable:
             return refresh
             return refresh
         return attribute
         return attribute
 
 
-    def __call__(self, *args: Any, **kwargs: Any) -> Union[None, Awaitable]:
+    def __call__(self, *args: Any, **kwargs: Any) -> Union[Any, Awaitable]:
         self.prune()
         self.prune()
         target = RefreshableTarget(container=RefreshableContainer(), refreshable=self, instance=self.instance,
         target = RefreshableTarget(container=RefreshableContainer(), refreshable=self, instance=self.instance,
                                    args=args, kwargs=kwargs)
                                    args=args, kwargs=kwargs)

+ 13 - 0
tests/test_refreshable.py

@@ -205,3 +205,16 @@ def test_refreshable_with_state(screen: Screen):
     screen.wait(0.5)
     screen.wait(0.5)
     screen.should_contain('A: 1')
     screen.should_contain('A: 1')
     screen.should_contain('B: 1')
     screen.should_contain('B: 1')
+
+
+def test_refreshable_with_return_value(screen: Screen):
+    @ui.refreshable
+    def number_ui() -> int:
+        ui.label('42')
+        return 42
+
+    answer = number_ui()
+    assert answer == 42
+
+    screen.open('/')
+    screen.should_contain('42')