فهرست منبع

moving auto-context code into sperate class

Rodja Trappe 2 سال پیش
والد
کامیت
7d3de3b505
6فایلهای تغییر یافته به همراه56 افزوده شده و 50 حذف شده
  1. 2 2
      api_docs_and_examples.py
  2. 43 0
      nicegui/auto_context.py
  3. 3 3
      nicegui/events.py
  4. 0 37
      nicegui/globals.py
  5. 6 6
      nicegui/page.py
  6. 2 2
      nicegui/timer.py

+ 2 - 2
api_docs_and_examples.py

@@ -5,7 +5,7 @@ from typing import Callable, Union
 
 import docutils.core
 
-from nicegui import globals, ui
+from nicegui import auto_context, globals, ui
 from nicegui.task_logger import create_task
 
 REGEX_H4 = re.compile(r'<h4.*?>(.*?)</h4>')
@@ -815,7 +815,7 @@ This will make `ui.plot` and `ui.line_plot` unavailable.
             ui.notify('Turning off that line plot to save resources on our live demo server. 😎')
         line_checkbox.value = msg.value
         if msg.value:
-            with globals.within_view(line_checkbox.view):
+            with auto_context.within_view(line_checkbox.view):
                 ui.timer(10.0, turn_off, once=True)
         line_checkbox.update()
         return False

+ 43 - 0
nicegui/auto_context.py

@@ -0,0 +1,43 @@
+import asyncio
+from contextlib import contextmanager
+from typing import TYPE_CHECKING, Awaitable, Callable, Dict, Generator, List, Optional, Union
+
+from . import globals
+from .task_logger import create_task
+
+
+def get_task_id() -> int:
+    return id(asyncio.current_task()) if globals.loop and globals.loop.is_running() else 0
+
+
+def get_view_stack() -> List['jp.HTMLBaseComponent']:
+    task_id = get_task_id()
+    if task_id not in globals.view_stacks:
+        globals.view_stacks[task_id] = []
+    return globals.view_stacks[task_id]
+
+
+def prune_view_stack() -> None:
+    task_id = get_task_id()
+    if not globals.view_stacks[task_id]:
+        del globals.view_stacks[task_id]
+
+
+class within_view(object):
+    def __init__(self, view: 'jp.HTMLBaseComponent'):
+        self.view = view
+
+    def __enter__(self):
+        self.child_count = len(self.view)
+        get_view_stack().append(self.view)
+        return self
+
+    def __exit__(self, type, value, traceback):
+        get_view_stack().pop()
+        prune_view_stack()
+        self.lazy_update()
+
+    def lazy_update(self):
+        if len(self.view) != self.child_count:
+            self.child_count = len(self.view)
+            create_task(self.view.update())

+ 3 - 3
nicegui/events.py

@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Any, Callable, List, Optional
 
 from starlette.websockets import WebSocket
 
-from . import globals
+from . import auto_context, globals
 from .helpers import is_coroutine
 from .lifecycle import on_startup
 from .task_logger import create_task
@@ -238,11 +238,11 @@ def handle_event(handler: Optional[Callable], arguments: EventArguments) -> Opti
         if handler is None:
             return False
         no_arguments = not signature(handler).parameters
-        with globals.within_view(arguments.sender.parent_view):
+        with auto_context.within_view(arguments.sender.parent_view):
             result = handler() if no_arguments else handler(arguments)
         if is_coroutine(handler):
             async def wait_for_result():
-                with globals.within_view(arguments.sender.parent_view):
+                with auto_context.within_view(arguments.sender.parent_view):
                     await result
             if globals.loop and globals.loop.is_running():
                 create_task(wait_for_result(), name=str(handler))

+ 0 - 37
nicegui/globals.py

@@ -45,40 +45,3 @@ def find_route(function: Callable) -> str:
     if not routes:
         raise ValueError(f'Invalid page function {function}')
     return routes[0]
-
-
-def get_task_id() -> int:
-    return id(asyncio.current_task()) if loop and loop.is_running() else 0
-
-
-def get_view_stack() -> List['jp.HTMLBaseComponent']:
-    task_id = get_task_id()
-    if task_id not in view_stacks:
-        view_stacks[task_id] = []
-    return view_stacks[task_id]
-
-
-def prune_view_stack() -> None:
-    task_id = get_task_id()
-    if not view_stacks[task_id]:
-        del view_stacks[task_id]
-
-
-class within_view(object):
-    def __init__(self, view: 'jp.HTMLBaseComponent'):
-        self.view = view
-
-    def __enter__(self):
-        self.child_count = len(self.view)
-        get_view_stack().append(self.view)
-        return self
-
-    def __exit__(self, type, value, traceback):
-        get_view_stack().pop()
-        prune_view_stack()
-        self.lazy_update()
-
-    def lazy_update(self):
-        if len(self.view) != self.child_count:
-            self.child_count = len(self.view)
-            create_task(self.view.update())

+ 6 - 6
nicegui/page.py

@@ -16,7 +16,7 @@ from starlette.responses import FileResponse
 from starlette.routing import Route, compile_path
 from starlette.websockets import WebSocket
 
-from . import globals
+from . import auto_context, globals
 from .events import PageEvent
 from .helpers import is_coroutine
 from .page_builder import PageBuilder
@@ -74,7 +74,7 @@ class Page(jp.QuasarPage):
             self.favicon = f'_favicon/{favicon}'
 
     async def _route_function(self, request: Request) -> Page:
-        with globals.within_view(self.view):
+        with auto_context.within_view(self.view):
             for handler in globals.connect_handlers + ([self.connect_handler] if self.connect_handler else []):
                 arg_count = len(inspect.signature(handler).parameters)
                 is_coro = is_coroutine(handler)
@@ -87,7 +87,7 @@ class Page(jp.QuasarPage):
         return self
 
     async def handle_page_ready(self, msg: AdDict) -> bool:
-        with globals.within_view(self.view) as context:
+        with auto_context.within_view(self.view) as context:
             try:
                 if self.page_ready_generator is not None:
                     if isinstance(self.page_ready_generator, types.AsyncGeneratorType):
@@ -113,7 +113,7 @@ class Page(jp.QuasarPage):
         return False
 
     async def on_disconnect(self, websocket: Optional[WebSocket] = None) -> None:
-        with globals.within_view(self.view):
+        with auto_context.within_view(self.view):
             for handler in globals.disconnect_handlers + ([self.disconnect_handler] if self.disconnect_handler else[]):
                 arg_count = len(inspect.signature(handler).parameters)
                 is_coro = is_coroutine(handler)
@@ -224,7 +224,7 @@ class page:
                 shared=self.shared,
             )
             try:
-                with globals.within_view(self.page.view):
+                with auto_context.within_view(self.page.view):
                     if 'request' in inspect.signature(func).parameters:
                         if self.shared:
                             raise RuntimeError('Cannot use `request` argument in shared page')
@@ -263,7 +263,7 @@ class page:
 
 
 def find_parent_view() -> jp.HTMLBaseComponent:
-    view_stack = globals.get_view_stack()
+    view_stack = auto_context.get_view_stack()
     if not view_stack:
         if globals.loop and globals.loop.is_running():
             raise RuntimeError('cannot find parent view, view stack is empty')

+ 2 - 2
nicegui/timer.py

@@ -6,7 +6,7 @@ from typing import Callable, List, Optional
 
 from starlette.websockets import WebSocket
 
-from . import globals
+from . import auto_context, globals
 from .binding import BindableProperty
 from .helpers import is_coroutine
 from .page import Page, find_parent_page, find_parent_view
@@ -41,7 +41,7 @@ class Timer:
 
         async def do_callback():
             try:
-                with globals.within_view(self.parent_view):
+                with auto_context.within_view(self.parent_view):
                     result = callback()
                     if is_coroutine(callback):
                         await result