Browse Source

#722 specify type annotation for callables

Falko Schindler 2 years ago
parent
commit
d6ee01d83e
43 changed files with 178 additions and 115 deletions
  1. 5 5
      nicegui/binding.py
  2. 5 5
      nicegui/client.py
  3. 1 1
      nicegui/element.py
  4. 2 2
      nicegui/elements/button.py
  5. 2 2
      nicegui/elements/checkbox.py
  6. 5 1
      nicegui/elements/choice_element.py
  7. 7 3
      nicegui/elements/color_input.py
  8. 2 2
      nicegui/elements/color_picker.py
  9. 2 2
      nicegui/elements/date.py
  10. 2 2
      nicegui/elements/input.py
  11. 7 3
      nicegui/elements/interactive_image.py
  12. 3 3
      nicegui/elements/joystick.py
  13. 2 2
      nicegui/elements/keyboard.py
  14. 2 2
      nicegui/elements/link.py
  15. 6 2
      nicegui/elements/menu.py
  16. 7 4
      nicegui/elements/mixins/content_element.py
  17. 7 4
      nicegui/elements/mixins/disableable_element.py
  18. 7 4
      nicegui/elements/mixins/filter_element.py
  19. 7 4
      nicegui/elements/mixins/source_element.py
  20. 7 4
      nicegui/elements/mixins/text_element.py
  21. 13 5
      nicegui/elements/mixins/value_element.py
  22. 7 5
      nicegui/elements/mixins/visibility.py
  23. 3 2
      nicegui/elements/number.py
  24. 5 1
      nicegui/elements/radio.py
  25. 2 1
      nicegui/elements/scene.py
  26. 3 2
      nicegui/elements/select.py
  27. 3 2
      nicegui/elements/slider.py
  28. 3 2
      nicegui/elements/splitter.py
  29. 2 2
      nicegui/elements/switch.py
  30. 2 2
      nicegui/elements/table.py
  31. 3 2
      nicegui/elements/tabs.py
  32. 4 3
      nicegui/elements/textarea.py
  33. 4 4
      nicegui/elements/time.py
  34. 5 1
      nicegui/elements/toggle.py
  35. 4 3
      nicegui/elements/tree.py
  36. 3 3
      nicegui/elements/upload.py
  37. 1 1
      nicegui/events.py
  38. 2 2
      nicegui/functions/open.py
  39. 1 1
      nicegui/functions/refreshable.py
  40. 10 4
      nicegui/functions/timer.py
  41. 7 7
      nicegui/globals.py
  42. 1 1
      nicegui/helpers.py
  43. 2 2
      nicegui/page.py

+ 5 - 5
nicegui/binding.py

@@ -8,7 +8,7 @@ from . import globals
 
 
 bindings: DefaultDict[Tuple[int, str], List] = defaultdict(list)
 bindings: DefaultDict[Tuple[int, str], List] = defaultdict(list)
 bindable_properties: Dict[Tuple[int, str], Any] = {}
 bindable_properties: Dict[Tuple[int, str], Any] = {}
-active_links: List[Tuple[Any, str, Any, str, Callable]] = []
+active_links: List[Tuple[Any, str, Any, str, Callable[[Any], Any]]] = []
 
 
 
 
 def get_attribute(obj: Union[object, Dict], name: str) -> Any:
 def get_attribute(obj: Union[object, Dict], name: str) -> Any:
@@ -54,14 +54,14 @@ def propagate(source_obj: Any, source_name: str, visited: Optional[Set[Tuple[int
             propagate(target_obj, target_name, visited)
             propagate(target_obj, target_name, visited)
 
 
 
 
-def bind_to(self_obj: Any, self_name: str, other_obj: Any, other_name: str, forward: Callable) -> None:
+def bind_to(self_obj: Any, self_name: str, other_obj: Any, other_name: str, forward: Callable[[Any], Any]) -> None:
     bindings[(id(self_obj), self_name)].append((self_obj, other_obj, other_name, forward))
     bindings[(id(self_obj), self_name)].append((self_obj, other_obj, other_name, forward))
     if (id(self_obj), self_name) not in bindable_properties:
     if (id(self_obj), self_name) not in bindable_properties:
         active_links.append((self_obj, self_name, other_obj, other_name, forward))
         active_links.append((self_obj, self_name, other_obj, other_name, forward))
     propagate(self_obj, self_name)
     propagate(self_obj, self_name)
 
 
 
 
-def bind_from(self_obj: Any, self_name: str, other_obj: Any, other_name: str, backward: Callable) -> None:
+def bind_from(self_obj: Any, self_name: str, other_obj: Any, other_name: str, backward: Callable[[Any], Any]) -> None:
     bindings[(id(other_obj), other_name)].append((other_obj, self_obj, self_name, backward))
     bindings[(id(other_obj), other_name)].append((other_obj, self_obj, self_name, backward))
     if (id(other_obj), other_name) not in bindable_properties:
     if (id(other_obj), other_name) not in bindable_properties:
         active_links.append((other_obj, other_name, self_obj, self_name, backward))
         active_links.append((other_obj, other_name, self_obj, self_name, backward))
@@ -69,14 +69,14 @@ def bind_from(self_obj: Any, self_name: str, other_obj: Any, other_name: str, ba
 
 
 
 
 def bind(self_obj: Any, self_name: str, other_obj: Any, other_name: str, *,
 def bind(self_obj: Any, self_name: str, other_obj: Any, other_name: str, *,
-         forward: Callable = lambda x: x, backward: Callable = lambda x: x) -> None:
+         forward: Callable[[Any], Any] = lambda x: x, backward: Callable[[Any], Any] = lambda x: x) -> None:
     bind_from(self_obj, self_name, other_obj, other_name, backward=backward)
     bind_from(self_obj, self_name, other_obj, other_name, backward=backward)
     bind_to(self_obj, self_name, other_obj, other_name, forward=forward)
     bind_to(self_obj, self_name, other_obj, other_name, forward=forward)
 
 
 
 
 class BindableProperty:
 class BindableProperty:
 
 
-    def __init__(self, on_change: Optional[Callable] = None) -> None:
+    def __init__(self, on_change: Optional[Callable[..., Any]] = None) -> None:
         self.on_change = on_change
         self.on_change = on_change
 
 
     def __set_name__(self, _, name: str) -> None:
     def __set_name__(self, _, name: str) -> None:

+ 5 - 5
nicegui/client.py

@@ -47,8 +47,8 @@ class Client:
 
 
         self.page = page
         self.page = page
 
 
-        self.connect_handlers: List[Union[Callable, Awaitable]] = []
-        self.disconnect_handlers: List[Union[Callable, Awaitable]] = []
+        self.connect_handlers: List[Union[Callable[..., Any], Awaitable]] = []
+        self.disconnect_handlers: List[Union[Callable[..., Any], Awaitable]] = []
 
 
     @property
     @property
     def ip(self) -> Optional[str]:
     def ip(self) -> Optional[str]:
@@ -130,7 +130,7 @@ class Client:
             await asyncio.sleep(check_interval)
             await asyncio.sleep(check_interval)
         return self.waiting_javascript_commands.pop(request_id)
         return self.waiting_javascript_commands.pop(request_id)
 
 
-    def open(self, target: Union[Callable, str]) -> None:
+    def open(self, target: Union[Callable[..., Any], str]) -> None:
         """Open a new page in the client."""
         """Open a new page in the client."""
         path = target if isinstance(target, str) else globals.page_routes[target]
         path = target if isinstance(target, str) else globals.page_routes[target]
         outbox.enqueue_message('open', path, self.id)
         outbox.enqueue_message('open', path, self.id)
@@ -139,10 +139,10 @@ class Client:
         """Download a file from the given URL."""
         """Download a file from the given URL."""
         outbox.enqueue_message('download', {'url': url, 'filename': filename}, self.id)
         outbox.enqueue_message('download', {'url': url, 'filename': filename}, self.id)
 
 
-    def on_connect(self, handler: Union[Callable, Awaitable]) -> None:
+    def on_connect(self, handler: Union[Callable[..., Any], Awaitable]) -> None:
         """Register a callback to be called when the client connects."""
         """Register a callback to be called when the client connects."""
         self.connect_handlers.append(handler)
         self.connect_handlers.append(handler)
 
 
-    def on_disconnect(self, handler: Union[Callable, Awaitable]) -> None:
+    def on_disconnect(self, handler: Union[Callable[..., Any], Awaitable]) -> None:
         """Register a callback to be called when the client disconnects."""
         """Register a callback to be called when the client disconnects."""
         self.disconnect_handlers.append(handler)
         self.disconnect_handlers.append(handler)

+ 1 - 1
nicegui/element.py

@@ -197,7 +197,7 @@ class Element(Visibility):
 
 
     def on(self,
     def on(self,
            type: str,
            type: str,
-           handler: Optional[Callable],
+           handler: Optional[Callable[..., Any]] = None,
            args: Optional[List[str]] = None, *,
            args: Optional[List[str]] = None, *,
            throttle: float = 0.0,
            throttle: float = 0.0,
            leading_events: bool = True,
            leading_events: bool = True,

+ 2 - 2
nicegui/elements/button.py

@@ -1,5 +1,5 @@
 import asyncio
 import asyncio
-from typing import Callable, Optional
+from typing import Any, Callable, Optional
 
 
 from ..colors import set_background_color
 from ..colors import set_background_color
 from ..events import ClickEventArguments, handle_event
 from ..events import ClickEventArguments, handle_event
@@ -11,7 +11,7 @@ class Button(TextElement, DisableableElement):
 
 
     def __init__(self,
     def __init__(self,
                  text: str = '', *,
                  text: str = '', *,
-                 on_click: Optional[Callable] = None,
+                 on_click: Optional[Callable[..., Any]] = None,
                  color: Optional[str] = 'primary',
                  color: Optional[str] = 'primary',
                  ) -> None:
                  ) -> None:
         """Button
         """Button

+ 2 - 2
nicegui/elements/checkbox.py

@@ -1,4 +1,4 @@
-from typing import Callable, Optional
+from typing import Any, Callable, Optional
 
 
 from .mixins.disableable_element import DisableableElement
 from .mixins.disableable_element import DisableableElement
 from .mixins.text_element import TextElement
 from .mixins.text_element import TextElement
@@ -7,7 +7,7 @@ from .mixins.value_element import ValueElement
 
 
 class Checkbox(TextElement, ValueElement, DisableableElement):
 class Checkbox(TextElement, ValueElement, DisableableElement):
 
 
-    def __init__(self, text: str = '', *, value: bool = False, on_change: Optional[Callable] = None) -> None:
+    def __init__(self, text: str = '', *, value: bool = False, on_change: Optional[Callable[..., Any]] = None) -> None:
         """Checkbox
         """Checkbox
 
 
         :param text: the label to display next to the checkbox
         :param text: the label to display next to the checkbox

+ 5 - 1
nicegui/elements/choice_element.py

@@ -6,7 +6,11 @@ from .mixins.value_element import ValueElement
 class ChoiceElement(ValueElement):
 class ChoiceElement(ValueElement):
 
 
     def __init__(self, *,
     def __init__(self, *,
-                 tag: str, options: Union[List, Dict], value: Any, on_change: Optional[Callable] = None) -> None:
+                 tag: str,
+                 options: Union[List, Dict],
+                 value: Any,
+                 on_change: Optional[Callable[..., Any]] = None,
+                 ) -> None:
         self.options = options
         self.options = options
         self._values: List[str] = []
         self._values: List[str] = []
         self._labels: List[str] = []
         self._labels: List[str] = []

+ 7 - 3
nicegui/elements/color_input.py

@@ -1,4 +1,4 @@
-from typing import Callable, Optional
+from typing import Any, Callable, Optional
 
 
 from nicegui import ui
 from nicegui import ui
 
 
@@ -10,8 +10,12 @@ from .mixins.value_element import ValueElement
 class ColorInput(ValueElement, DisableableElement):
 class ColorInput(ValueElement, DisableableElement):
     LOOPBACK = False
     LOOPBACK = False
 
 
-    def __init__(self, label: Optional[str] = None, *,
-                 placeholder: Optional[str] = None, value: str = '', on_change: Optional[Callable] = None) -> None:
+    def __init__(self,
+                 label: Optional[str] = None, *,
+                 placeholder: Optional[str] = None,
+                 value: str = '',
+                 on_change: Optional[Callable[..., Any]] = None,
+                 ) -> None:
         """Color Input
         """Color Input
 
 
         :param label: displayed label for the color input
         :param label: displayed label for the color input

+ 2 - 2
nicegui/elements/color_picker.py

@@ -1,4 +1,4 @@
-from typing import Callable, Dict
+from typing import Any, Callable, Dict
 
 
 from nicegui.events import ColorPickEventArguments, handle_event
 from nicegui.events import ColorPickEventArguments, handle_event
 
 
@@ -8,7 +8,7 @@ from .menu import Menu
 
 
 class ColorPicker(Menu):
 class ColorPicker(Menu):
 
 
-    def __init__(self, *, on_pick: Callable, value: bool = False) -> None:
+    def __init__(self, *, on_pick: Callable[..., Any], value: bool = False) -> None:
         """Color Picker
         """Color Picker
 
 
         :param on_pick: callback to execute when a color is picked
         :param on_pick: callback to execute when a color is picked

+ 2 - 2
nicegui/elements/date.py

@@ -1,4 +1,4 @@
-from typing import Callable, Optional
+from typing import Any, Callable, Optional
 
 
 from .mixins.disableable_element import DisableableElement
 from .mixins.disableable_element import DisableableElement
 from .mixins.value_element import ValueElement
 from .mixins.value_element import ValueElement
@@ -11,7 +11,7 @@ class Date(ValueElement, DisableableElement):
                  value: Optional[str] = None,
                  value: Optional[str] = None,
                  *,
                  *,
                  mask: str = 'YYYY-MM-DD',
                  mask: str = 'YYYY-MM-DD',
-                 on_change: Optional[Callable] = None) -> None:
+                 on_change: Optional[Callable[..., Any]] = None) -> None:
         """Date Input
         """Date Input
 
 
         This element is based on Quasar's `QDate <https://quasar.dev/vue-components/date>`_ component.
         This element is based on Quasar's `QDate <https://quasar.dev/vue-components/date>`_ component.

+ 2 - 2
nicegui/elements/input.py

@@ -14,9 +14,9 @@ class Input(ValueElement, DisableableElement):
                  value: str = '',
                  value: str = '',
                  password: bool = False,
                  password: bool = False,
                  password_toggle_button: bool = False,
                  password_toggle_button: bool = False,
-                 on_change: Optional[Callable] = None,
+                 on_change: Optional[Callable[..., Any]] = None,
                  autocomplete: Optional[List[str]] = None,
                  autocomplete: Optional[List[str]] = None,
-                 validation: Dict[str, Callable] = {}) -> None:
+                 validation: Dict[str, Callable[..., bool]] = {}) -> None:
         """Text Input
         """Text Input
 
 
         This element is based on Quasar's `QInput <https://quasar.dev/vue-components/input>`_ component.
         This element is based on Quasar's `QInput <https://quasar.dev/vue-components/input>`_ component.

+ 7 - 3
nicegui/elements/interactive_image.py

@@ -1,6 +1,6 @@
 from __future__ import annotations
 from __future__ import annotations
 
 
-from typing import Callable, Dict, List, Optional
+from typing import Any, Callable, Dict, List, Optional
 
 
 from ..dependencies import register_component
 from ..dependencies import register_component
 from ..events import MouseEventArguments, handle_event
 from ..events import MouseEventArguments, handle_event
@@ -13,9 +13,13 @@ register_component('interactive_image', __file__, 'interactive_image.js')
 class InteractiveImage(SourceElement, ContentElement):
 class InteractiveImage(SourceElement, ContentElement):
     CONTENT_PROP = 'content'
     CONTENT_PROP = 'content'
 
 
-    def __init__(self, source: str = '', *,
+    def __init__(self,
+                 source: str = '', *,
                  content: str = '',
                  content: str = '',
-                 on_mouse: Optional[Callable] = None, events: List[str] = ['click'], cross: bool = False) -> None:
+                 on_mouse: Optional[Callable[..., Any]] = None,
+                 events: List[str] = ['click'],
+                 cross: bool = False,
+                 ) -> None:
         """Interactive Image
         """Interactive Image
 
 
         Create an image with an SVG overlay that handles mouse events and yields image coordinates.
         Create an image with an SVG overlay that handles mouse events and yields image coordinates.

+ 3 - 3
nicegui/elements/joystick.py

@@ -10,9 +10,9 @@ register_component('joystick', __file__, 'joystick.vue', ['lib/nipplejs.min.js']
 class Joystick(Element):
 class Joystick(Element):
 
 
     def __init__(self, *,
     def __init__(self, *,
-                 on_start: Optional[Callable] = None,
-                 on_move: Optional[Callable] = None,
-                 on_end: Optional[Callable] = None,
+                 on_start: Optional[Callable[..., Any]] = None,
+                 on_move: Optional[Callable[..., Any]] = None,
+                 on_end: Optional[Callable[..., Any]] = None,
                  throttle: float = 0.05,
                  throttle: float = 0.05,
                  ** options: Any) -> None:
                  ** options: Any) -> None:
         """Joystick
         """Joystick

+ 2 - 2
nicegui/elements/keyboard.py

@@ -1,4 +1,4 @@
-from typing import Callable, Dict, List
+from typing import Any, Callable, Dict, List
 
 
 from typing_extensions import Literal
 from typing_extensions import Literal
 
 
@@ -14,7 +14,7 @@ class Keyboard(Element):
     active = BindableProperty()
     active = BindableProperty()
 
 
     def __init__(self,
     def __init__(self,
-                 on_key: Callable, *,
+                 on_key: Callable[..., Any], *,
                  active: bool = True,
                  active: bool = True,
                  repeating: bool = True,
                  repeating: bool = True,
                  ignore: List[Literal['input', 'select', 'button', 'textarea']] = ['input', 'select', 'button', 'textarea'],
                  ignore: List[Literal['input', 'select', 'button', 'textarea']] = ['input', 'select', 'button', 'textarea'],

+ 2 - 2
nicegui/elements/link.py

@@ -1,4 +1,4 @@
-from typing import Callable, Union
+from typing import Any, Callable, Union
 
 
 from .. import globals
 from .. import globals
 from ..dependencies import register_component
 from ..dependencies import register_component
@@ -10,7 +10,7 @@ register_component('link', __file__, 'link.js')
 
 
 class Link(TextElement):
 class Link(TextElement):
 
 
-    def __init__(self, text: str = '', target: Union[Callable, str] = '#', new_tab: bool = False) -> None:
+    def __init__(self, text: str = '', target: Union[Callable[..., Any], str] = '#', new_tab: bool = False) -> None:
         """Link
         """Link
 
 
         Create a hyperlink.
         Create a hyperlink.

+ 6 - 2
nicegui/elements/menu.py

@@ -1,4 +1,4 @@
-from typing import Callable, Optional
+from typing import Any, Callable, Optional
 
 
 from .. import globals
 from .. import globals
 from ..events import ClickEventArguments, handle_event
 from ..events import ClickEventArguments, handle_event
@@ -28,7 +28,11 @@ class Menu(ValueElement):
 
 
 class MenuItem(TextElement):
 class MenuItem(TextElement):
 
 
-    def __init__(self, text: str = '', on_click: Optional[Callable] = None, *, auto_close: bool = True) -> None:
+    def __init__(self,
+                 text: str = '',
+                 on_click: Optional[Callable[..., Any]] = None, *,
+                 auto_close: bool = True,
+                 ) -> None:
         """Menu Item
         """Menu Item
 
 
         A menu item to be added to a menu.
         A menu item to be added to a menu.

+ 7 - 4
nicegui/elements/mixins/content_element.py

@@ -18,7 +18,8 @@ class ContentElement(Element):
     def bind_content_to(self,
     def bind_content_to(self,
                         target_object: Any,
                         target_object: Any,
                         target_name: str = 'content',
                         target_name: str = 'content',
-                        forward: Callable = lambda x: x) -> Self:
+                        forward: Callable[..., Any] = lambda x: x,
+                        ) -> Self:
         """Bind the content of this element to the target object's target_name property.
         """Bind the content of this element to the target object's target_name property.
 
 
         The binding works one way only, from this element to the target.
         The binding works one way only, from this element to the target.
@@ -33,7 +34,8 @@ class ContentElement(Element):
     def bind_content_from(self,
     def bind_content_from(self,
                           target_object: Any,
                           target_object: Any,
                           target_name: str = 'content',
                           target_name: str = 'content',
-                          backward: Callable = lambda x: x) -> Self:
+                          backward: Callable[..., Any] = lambda x: x,
+                          ) -> Self:
         """Bind the content of this element from the target object's target_name property.
         """Bind the content of this element from the target object's target_name property.
 
 
         The binding works one way only, from the target to this element.
         The binding works one way only, from the target to this element.
@@ -48,8 +50,9 @@ class ContentElement(Element):
     def bind_content(self,
     def bind_content(self,
                      target_object: Any,
                      target_object: Any,
                      target_name: str = 'content', *,
                      target_name: str = 'content', *,
-                     forward: Callable = lambda x: x,
-                     backward: Callable = lambda x: x) -> Self:
+                     forward: Callable[..., Any] = lambda x: x,
+                     backward: Callable[..., Any] = lambda x: x,
+                     ) -> Self:
         """Bind the content of this element to the target object's target_name property.
         """Bind the content of this element to the target object's target_name property.
 
 
         The binding works both ways, from this element to the target and from the target to this element.
         The binding works both ways, from this element to the target and from the target to this element.

+ 7 - 4
nicegui/elements/mixins/disableable_element.py

@@ -24,7 +24,8 @@ class DisableableElement(Element):
     def bind_enabled_to(self,
     def bind_enabled_to(self,
                         target_object: Any,
                         target_object: Any,
                         target_name: str = 'enabled',
                         target_name: str = 'enabled',
-                        forward: Callable = lambda x: x) -> Self:
+                        forward: Callable[..., Any] = lambda x: x,
+                        ) -> Self:
         """Bind the enabled state of this element to the target object's target_name property.
         """Bind the enabled state of this element to the target object's target_name property.
 
 
         The binding works one way only, from this element to the target.
         The binding works one way only, from this element to the target.
@@ -39,7 +40,8 @@ class DisableableElement(Element):
     def bind_enabled_from(self,
     def bind_enabled_from(self,
                           target_object: Any,
                           target_object: Any,
                           target_name: str = 'enabled',
                           target_name: str = 'enabled',
-                          backward: Callable = lambda x: x) -> Self:
+                          backward: Callable[..., Any] = lambda x: x,
+                          ) -> Self:
         """Bind the enabled state of this element from the target object's target_name property.
         """Bind the enabled state of this element from the target object's target_name property.
 
 
         The binding works one way only, from the target to this element.
         The binding works one way only, from the target to this element.
@@ -54,8 +56,9 @@ class DisableableElement(Element):
     def bind_enabled(self,
     def bind_enabled(self,
                      target_object: Any,
                      target_object: Any,
                      target_name: str = 'enabled', *,
                      target_name: str = 'enabled', *,
-                     forward: Callable = lambda x: x,
-                     backward: Callable = lambda x: x) -> Self:
+                     forward: Callable[..., Any] = lambda x: x,
+                     backward: Callable[..., Any] = lambda x: x,
+                     ) -> Self:
         """Bind the enabled state of this element to the target object's target_name property.
         """Bind the enabled state of this element to the target object's target_name property.
 
 
         The binding works both ways, from this element to the target and from the target to this element.
         The binding works both ways, from this element to the target and from the target to this element.

+ 7 - 4
nicegui/elements/mixins/filter_element.py

@@ -18,7 +18,8 @@ class FilterElement(Element):
     def bind_filter_to(self,
     def bind_filter_to(self,
                        target_object: Any,
                        target_object: Any,
                        target_name: str = 'filter',
                        target_name: str = 'filter',
-                       forward: Callable = lambda x: x) -> Self:
+                       forward: Callable[..., Any] = lambda x: x,
+                       ) -> Self:
         """Bind the filter of this element to the target object's target_name property.
         """Bind the filter of this element to the target object's target_name property.
 
 
         The binding works one way only, from this element to the target.
         The binding works one way only, from this element to the target.
@@ -33,7 +34,8 @@ class FilterElement(Element):
     def bind_filter_from(self,
     def bind_filter_from(self,
                          target_object: Any,
                          target_object: Any,
                          target_name: str = 'filter',
                          target_name: str = 'filter',
-                         backward: Callable = lambda x: x) -> Self:
+                         backward: Callable[..., Any] = lambda x: x,
+                         ) -> Self:
         """Bind the filter of this element from the target object's target_name property.
         """Bind the filter of this element from the target object's target_name property.
 
 
         The binding works one way only, from the target to this element.
         The binding works one way only, from the target to this element.
@@ -48,8 +50,9 @@ class FilterElement(Element):
     def bind_filter(self,
     def bind_filter(self,
                     target_object: Any,
                     target_object: Any,
                     target_name: str = 'filter', *,
                     target_name: str = 'filter', *,
-                    forward: Callable = lambda x: x,
-                    backward: Callable = lambda x: x) -> Self:
+                    forward: Callable[..., Any] = lambda x: x,
+                    backward: Callable[..., Any] = lambda x: x,
+                    ) -> Self:
         """Bind the filter of this element to the target object's target_name property.
         """Bind the filter of this element to the target object's target_name property.
 
 
         The binding works both ways, from this element to the target and from the target to this element.
         The binding works both ways, from this element to the target and from the target to this element.

+ 7 - 4
nicegui/elements/mixins/source_element.py

@@ -17,7 +17,8 @@ class SourceElement(Element):
     def bind_source_to(self,
     def bind_source_to(self,
                        target_object: Any,
                        target_object: Any,
                        target_name: str = 'source',
                        target_name: str = 'source',
-                       forward: Callable = lambda x: x) -> Self:
+                       forward: Callable[..., Any] = lambda x: x,
+                       ) -> Self:
         """Bind the source of this element to the target object's target_name property.
         """Bind the source of this element to the target object's target_name property.
 
 
         The binding works one way only, from this element to the target.
         The binding works one way only, from this element to the target.
@@ -32,7 +33,8 @@ class SourceElement(Element):
     def bind_source_from(self,
     def bind_source_from(self,
                          target_object: Any,
                          target_object: Any,
                          target_name: str = 'source',
                          target_name: str = 'source',
-                         backward: Callable = lambda x: x) -> Self:
+                         backward: Callable[..., Any] = lambda x: x,
+                         ) -> Self:
         """Bind the source of this element from the target object's target_name property.
         """Bind the source of this element from the target object's target_name property.
 
 
         The binding works one way only, from the target to this element.
         The binding works one way only, from the target to this element.
@@ -47,8 +49,9 @@ class SourceElement(Element):
     def bind_source(self,
     def bind_source(self,
                     target_object: Any,
                     target_object: Any,
                     target_name: str = 'source', *,
                     target_name: str = 'source', *,
-                    forward: Callable = lambda x: x,
-                    backward: Callable = lambda x: x) -> Self:
+                    forward: Callable[..., Any] = lambda x: x,
+                    backward: Callable[..., Any] = lambda x: x,
+                    ) -> Self:
         """Bind the source of this element to the target object's target_name property.
         """Bind the source of this element to the target object's target_name property.
 
 
         The binding works both ways, from this element to the target and from the target to this element.
         The binding works both ways, from this element to the target and from the target to this element.

+ 7 - 4
nicegui/elements/mixins/text_element.py

@@ -17,7 +17,8 @@ class TextElement(Element):
     def bind_text_to(self,
     def bind_text_to(self,
                      target_object: Any,
                      target_object: Any,
                      target_name: str = 'text',
                      target_name: str = 'text',
-                     forward: Callable = lambda x: x) -> Self:
+                     forward: Callable[..., Any] = lambda x: x,
+                     ) -> Self:
         """Bind the text of this element to the target object's target_name property.
         """Bind the text of this element to the target object's target_name property.
 
 
         The binding works one way only, from this element to the target.
         The binding works one way only, from this element to the target.
@@ -32,7 +33,8 @@ class TextElement(Element):
     def bind_text_from(self,
     def bind_text_from(self,
                        target_object: Any,
                        target_object: Any,
                        target_name: str = 'text',
                        target_name: str = 'text',
-                       backward: Callable = lambda x: x) -> Self:
+                       backward: Callable[..., Any] = lambda x: x,
+                       ) -> Self:
         """Bind the text of this element from the target object's target_name property.
         """Bind the text of this element from the target object's target_name property.
 
 
         The binding works one way only, from the target to this element.
         The binding works one way only, from the target to this element.
@@ -47,8 +49,9 @@ class TextElement(Element):
     def bind_text(self,
     def bind_text(self,
                   target_object: Any,
                   target_object: Any,
                   target_name: str = 'text', *,
                   target_name: str = 'text', *,
-                  forward: Callable = lambda x: x,
-                  backward: Callable = lambda x: x) -> Self:
+                  forward: Callable[..., Any] = lambda x: x,
+                  backward: Callable[..., Any] = lambda x: x,
+                  ) -> Self:
         """Bind the text of this element to the target object's target_name property.
         """Bind the text of this element to the target object's target_name property.
 
 
         The binding works both ways, from this element to the target and from the target to this element.
         The binding works both ways, from this element to the target and from the target to this element.

+ 13 - 5
nicegui/elements/mixins/value_element.py

@@ -13,7 +13,12 @@ class ValueElement(Element):
     LOOPBACK = True
     LOOPBACK = True
     value = BindableProperty(on_change=lambda sender, value: sender.on_value_change(value))
     value = BindableProperty(on_change=lambda sender, value: sender.on_value_change(value))
 
 
-    def __init__(self, *, value: Any, on_value_change: Optional[Callable], throttle: float = 0, **kwargs) -> None:
+    def __init__(self, *,
+                 value: Any,
+                 on_value_change: Optional[Callable[..., Any]],
+                 throttle: float = 0,
+                 **kwargs,
+                 ) -> None:
         super().__init__(**kwargs)
         super().__init__(**kwargs)
         self.set_value(value)
         self.set_value(value)
         self._props[self.VALUE_PROP] = self._value_to_model_value(value)
         self._props[self.VALUE_PROP] = self._value_to_model_value(value)
@@ -30,7 +35,8 @@ class ValueElement(Element):
     def bind_value_to(self,
     def bind_value_to(self,
                       target_object: Any,
                       target_object: Any,
                       target_name: str = 'value',
                       target_name: str = 'value',
-                      forward: Callable = lambda x: x) -> Self:
+                      forward: Callable[..., Any] = lambda x: x,
+                      ) -> Self:
         """Bind the value of this element to the target object's target_name property.
         """Bind the value of this element to the target object's target_name property.
 
 
         The binding works one way only, from this element to the target.
         The binding works one way only, from this element to the target.
@@ -45,7 +51,8 @@ class ValueElement(Element):
     def bind_value_from(self,
     def bind_value_from(self,
                         target_object: Any,
                         target_object: Any,
                         target_name: str = 'value',
                         target_name: str = 'value',
-                        backward: Callable = lambda x: x) -> Self:
+                        backward: Callable[..., Any] = lambda x: x,
+                        ) -> Self:
         """Bind the value of this element from the target object's target_name property.
         """Bind the value of this element from the target object's target_name property.
 
 
         The binding works one way only, from the target to this element.
         The binding works one way only, from the target to this element.
@@ -60,8 +67,9 @@ class ValueElement(Element):
     def bind_value(self,
     def bind_value(self,
                    target_object: Any,
                    target_object: Any,
                    target_name: str = 'value', *,
                    target_name: str = 'value', *,
-                   forward: Callable = lambda x: x,
-                   backward: Callable = lambda x: x) -> Self:
+                   forward: Callable[..., Any] = lambda x: x,
+                   backward: Callable[..., Any] = lambda x: x,
+                   ) -> Self:
         """Bind the value of this element to the target object's target_name property.
         """Bind the value of this element to the target object's target_name property.
 
 
         The binding works both ways, from this element to the target and from the target to this element.
         The binding works both ways, from this element to the target and from the target to this element.

+ 7 - 5
nicegui/elements/mixins/visibility.py

@@ -18,7 +18,8 @@ class Visibility:
     def bind_visibility_to(self,
     def bind_visibility_to(self,
                            target_object: Any,
                            target_object: Any,
                            target_name: str = 'visible',
                            target_name: str = 'visible',
-                           forward: Callable = lambda x: x) -> Self:
+                           forward: Callable[..., Any] = lambda x: x,
+                           ) -> Self:
         """Bind the visibility of this element to the target object's target_name property.
         """Bind the visibility of this element to the target object's target_name property.
 
 
         The binding works one way only, from this element to the target.
         The binding works one way only, from this element to the target.
@@ -33,7 +34,7 @@ class Visibility:
     def bind_visibility_from(self,
     def bind_visibility_from(self,
                              target_object: Any,
                              target_object: Any,
                              target_name: str = 'visible',
                              target_name: str = 'visible',
-                             backward: Callable = lambda x: x, *,
+                             backward: Callable[..., Any] = lambda x: x, *,
                              value: Any = None) -> Self:
                              value: Any = None) -> Self:
         """Bind the visibility of this element from the target object's target_name property.
         """Bind the visibility of this element from the target object's target_name property.
 
 
@@ -52,9 +53,10 @@ class Visibility:
     def bind_visibility(self,
     def bind_visibility(self,
                         target_object: Any,
                         target_object: Any,
                         target_name: str = 'visible', *,
                         target_name: str = 'visible', *,
-                        forward: Callable = lambda x: x,
-                        backward: Callable = lambda x: x,
-                        value: Any = None) -> Self:
+                        forward: Callable[..., Any] = lambda x: x,
+                        backward: Callable[..., Any] = lambda x: x,
+                        value: Any = None,
+                        ) -> Self:
         """Bind the visibility of this element to the target object's target_name property.
         """Bind the visibility of this element to the target object's target_name property.
 
 
         The binding works both ways, from this element to the target and from the target to this element.
         The binding works both ways, from this element to the target and from the target to this element.

+ 3 - 2
nicegui/elements/number.py

@@ -17,8 +17,9 @@ class Number(ValueElement, DisableableElement):
                  prefix: Optional[str] = None,
                  prefix: Optional[str] = None,
                  suffix: Optional[str] = None,
                  suffix: Optional[str] = None,
                  format: Optional[str] = None,
                  format: Optional[str] = None,
-                 on_change: Optional[Callable] = None,
-                 validation: Dict[str, Callable] = {}) -> None:
+                 on_change: Optional[Callable[..., Any]] = None,
+                 validation: Dict[str, Callable[..., bool]] = {},
+                 ) -> None:
         """Number Input
         """Number Input
 
 
         This element is based on Quasar's `QInput <https://quasar.dev/vue-components/input>`_ component.
         This element is based on Quasar's `QInput <https://quasar.dev/vue-components/input>`_ component.

+ 5 - 1
nicegui/elements/radio.py

@@ -6,7 +6,11 @@ from .mixins.disableable_element import DisableableElement
 
 
 class Radio(ChoiceElement, DisableableElement):
 class Radio(ChoiceElement, DisableableElement):
 
 
-    def __init__(self, options: Union[List, Dict], *, value: Any = None, on_change: Optional[Callable] = None):
+    def __init__(self,
+                 options: Union[List, Dict], *,
+                 value: Any = None,
+                 on_change: Optional[Callable[..., Any]] = None,
+                 ) -> None:
         """Radio Selection
         """Radio Selection
 
 
         The options can be specified as a list of values, or as a dictionary mapping values to labels.
         The options can be specified as a list of values, or as a dictionary mapping values to labels.

+ 2 - 1
nicegui/elements/scene.py

@@ -57,7 +57,8 @@ class Scene(Element):
                  width: int = 400,
                  width: int = 400,
                  height: int = 300,
                  height: int = 300,
                  grid: bool = True,
                  grid: bool = True,
-                 on_click: Optional[Callable] = None) -> None:
+                 on_click: Optional[Callable[..., Any]] = None,
+                 ) -> None:
         """3D Scene
         """3D Scene
 
 
         Display a 3d scene using `three.js <https://threejs.org/>`_.
         Display a 3d scene using `three.js <https://threejs.org/>`_.

+ 3 - 2
nicegui/elements/select.py

@@ -15,8 +15,9 @@ class Select(ChoiceElement, DisableableElement):
     def __init__(self, options: Union[List, Dict], *,
     def __init__(self, options: Union[List, Dict], *,
                  label: Optional[str] = None,
                  label: Optional[str] = None,
                  value: Any = None,
                  value: Any = None,
-                 on_change: Optional[Callable] = None,
-                 with_input: bool = False) -> None:
+                 on_change: Optional[Callable[..., Any]] = None,
+                 with_input: bool = False,
+                 ) -> None:
         """Dropdown Selection
         """Dropdown Selection
 
 
         The options can be specified as a list of values, or as a dictionary mapping values to labels.
         The options can be specified as a list of values, or as a dictionary mapping values to labels.

+ 3 - 2
nicegui/elements/slider.py

@@ -1,4 +1,4 @@
-from typing import Callable, Optional
+from typing import Any, Callable, Optional
 
 
 from .mixins.disableable_element import DisableableElement
 from .mixins.disableable_element import DisableableElement
 from .mixins.value_element import ValueElement
 from .mixins.value_element import ValueElement
@@ -11,7 +11,8 @@ class Slider(ValueElement, DisableableElement):
                  max: float,
                  max: float,
                  step: float = 1.0,
                  step: float = 1.0,
                  value: Optional[float] = None,
                  value: Optional[float] = None,
-                 on_change: Optional[Callable] = None) -> None:
+                 on_change: Optional[Callable[..., Any]] = None,
+                 ) -> None:
         """Slider
         """Slider
 
 
         :param min: lower bound of the slider
         :param min: lower bound of the slider

+ 3 - 2
nicegui/elements/splitter.py

@@ -1,4 +1,4 @@
-from typing import Callable, Optional, Tuple
+from typing import Any, Callable, Optional, Tuple
 
 
 from .mixins.disableable_element import DisableableElement
 from .mixins.disableable_element import DisableableElement
 from .mixins.value_element import ValueElement
 from .mixins.value_element import ValueElement
@@ -11,7 +11,8 @@ class Splitter(ValueElement, DisableableElement):
                  reverse: Optional[bool] = False,
                  reverse: Optional[bool] = False,
                  limits: Optional[Tuple[float, float]] = (0, 100),
                  limits: Optional[Tuple[float, float]] = (0, 100),
                  value: Optional[float] = 50,
                  value: Optional[float] = 50,
-                 on_change: Optional[Callable] = None) -> None:
+                 on_change: Optional[Callable[..., Any]] = None,
+                 ) -> None:
         """Splitter
         """Splitter
 
 
         The `ui.splitter` element divides the screen space into resizable sections, 
         The `ui.splitter` element divides the screen space into resizable sections, 

+ 2 - 2
nicegui/elements/switch.py

@@ -1,4 +1,4 @@
-from typing import Callable, Optional
+from typing import Any, Callable, Optional
 
 
 from .mixins.disableable_element import DisableableElement
 from .mixins.disableable_element import DisableableElement
 from .mixins.text_element import TextElement
 from .mixins.text_element import TextElement
@@ -7,7 +7,7 @@ from .mixins.value_element import ValueElement
 
 
 class Switch(TextElement, ValueElement, DisableableElement):
 class Switch(TextElement, ValueElement, DisableableElement):
 
 
-    def __init__(self, text: str = '', *, value: bool = False, on_change: Optional[Callable] = None) -> None:
+    def __init__(self, text: str = '', *, value: bool = False, on_change: Optional[Callable[..., Any]] = None) -> None:
         """Switch
         """Switch
 
 
         :param text: the label to display next to the switch
         :param text: the label to display next to the switch

+ 2 - 2
nicegui/elements/table.py

@@ -1,4 +1,4 @@
-from typing import Callable, Dict, List, Optional
+from typing import Any, Callable, Dict, List, Optional
 
 
 from typing_extensions import Literal
 from typing_extensions import Literal
 
 
@@ -16,7 +16,7 @@ class Table(FilterElement):
                  title: Optional[str] = None,
                  title: Optional[str] = None,
                  selection: Optional[Literal['single', 'multiple']] = None,
                  selection: Optional[Literal['single', 'multiple']] = None,
                  pagination: Optional[int] = None,
                  pagination: Optional[int] = None,
-                 on_select: Optional[Callable] = None,
+                 on_select: Optional[Callable[..., Any]] = None,
                  ) -> None:
                  ) -> None:
         """Table
         """Table
 
 

+ 3 - 2
nicegui/elements/tabs.py

@@ -9,7 +9,8 @@ class Tabs(ValueElement):
 
 
     def __init__(self, *,
     def __init__(self, *,
                  value: Any = None,
                  value: Any = None,
-                 on_change: Optional[Callable] = None) -> None:
+                 on_change: Optional[Callable[..., Any]] = None,
+                 ) -> None:
         """Tabs
         """Tabs
 
 
         This element represents `Quasar's QTabs <https://quasar.dev/vue-components/tabs#qtabs-api>`_ component.
         This element represents `Quasar's QTabs <https://quasar.dev/vue-components/tabs#qtabs-api>`_ component.
@@ -47,7 +48,7 @@ class TabPanels(ValueElement):
     def __init__(self,
     def __init__(self,
                  tabs: Tabs, *,
                  tabs: Tabs, *,
                  value: Any = None,
                  value: Any = None,
-                 on_change: Optional[Callable] = None,
+                 on_change: Optional[Callable[..., Any]] = None,
                  animated: bool = True,
                  animated: bool = True,
                  ) -> None:
                  ) -> None:
         """Tab Panels
         """Tab Panels

+ 4 - 3
nicegui/elements/textarea.py

@@ -1,4 +1,4 @@
-from typing import Callable, Dict, Optional
+from typing import Any, Callable, Dict, Optional
 
 
 from .input import Input
 from .input import Input
 
 
@@ -9,8 +9,9 @@ class Textarea(Input):
                  label: Optional[str] = None, *,
                  label: Optional[str] = None, *,
                  placeholder: Optional[str] = None,
                  placeholder: Optional[str] = None,
                  value: str = '',
                  value: str = '',
-                 on_change: Optional[Callable] = None,
-                 validation: Dict[str, Callable] = {}) -> None:
+                 on_change: Optional[Callable[..., Any]] = None,
+                 validation: Dict[str, Callable[..., bool]] = {},
+                 ) -> None:
         """Textarea
         """Textarea
 
 
         This element is based on Quasar's `QInput <https://quasar.dev/vue-components/input>`_ component.
         This element is based on Quasar's `QInput <https://quasar.dev/vue-components/input>`_ component.

+ 4 - 4
nicegui/elements/time.py

@@ -1,4 +1,4 @@
-from typing import Callable, Optional
+from typing import Any, Callable, Optional
 
 
 from .mixins.disableable_element import DisableableElement
 from .mixins.disableable_element import DisableableElement
 from .mixins.value_element import ValueElement
 from .mixins.value_element import ValueElement
@@ -7,10 +7,10 @@ from .mixins.value_element import ValueElement
 class Time(ValueElement, DisableableElement):
 class Time(ValueElement, DisableableElement):
 
 
     def __init__(self,
     def __init__(self,
-                 value: Optional[str] = None,
-                 *,
+                 value: Optional[str] = None, *,
                  mask: str = 'HH:mm',
                  mask: str = 'HH:mm',
-                 on_change: Optional[Callable] = None) -> None:
+                 on_change: Optional[Callable[..., Any]] = None,
+                 ) -> None:
         """Time Input
         """Time Input
 
 
         This element is based on Quasar's `QTime <https://quasar.dev/vue-components/date>`_ component.
         This element is based on Quasar's `QTime <https://quasar.dev/vue-components/date>`_ component.

+ 5 - 1
nicegui/elements/toggle.py

@@ -6,7 +6,11 @@ from .mixins.disableable_element import DisableableElement
 
 
 class Toggle(ChoiceElement, DisableableElement):
 class Toggle(ChoiceElement, DisableableElement):
 
 
-    def __init__(self, options: Union[List, Dict], *, value: Any = None, on_change: Optional[Callable] = None) -> None:
+    def __init__(self,
+                 options: Union[List, Dict], *,
+                 value: Any = None,
+                 on_change: Optional[Callable[..., Any]] = None,
+                 ) -> None:
         """Toggle
         """Toggle
 
 
         The options can be specified as a list of values, or as a dictionary mapping values to labels.
         The options can be specified as a list of values, or as a dictionary mapping values to labels.

+ 4 - 3
nicegui/elements/tree.py

@@ -11,9 +11,10 @@ class Tree(Element):
                  node_key: str = 'id',
                  node_key: str = 'id',
                  label_key: str = 'label',
                  label_key: str = 'label',
                  children_key: str = 'children',
                  children_key: str = 'children',
-                 on_select: Optional[Callable] = None,
-                 on_expand: Optional[Callable] = None,
-                 on_tick: Optional[Callable] = None) -> None:
+                 on_select: Optional[Callable[..., Any]] = None,
+                 on_expand: Optional[Callable[..., Any]] = None,
+                 on_tick: Optional[Callable[..., Any]] = None,
+                 ) -> None:
         """Tree
         """Tree
 
 
         Display hierarchical data using Quasar's `QTree <https://quasar.dev/vue-components/tree>`_ component.
         Display hierarchical data using Quasar's `QTree <https://quasar.dev/vue-components/tree>`_ component.

+ 3 - 3
nicegui/elements/upload.py

@@ -1,4 +1,4 @@
-from typing import Callable, Optional
+from typing import Any, Callable, Optional
 
 
 from fastapi import Request, Response
 from fastapi import Request, Response
 
 
@@ -17,8 +17,8 @@ class Upload(DisableableElement):
                  max_file_size: Optional[int] = None,
                  max_file_size: Optional[int] = None,
                  max_total_size: Optional[int] = None,
                  max_total_size: Optional[int] = None,
                  max_files: Optional[int] = None,
                  max_files: Optional[int] = None,
-                 on_upload: Optional[Callable] = None,
-                 on_rejected: Optional[Callable] = None,
+                 on_upload: Optional[Callable[..., Any]] = None,
+                 on_rejected: Optional[Callable[..., Any]] = None,
                  label: str = '',
                  label: str = '',
                  auto_upload: bool = False,
                  auto_upload: bool = False,
                  ) -> None:
                  ) -> None:

+ 1 - 1
nicegui/events.py

@@ -268,7 +268,7 @@ class KeyEventArguments(EventArguments):
     modifiers: KeyboardModifiers
     modifiers: KeyboardModifiers
 
 
 
 
-def handle_event(handler: Optional[Callable],
+def handle_event(handler: Optional[Callable[..., Any]],
                  arguments: Union[EventArguments, Dict], *,
                  arguments: Union[EventArguments, Dict], *,
                  sender: Optional['Element'] = None) -> None:
                  sender: Optional['Element'] = None) -> None:
     try:
     try:

+ 2 - 2
nicegui/functions/open.py

@@ -1,9 +1,9 @@
-from typing import Callable, Union
+from typing import Any, Callable, Union
 
 
 from .. import globals
 from .. import globals
 
 
 
 
-def open(target: Union[Callable, str]) -> None:
+def open(target: Union[Callable[..., Any], str]) -> None:
     """Open
     """Open
 
 
     Can be used to programmatically trigger redirects for a specific client.
     Can be used to programmatically trigger redirects for a specific client.

+ 1 - 1
nicegui/functions/refreshable.py

@@ -12,7 +12,7 @@ register_component('refreshable', __file__, 'refreshable.js')
 
 
 class refreshable:
 class refreshable:
 
 
-    def __init__(self, func: Callable) -> None:
+    def __init__(self, func: Callable[..., Any]) -> None:
         """Refreshable UI functions
         """Refreshable UI functions
 
 
         The `@ui.refreshable` decorator allows you to create functions that have a `refresh` method.
         The `@ui.refreshable` decorator allows you to create functions that have a `refresh` method.

+ 10 - 4
nicegui/functions/timer.py

@@ -1,6 +1,6 @@
 import asyncio
 import asyncio
 import time
 import time
-from typing import Callable
+from typing import Any, Callable
 
 
 from .. import background_tasks, globals
 from .. import background_tasks, globals
 from ..binding import BindableProperty
 from ..binding import BindableProperty
@@ -11,7 +11,12 @@ class Timer:
     active = BindableProperty()
     active = BindableProperty()
     interval = BindableProperty()
     interval = BindableProperty()
 
 
-    def __init__(self, interval: float, callback: Callable, *, active: bool = True, once: bool = False) -> None:
+    def __init__(self,
+                 interval: float,
+                 callback: Callable[..., Any], *,
+                 active: bool = True,
+                 once: bool = False,
+                 ) -> None:
         """Timer
         """Timer
 
 
         One major drive behind the creation of NiceGUI was the necessity to have a simple approach to update the interface in regular intervals,
         One major drive behind the creation of NiceGUI was the necessity to have a simple approach to update the interface in regular intervals,
@@ -78,10 +83,11 @@ class Timer:
             globals.handle_exception(e)
             globals.handle_exception(e)
 
 
     async def _connected(self, timeout: float = 60.0) -> bool:
     async def _connected(self, timeout: float = 60.0) -> bool:
-        '''Wait for the client connection before the timer callback can be allowed to manipulate the state.
+        """Wait for the client connection before the timer callback can be allowed to manipulate the state.
+
         See https://github.com/zauberzeug/nicegui/issues/206 for details.
         See https://github.com/zauberzeug/nicegui/issues/206 for details.
         Returns True if the client is connected, False if the client is not connected and the timer should be cancelled.
         Returns True if the client is connected, False if the client is not connected and the timer should be cancelled.
-        '''
+        """
         if self.slot.parent.client.shared:
         if self.slot.parent.client.shared:
             return True
             return True
         else:
         else:

+ 7 - 7
nicegui/globals.py

@@ -3,7 +3,7 @@ import inspect
 import logging
 import logging
 from contextlib import contextmanager
 from contextlib import contextmanager
 from enum import Enum
 from enum import Enum
-from typing import TYPE_CHECKING, Awaitable, Callable, Dict, List, Optional, Union
+from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, List, Optional, Union
 
 
 from socketio import AsyncServer
 from socketio import AsyncServer
 from uvicorn import Server
 from uvicorn import Server
@@ -48,13 +48,13 @@ slot_stacks: Dict[int, List['Slot']] = {}
 clients: Dict[str, 'Client'] = {}
 clients: Dict[str, 'Client'] = {}
 index_client: 'Client'
 index_client: 'Client'
 
 
-page_routes: Dict[Callable, str] = {}
+page_routes: Dict[Callable[..., Any], str] = {}
 
 
-startup_handlers: List[Union[Callable, Awaitable]] = []
-shutdown_handlers: List[Union[Callable, Awaitable]] = []
-connect_handlers: List[Union[Callable, Awaitable]] = []
-disconnect_handlers: List[Union[Callable, Awaitable]] = []
-exception_handlers: List[Callable] = [log.exception]
+startup_handlers: List[Union[Callable[..., Any], Awaitable]] = []
+shutdown_handlers: List[Union[Callable[..., Any], Awaitable]] = []
+connect_handlers: List[Union[Callable[..., Any], Awaitable]] = []
+disconnect_handlers: List[Union[Callable[..., Any], Awaitable]] = []
+exception_handlers: List[Callable[..., Any]] = [log.exception]
 
 
 
 
 def get_task_id() -> int:
 def get_task_id() -> int:

+ 1 - 1
nicegui/helpers.py

@@ -23,7 +23,7 @@ def is_coroutine(object: Any) -> bool:
     return asyncio.iscoroutinefunction(object)
     return asyncio.iscoroutinefunction(object)
 
 
 
 
-def safe_invoke(func: Union[Callable, Awaitable], client: Optional['Client'] = None) -> None:
+def safe_invoke(func: Union[Callable[..., Any], Awaitable], client: Optional['Client'] = None) -> None:
     try:
     try:
         if isinstance(func, Awaitable):
         if isinstance(func, Awaitable):
             async def func_with_client():
             async def func_with_client():

+ 2 - 2
nicegui/page.py

@@ -1,7 +1,7 @@
 import asyncio
 import asyncio
 import inspect
 import inspect
 import time
 import time
-from typing import Callable, Optional
+from typing import Any, Callable, Optional
 
 
 from fastapi import Request, Response
 from fastapi import Request, Response
 
 
@@ -62,7 +62,7 @@ class page:
     def resolve_language(self) -> Optional[str]:
     def resolve_language(self) -> Optional[str]:
         return self.language if self.language is not ... else globals.language
         return self.language if self.language is not ... else globals.language
 
 
-    def __call__(self, func: Callable) -> Callable:
+    def __call__(self, func: Callable[..., Any]) -> Callable[..., Any]:
         globals.app.remove_route(self.path)  # NOTE make sure only the latest route definition is used
         globals.app.remove_route(self.path)  # NOTE make sure only the latest route definition is used
         parameters_of_decorated_func = list(inspect.signature(func).parameters.keys())
         parameters_of_decorated_func = list(inspect.signature(func).parameters.keys())