Преглед изворни кода

remove and update deprecated APIs (#3648)

Falko Schindler пре 8 месеци
родитељ
комит
108035a986

+ 1 - 18
nicegui/client.py

@@ -181,11 +181,7 @@ class Client:
             await asyncio.sleep(check_interval)
             await asyncio.sleep(check_interval)
         self.is_waiting_for_disconnect = False
         self.is_waiting_for_disconnect = False
 
 
-    def run_javascript(self, code: str, *,
-                       respond: Optional[bool] = None,  # DEPRECATED
-                       timeout: float = 1.0,
-                       check_interval: float = 0.01,  # DEPRECATED
-                       ) -> AwaitableResponse:
+    def run_javascript(self, code: str, *, timeout: float = 1.0) -> AwaitableResponse:
         """Execute JavaScript on the client.
         """Execute JavaScript on the client.
 
 
         The client connection must be established before this method is called.
         The client connection must be established before this method is called.
@@ -199,19 +195,6 @@ class Client:
 
 
         :return: AwaitableResponse that can be awaited to get the result of the JavaScript code
         :return: AwaitableResponse that can be awaited to get the result of the JavaScript code
         """
         """
-        if respond is True:
-            helpers.warn_once('The "respond" argument of run_javascript() has been removed. '
-                              'Now the method always returns an AwaitableResponse that can be awaited. '
-                              'Please remove the "respond=True" argument.')
-        if respond is False:
-            raise ValueError('The "respond" argument of run_javascript() has been removed. '
-                             'Now the method always returns an AwaitableResponse that can be awaited. '
-                             'Please remove the "respond=False" argument and call the method without awaiting.')
-        if check_interval != 0.01:
-            helpers.warn_once('The "check_interval" argument of run_javascript() and similar methods has been removed. '
-                              'Now the method automatically returns when receiving a response without checking regularly in an interval. '
-                              'Please remove the "check_interval" argument.')
-
         request_id = str(uuid.uuid4())
         request_id = str(uuid.uuid4())
         target_id = self._temporary_socket_id or self.id
         target_id = self._temporary_socket_id or self.id
 
 

+ 0 - 16
nicegui/context.py

@@ -2,7 +2,6 @@ from __future__ import annotations
 
 
 from typing import TYPE_CHECKING, List
 from typing import TYPE_CHECKING, List
 
 
-from . import helpers
 from .slot import Slot
 from .slot import Slot
 
 
 if TYPE_CHECKING:
 if TYPE_CHECKING:
@@ -11,21 +10,6 @@ if TYPE_CHECKING:
 
 
 class Context:
 class Context:
 
 
-    def get_slot_stack(self) -> List[Slot]:
-        """Return the slot stack of the current asyncio task. (DEPRECATED, use context.slot_stack instead)"""
-        helpers.warn_once('context.get_slot_stack() is deprecated, use context.slot_stack instead')
-        return self.slot_stack
-
-    def get_slot(self) -> Slot:
-        """Return the current slot. (DEPRECATED, use context.slot instead)"""
-        helpers.warn_once('context.get_slot() is deprecated, use context.slot instead')
-        return self.slot
-
-    def get_client(self) -> Client:
-        """Return the current client. (DEPRECATED, use context.client instead)"""
-        helpers.warn_once('context.get_client() is deprecated, use context.client instead')
-        return self.client
-
     @property
     @property
     def slot_stack(self) -> List[Slot]:
     def slot_stack(self) -> List[Slot]:
         """Return the slot stack of the current asyncio task."""
         """Return the slot stack of the current asyncio task."""

+ 5 - 3
nicegui/element.py

@@ -109,12 +109,15 @@ class Element(Visibility):
 
 
         if libraries:
         if libraries:
             helpers.warn_once(f'The `libraries` parameter for subclassing "{cls.__name__}" is deprecated. '
             helpers.warn_once(f'The `libraries` parameter for subclassing "{cls.__name__}" is deprecated. '
+                              'It will be removed in NiceGUI 3.0. '
                               'Use `dependencies` instead.')
                               'Use `dependencies` instead.')
         if exposed_libraries:
         if exposed_libraries:
             helpers.warn_once(f'The `exposed_libraries` parameter for subclassing "{cls.__name__}" is deprecated. '
             helpers.warn_once(f'The `exposed_libraries` parameter for subclassing "{cls.__name__}" is deprecated. '
+                              'It will be removed in NiceGUI 3.0. '
                               'Use `dependencies` instead.')
                               'Use `dependencies` instead.')
         if extra_libraries:
         if extra_libraries:
             helpers.warn_once(f'The `extra_libraries` parameter for subclassing "{cls.__name__}" is deprecated. '
             helpers.warn_once(f'The `extra_libraries` parameter for subclassing "{cls.__name__}" is deprecated. '
+                              'It will be removed in NiceGUI 3.0. '
                               'Use `dependencies` instead.')
                               'Use `dependencies` instead.')
 
 
         cls.component = copy(cls.component)
         cls.component = copy(cls.component)
@@ -391,7 +394,7 @@ class Element(Visibility):
             return
             return
         self.client.outbox.enqueue_update(self)
         self.client.outbox.enqueue_update(self)
 
 
-    def run_method(self, name: str, *args: Any, timeout: float = 1, check_interval: float = 0.01) -> AwaitableResponse:
+    def run_method(self, name: str, *args: Any, timeout: float = 1) -> AwaitableResponse:
         """Run a method on the client side.
         """Run a method on the client side.
 
 
         If the function is awaited, the result of the method call is returned.
         If the function is awaited, the result of the method call is returned.
@@ -403,8 +406,7 @@ class Element(Visibility):
         """
         """
         if not core.loop:
         if not core.loop:
             return NullResponse()
             return NullResponse()
-        return self.client.run_javascript(f'return runMethod({self.id}, "{name}", {json.dumps(args)})',
-                                          timeout=timeout, check_interval=check_interval)
+        return self.client.run_javascript(f'return runMethod({self.id}, "{name}", {json.dumps(args)})', timeout=timeout)
 
 
     def get_computed_prop(self, prop_name: str, *, timeout: float = 1) -> AwaitableResponse:
     def get_computed_prop(self, prop_name: str, *, timeout: float = 1) -> AwaitableResponse:
         """Return a computed property.
         """Return a computed property.

+ 7 - 19
nicegui/elements/aggrid.py

@@ -92,11 +92,7 @@ class AgGrid(Element, component='aggrid.js', dependencies=['lib/aggrid/ag-grid-c
         super().update()
         super().update()
         self.run_method('update_grid')
         self.run_method('update_grid')
 
 
-    def call_api_method(self, name: str, *args, timeout: float = 1, check_interval: float = 0.01) -> AwaitableResponse:
-        """DEPRECATED: Use `run_grid_method` instead."""
-        return self.run_grid_method(name, *args, timeout=timeout, check_interval=check_interval)
-
-    def run_grid_method(self, name: str, *args, timeout: float = 1, check_interval: float = 0.01) -> AwaitableResponse:
+    def run_grid_method(self, name: str, *args, timeout: float = 1) -> AwaitableResponse:
         """Run an AG Grid API method.
         """Run an AG Grid API method.
 
 
         See `AG Grid API <https://www.ag-grid.com/javascript-data-grid/grid-api/>`_ for a list of methods.
         See `AG Grid API <https://www.ag-grid.com/javascript-data-grid/grid-api/>`_ for a list of methods.
@@ -110,14 +106,9 @@ class AgGrid(Element, component='aggrid.js', dependencies=['lib/aggrid/ag-grid-c
 
 
         :return: AwaitableResponse that can be awaited to get the result of the method call
         :return: AwaitableResponse that can be awaited to get the result of the method call
         """
         """
-        return self.run_method('run_grid_method', name, *args, timeout=timeout, check_interval=check_interval)
-
-    def call_column_method(self, name: str, *args, timeout: float = 1, check_interval: float = 0.01) -> AwaitableResponse:
-        """DEPRECATED: Use `run_column_method` instead."""
-        return self.run_column_method(name, *args, timeout=timeout, check_interval=check_interval)
+        return self.run_method('run_grid_method', name, *args, timeout=timeout)
 
 
-    def run_column_method(self, name: str, *args,
-                          timeout: float = 1, check_interval: float = 0.01) -> AwaitableResponse:
+    def run_column_method(self, name: str, *args, timeout: float = 1) -> AwaitableResponse:
         """Run an AG Grid Column API method.
         """Run an AG Grid Column API method.
 
 
         See `AG Grid Column API <https://www.ag-grid.com/javascript-data-grid/column-api/>`_ for a list of methods.
         See `AG Grid Column API <https://www.ag-grid.com/javascript-data-grid/column-api/>`_ for a list of methods.
@@ -131,10 +122,9 @@ class AgGrid(Element, component='aggrid.js', dependencies=['lib/aggrid/ag-grid-c
 
 
         :return: AwaitableResponse that can be awaited to get the result of the method call
         :return: AwaitableResponse that can be awaited to get the result of the method call
         """
         """
-        return self.run_method('run_column_method', name, *args, timeout=timeout, check_interval=check_interval)
+        return self.run_method('run_column_method', name, *args, timeout=timeout)
 
 
-    def run_row_method(self, row_id: str, name: str, *args,
-                       timeout: float = 1, check_interval: float = 0.01) -> AwaitableResponse:
+    def run_row_method(self, row_id: str, name: str, *args, timeout: float = 1) -> AwaitableResponse:
         """Run an AG Grid API method on a specific row.
         """Run an AG Grid API method on a specific row.
 
 
         See `AG Grid Row Reference <https://www.ag-grid.com/javascript-data-grid/row-object/>`_ for a list of methods.
         See `AG Grid Row Reference <https://www.ag-grid.com/javascript-data-grid/row-object/>`_ for a list of methods.
@@ -149,7 +139,7 @@ class AgGrid(Element, component='aggrid.js', dependencies=['lib/aggrid/ag-grid-c
 
 
         :return: AwaitableResponse that can be awaited to get the result of the method call
         :return: AwaitableResponse that can be awaited to get the result of the method call
         """
         """
-        return self.run_method('run_row_method', row_id, name, *args, timeout=timeout, check_interval=check_interval)
+        return self.run_method('run_row_method', row_id, name, *args, timeout=timeout)
 
 
     async def get_selected_rows(self) -> List[Dict]:
     async def get_selected_rows(self) -> List[Dict]:
         """Get the currently selected rows.
         """Get the currently selected rows.
@@ -177,7 +167,6 @@ class AgGrid(Element, component='aggrid.js', dependencies=['lib/aggrid/ag-grid-c
         self,
         self,
         *,
         *,
         timeout: float = 1,
         timeout: float = 1,
-        check_interval: float = 0.01,
         method: Literal['all_unsorted', 'filtered_unsorted', 'filtered_sorted', 'leaf'] = 'all_unsorted'
         method: Literal['all_unsorted', 'filtered_unsorted', 'filtered_sorted', 'leaf'] = 'all_unsorted'
     ) -> List[Dict]:
     ) -> List[Dict]:
         """Get the data from the client including any edits made by the client.
         """Get the data from the client including any edits made by the client.
@@ -190,7 +179,6 @@ class AgGrid(Element, component='aggrid.js', dependencies=['lib/aggrid/ag-grid-c
         This does not happen when the cell loses focus, unless ``stopEditingWhenCellsLoseFocus: True`` is set.
         This does not happen when the cell loses focus, unless ``stopEditingWhenCellsLoseFocus: True`` is set.
 
 
         :param timeout: timeout in seconds (default: 1 second)
         :param timeout: timeout in seconds (default: 1 second)
-        :param check_interval: interval in seconds to check for the result (default: 0.01 seconds)
         :param method: method to access the data, "all_unsorted" (default), "filtered_unsorted", "filtered_sorted", "leaf"
         :param method: method to access the data, "all_unsorted" (default), "filtered_unsorted", "filtered_sorted", "leaf"
 
 
         :return: list of row data
         :return: list of row data
@@ -205,7 +193,7 @@ class AgGrid(Element, component='aggrid.js', dependencies=['lib/aggrid/ag-grid-c
             const rowData = [];
             const rowData = [];
             getElement({self.id}).gridOptions.api.{API_METHODS[method]}(node => rowData.push(node.data));
             getElement({self.id}).gridOptions.api.{API_METHODS[method]}(node => rowData.push(node.data));
             return rowData;
             return rowData;
-        ''', timeout=timeout, check_interval=check_interval)
+        ''', timeout=timeout)
         return cast(List[Dict], result)
         return cast(List[Dict], result)
 
 
     async def load_client_data(self) -> None:
     async def load_client_data(self) -> None:

+ 0 - 5
nicegui/elements/chart.py

@@ -1,5 +0,0 @@
-def chart(*args, **kwargs) -> None:
-    """Deprecated. Please use `ui.highchart` instead."""
-    # DEPRECATED
-    raise RuntimeError('`ui.chart` is now `ui.highchart`. '
-                       'Please install `nicegui[highcharts]` and use `ui.highchart` instead.')

+ 2 - 3
nicegui/elements/echart.py

@@ -99,8 +99,7 @@ class EChart(Element, component='echart.js', dependencies=['lib/echarts/echarts.
         super().update()
         super().update()
         self.run_method('update_chart')
         self.run_method('update_chart')
 
 
-    def run_chart_method(self, name: str, *args, timeout: float = 1,
-                         check_interval: float = 0.01) -> AwaitableResponse:
+    def run_chart_method(self, name: str, *args, timeout: float = 1) -> AwaitableResponse:
         """Run a method of the JSONEditor instance.
         """Run a method of the JSONEditor instance.
 
 
         See the `ECharts documentation <https://echarts.apache.org/en/api.html#echartsInstance>`_ for a list of methods.
         See the `ECharts documentation <https://echarts.apache.org/en/api.html#echartsInstance>`_ for a list of methods.
@@ -114,4 +113,4 @@ class EChart(Element, component='echart.js', dependencies=['lib/echarts/echarts.
 
 
         :return: AwaitableResponse that can be awaited to get the result of the method call
         :return: AwaitableResponse that can be awaited to get the result of the method call
         """
         """
-        return self.run_method('run_chart_method', name, *args, timeout=timeout, check_interval=check_interval)
+        return self.run_method('run_chart_method', name, *args, timeout=timeout)

+ 2 - 3
nicegui/elements/json_editor.py

@@ -56,8 +56,7 @@ class JsonEditor(Element, component='json_editor.js', dependencies=['lib/vanilla
         super().update()
         super().update()
         self.run_method('update_editor')
         self.run_method('update_editor')
 
 
-    def run_editor_method(self, name: str, *args, timeout: float = 1,
-                          check_interval: float = 0.01) -> AwaitableResponse:
+    def run_editor_method(self, name: str, *args, timeout: float = 1) -> AwaitableResponse:
         """Run a method of the JSONEditor instance.
         """Run a method of the JSONEditor instance.
 
 
         See the `JSONEditor README <https://github.com/josdejong/svelte-jsoneditor/>`_ for a list of methods.
         See the `JSONEditor README <https://github.com/josdejong/svelte-jsoneditor/>`_ for a list of methods.
@@ -71,4 +70,4 @@ class JsonEditor(Element, component='json_editor.js', dependencies=['lib/vanilla
 
 
         :return: AwaitableResponse that can be awaited to get the result of the method call
         :return: AwaitableResponse that can be awaited to get the result of the method call
         """
         """
-        return self.run_method('run_editor_method', name, *args, timeout=timeout, check_interval=check_interval)
+        return self.run_method('run_editor_method', name, *args, timeout=timeout)

+ 6 - 6
nicegui/elements/leaflet.py

@@ -93,10 +93,10 @@ class Leaflet(Element, component='leaflet.js'):
         await asyncio.sleep(0.02)  # NOTE: wait for center to be updated as well
         await asyncio.sleep(0.02)  # NOTE: wait for center to be updated as well
         self.zoom = e.args['zoom']
         self.zoom = e.args['zoom']
 
 
-    def run_method(self, name: str, *args: Any, timeout: float = 1, check_interval: float = 0.01) -> AwaitableResponse:
+    def run_method(self, name: str, *args: Any, timeout: float = 1) -> AwaitableResponse:
         if not self.is_initialized:
         if not self.is_initialized:
             return NullResponse()
             return NullResponse()
-        return super().run_method(name, *args, timeout=timeout, check_interval=check_interval)
+        return super().run_method(name, *args, timeout=timeout)
 
 
     def set_center(self, center: Tuple[float, float]) -> None:
     def set_center(self, center: Tuple[float, float]) -> None:
         """Set the center location of the map."""
         """Set the center location of the map."""
@@ -122,7 +122,7 @@ class Leaflet(Element, component='leaflet.js'):
         self.layers.clear()
         self.layers.clear()
         self.run_method('clear_layers')
         self.run_method('clear_layers')
 
 
-    def run_map_method(self, name: str, *args, timeout: float = 1, check_interval: float = 0.01) -> AwaitableResponse:
+    def run_map_method(self, name: str, *args, timeout: float = 1) -> AwaitableResponse:
         """Run a method of the Leaflet map instance.
         """Run a method of the Leaflet map instance.
 
 
         Refer to the `Leaflet documentation <https://leafletjs.com/reference.html#map-methods-for-modifying-map-state>`_ for a list of methods.
         Refer to the `Leaflet documentation <https://leafletjs.com/reference.html#map-methods-for-modifying-map-state>`_ for a list of methods.
@@ -136,9 +136,9 @@ class Leaflet(Element, component='leaflet.js'):
 
 
         :return: AwaitableResponse that can be awaited to get the result of the method call
         :return: AwaitableResponse that can be awaited to get the result of the method call
         """
         """
-        return self.run_method('run_map_method', name, *args, timeout=timeout, check_interval=check_interval)
+        return self.run_method('run_map_method', name, *args, timeout=timeout)
 
 
-    def run_layer_method(self, layer_id: str, name: str, *args, timeout: float = 1, check_interval: float = 0.01) -> AwaitableResponse:
+    def run_layer_method(self, layer_id: str, name: str, *args, timeout: float = 1) -> AwaitableResponse:
         """Run a method of a Leaflet layer.
         """Run a method of a Leaflet layer.
 
 
         If the function is awaited, the result of the method call is returned.
         If the function is awaited, the result of the method call is returned.
@@ -151,7 +151,7 @@ class Leaflet(Element, component='leaflet.js'):
 
 
         :return: AwaitableResponse that can be awaited to get the result of the method call
         :return: AwaitableResponse that can be awaited to get the result of the method call
         """
         """
-        return self.run_method('run_layer_method', layer_id, name, *args, timeout=timeout, check_interval=check_interval)
+        return self.run_method('run_layer_method', layer_id, name, *args, timeout=timeout)
 
 
     def _handle_delete(self) -> None:
     def _handle_delete(self) -> None:
         binding.remove(self.layers)
         binding.remove(self.layers)

+ 2 - 2
nicegui/elements/leaflet_layer.py

@@ -29,7 +29,7 @@ class Layer:
     def to_dict(self) -> dict:
     def to_dict(self) -> dict:
         """Return a dictionary representation of the layer."""
         """Return a dictionary representation of the layer."""
 
 
-    def run_method(self, name: str, *args: Any, timeout: float = 1, check_interval: float = 0.01) -> AwaitableResponse:
+    def run_method(self, name: str, *args: Any, timeout: float = 1) -> AwaitableResponse:
         """Run a method of the Leaflet layer.
         """Run a method of the Leaflet layer.
 
 
         If the function is awaited, the result of the method call is returned.
         If the function is awaited, the result of the method call is returned.
@@ -41,4 +41,4 @@ class Layer:
 
 
         :return: AwaitableResponse that can be awaited to get the result of the method call
         :return: AwaitableResponse that can be awaited to get the result of the method call
         """
         """
-        return self.leaflet.run_method('run_layer_method', self.id, name, *args, timeout=timeout, check_interval=check_interval)
+        return self.leaflet.run_method('run_layer_method', self.id, name, *args, timeout=timeout)

+ 2 - 0
nicegui/elements/table.py

@@ -272,6 +272,7 @@ class Table(FilterElement, component='table.js'):
         """Add rows to the table."""
         """Add rows to the table."""
         if isinstance(rows, dict):  # DEPRECATED
         if isinstance(rows, dict):  # DEPRECATED
             warn_once('Calling add_rows() with variable-length arguments is deprecated. '
             warn_once('Calling add_rows() with variable-length arguments is deprecated. '
+                      'This option will be removed in NiceGUI 3.0. '
                       'Pass a list instead or use add_row() for a single row.')
                       'Pass a list instead or use add_row() for a single row.')
             rows = [rows, *args]
             rows = [rows, *args]
         self.rows.extend(rows)
         self.rows.extend(rows)
@@ -285,6 +286,7 @@ class Table(FilterElement, component='table.js'):
         """Remove rows from the table."""
         """Remove rows from the table."""
         if isinstance(rows, dict):  # DEPRECATED
         if isinstance(rows, dict):  # DEPRECATED
             warn_once('Calling remove_rows() with variable-length arguments is deprecated. '
             warn_once('Calling remove_rows() with variable-length arguments is deprecated. '
+                      'This option will be removed in NiceGUI 3.0. '
                       'Pass a list instead or use remove_row() for a single row.')
                       'Pass a list instead or use remove_row() for a single row.')
             rows = [rows, *args]
             rows = [rows, *args]
         keys = [row[self.row_key] for row in rows]
         keys = [row[self.row_key] for row in rows]

+ 2 - 6
nicegui/functions/javascript.py

@@ -1,12 +1,8 @@
-from typing import Optional
-
 from ..awaitable_response import AwaitableResponse
 from ..awaitable_response import AwaitableResponse
 from ..context import context
 from ..context import context
 
 
 
 
-def run_javascript(code: str, *,
-                   respond: Optional[bool] = None,
-                   timeout: float = 1.0, check_interval: float = 0.01) -> AwaitableResponse:
+def run_javascript(code: str, *, timeout: float = 1.0) -> AwaitableResponse:
     """Run JavaScript
     """Run JavaScript
 
 
     This function runs arbitrary JavaScript code on a page that is executed in the browser.
     This function runs arbitrary JavaScript code on a page that is executed in the browser.
@@ -23,4 +19,4 @@ def run_javascript(code: str, *,
 
 
     :return: AwaitableResponse that can be awaited to get the result of the JavaScript code
     :return: AwaitableResponse that can be awaited to get the result of the JavaScript code
     """
     """
-    return context.client.run_javascript(code, respond=respond, timeout=timeout, check_interval=check_interval)
+    return context.client.run_javascript(code, timeout=timeout)

+ 0 - 9
nicegui/functions/open.py

@@ -1,9 +0,0 @@
-from typing import Any, Callable, Union
-
-from ..element import Element
-from .navigate import navigate
-
-
-def open(target: Union[Callable[..., Any], str, Element], new_tab: bool = False) -> None:  # pylint: disable=redefined-builtin
-    """DEPRECATED: use `ui.navigate.to` instead"""
-    navigate.to(target, new_tab)

+ 0 - 16
nicegui/functions/style.py

@@ -13,22 +13,6 @@ from .. import helpers
 from .html import add_head_html
 from .html import add_head_html
 
 
 
 
-def add_style(content: Union[str, Path], indented: bool = False) -> None:  # DEPRECATED
-    """Add style definitions to the page. [DEPRECATED]
-
-    Note:
-    This function is deprecated, because it can't reliably detect the style language.
-    Use `add_css`, `add_scss` or `add_sass` instead.
-    """
-    if helpers.is_file(content):
-        content = Path(content).read_text()
-    if optional_features.has('sass'):
-        content = sass.compile(string=str(content).strip(), indented=indented)
-    helpers.warn_once("`ui.add_style` is deprecated, because it can't reliably detect the style language. "
-                      'Use `ui.add_css`, `ui.add_scss` or `ui.add_sass` instead.')
-    add_head_html(f'<style>{content}</style>')
-
-
 def add_css(content: Union[str, Path]) -> None:
 def add_css(content: Union[str, Path]) -> None:
     """Add CSS style definitions to the page.
     """Add CSS style definitions to the page.
 
 

+ 12 - 4
nicegui/page_layout.py

@@ -4,7 +4,6 @@ from .context import context
 from .element import Element
 from .element import Element
 from .elements.mixins.value_element import ValueElement
 from .elements.mixins.value_element import ValueElement
 from .functions.html import add_body_html
 from .functions.html import add_body_html
-from .logging import log
 
 
 DrawerSides = Literal['left', 'right']
 DrawerSides = Literal['left', 'right']
 
 
@@ -34,6 +33,8 @@ class Header(ValueElement):
 
 
         This element is based on Quasar's `QHeader <https://quasar.dev/layout/header-and-footer#qheader-api>`_ component.
         This element is based on Quasar's `QHeader <https://quasar.dev/layout/header-and-footer#qheader-api>`_ component.
 
 
+        Like other layout elements, the header can not be nested inside other elements.
+
         Note: The header is automatically placed above other layout elements in the DOM to improve accessibility.
         Note: The header is automatically placed above other layout elements in the DOM to improve accessibility.
         To change the order, use the `move` method.
         To change the order, use the `move` method.
 
 
@@ -97,6 +98,8 @@ class Drawer(Element):
 
 
         This element is based on Quasar's `QDrawer <https://quasar.dev/layout/drawer>`_ component.
         This element is based on Quasar's `QDrawer <https://quasar.dev/layout/drawer>`_ component.
 
 
+        Like other layout elements, a drawer can not be nested inside other elements.
+
         Note: Depending on the side, the drawer is automatically placed above or below the main page container in the DOM to improve accessibility.
         Note: Depending on the side, the drawer is automatically placed above or below the main page container in the DOM to improve accessibility.
         To change the order, use the `move` method.
         To change the order, use the `move` method.
 
 
@@ -154,6 +157,8 @@ class LeftDrawer(Drawer):
 
 
         This element is based on Quasar's `QDrawer <https://quasar.dev/layout/drawer>`_ component.
         This element is based on Quasar's `QDrawer <https://quasar.dev/layout/drawer>`_ component.
 
 
+        Like other layout elements, the left drawer can not be nested inside other elements.
+
         Note: The left drawer is automatically placed above the main page container in the DOM to improve accessibility.
         Note: The left drawer is automatically placed above the main page container in the DOM to improve accessibility.
         To change the order, use the `move` method.
         To change the order, use the `move` method.
 
 
@@ -186,6 +191,8 @@ class RightDrawer(Drawer):
 
 
         This element is based on Quasar's `QDrawer <https://quasar.dev/layout/drawer>`_ component.
         This element is based on Quasar's `QDrawer <https://quasar.dev/layout/drawer>`_ component.
 
 
+        Like other layout elements, the right drawer can not be nested inside other elements.
+
         Note: The right drawer is automatically placed below the main page container in the DOM to improve accessibility.
         Note: The right drawer is automatically placed below the main page container in the DOM to improve accessibility.
         To change the order, use the `move` method.
         To change the order, use the `move` method.
 
 
@@ -218,6 +225,8 @@ class Footer(ValueElement):
 
 
         This element is based on Quasar's `QFooter <https://quasar.dev/layout/header-and-footer#qfooter-api>`_ component.
         This element is based on Quasar's `QFooter <https://quasar.dev/layout/header-and-footer#qfooter-api>`_ component.
 
 
+        Like other layout elements, the footer can not be nested inside other elements.
+
         Note: The footer is automatically placed below other layout elements in the DOM to improve accessibility.
         Note: The footer is automatically placed below other layout elements in the DOM to improve accessibility.
         To change the order, use the `move` method.
         To change the order, use the `move` method.
 
 
@@ -273,6 +282,5 @@ class PageSticky(Element):
 def _check_current_slot(element: Element) -> None:
 def _check_current_slot(element: Element) -> None:
     parent = context.slot.parent
     parent = context.slot.parent
     if parent != parent.client.content:
     if parent != parent.client.content:
-        log.warning(f'Found top level layout element "{element.__class__.__name__}" inside element "{parent.__class__.__name__}". '
-                    'Top level layout elements should not be nested but must be direct children of the page content. '
-                    'This will be raising an exception in NiceGUI 1.5')  # DEPRECATED
+        raise RuntimeError(f'Found top level layout element "{element.__class__.__name__}" inside element "{parent.__class__.__name__}". '
+                           'Top level layout elements can not be nested but must be direct children of the page content.')

+ 0 - 16
nicegui/storage.py

@@ -104,7 +104,6 @@ class Storage:
 
 
     def __init__(self) -> None:
     def __init__(self) -> None:
         self.path = Path(os.environ.get('NICEGUI_STORAGE_PATH', '.nicegui')).resolve()
         self.path = Path(os.environ.get('NICEGUI_STORAGE_PATH', '.nicegui')).resolve()
-        self.migrate_to_utf8()  # DEPRECATED: remove this in 2.0 release
         self.max_tab_storage_age = timedelta(days=30).total_seconds()
         self.max_tab_storage_age = timedelta(days=30).total_seconds()
         self._general = PersistentDict(self.path / 'storage-general.json', encoding='utf-8')
         self._general = PersistentDict(self.path / 'storage-general.json', encoding='utf-8')
         self._users: Dict[str, PersistentDict] = {}
         self._users: Dict[str, PersistentDict] = {}
@@ -213,18 +212,3 @@ class Storage:
         self._tabs.clear()
         self._tabs.clear()
         for filepath in self.path.glob('storage-*.json'):
         for filepath in self.path.glob('storage-*.json'):
             filepath.unlink()
             filepath.unlink()
-
-    def migrate_to_utf8(self) -> None:
-        """Migrates storage files from system's default encoding to UTF-8.
-
-        To distinguish between the old and new encoding, the new files are named with dashes instead of underscores.
-        """
-        for filepath in self.path.glob('storage_*.json'):
-            new_filepath = filepath.with_name(filepath.name.replace('_', '-'))
-            try:
-                data = json.loads(filepath.read_text())
-            except Exception:
-                log.warning(f'Could not load storage file {filepath}')
-                data = {}
-            filepath.rename(new_filepath)
-            new_filepath.write_text(json.dumps(data), encoding='utf-8')

+ 1 - 0
nicegui/testing/conftest.py

@@ -4,4 +4,5 @@ from .plugin import *  # pylint: disable=wildcard-import,unused-wildcard-import
 
 
 # DEPRECATED
 # DEPRECATED
 warnings.warn('Importing from nicegui.testing.conftest is deprecated. '
 warnings.warn('Importing from nicegui.testing.conftest is deprecated. '
+              'It will be removed in NiceGUI 3.0. '
               'Use pytest_plugins = ["nicegui.testing.plugin"] instead.', DeprecationWarning, stacklevel=-1)
               'Use pytest_plugins = ["nicegui.testing.plugin"] instead.', DeprecationWarning, stacklevel=-1)

+ 1 - 6
nicegui/ui.py

@@ -11,7 +11,6 @@ __all__ = [
     'card_section',
     'card_section',
     'carousel',
     'carousel',
     'carousel_slide',
     'carousel_slide',
-    'chart',
     'chat_message',
     'chat_message',
     'checkbox',
     'checkbox',
     'chip',
     'chip',
@@ -105,7 +104,6 @@ __all__ = [
     'add_head_html',
     'add_head_html',
     'run_javascript',
     'run_javascript',
     'notify',
     'notify',
-    'open',
     'page_title',
     'page_title',
     'refreshable',
     'refreshable',
     'refreshable_method',
     'refreshable_method',
@@ -113,7 +111,6 @@ __all__ = [
     'add_css',
     'add_css',
     'add_sass',
     'add_sass',
     'add_scss',
     'add_scss',
-    'add_style',
     'update',
     'update',
     'page',
     'page',
     'drawer',
     'drawer',
@@ -141,7 +138,6 @@ from .elements.card import CardActions as card_actions
 from .elements.card import CardSection as card_section
 from .elements.card import CardSection as card_section
 from .elements.carousel import Carousel as carousel
 from .elements.carousel import Carousel as carousel
 from .elements.carousel import CarouselSlide as carousel_slide
 from .elements.carousel import CarouselSlide as carousel_slide
-from .elements.chart import chart
 from .elements.chat_message import ChatMessage as chat_message
 from .elements.chat_message import ChatMessage as chat_message
 from .elements.checkbox import Checkbox as checkbox
 from .elements.checkbox import Checkbox as checkbox
 from .elements.chip import Chip as chip
 from .elements.chip import Chip as chip
@@ -233,10 +229,9 @@ from .functions.javascript import run_javascript
 from .functions.navigate import navigate
 from .functions.navigate import navigate
 from .functions.notify import notify
 from .functions.notify import notify
 from .functions.on import on
 from .functions.on import on
-from .functions.open import open  # pylint: disable=redefined-builtin
 from .functions.page_title import page_title
 from .functions.page_title import page_title
 from .functions.refreshable import refreshable, refreshable_method, state
 from .functions.refreshable import refreshable, refreshable_method, state
-from .functions.style import add_css, add_sass, add_scss, add_style
+from .functions.style import add_css, add_sass, add_scss
 from .functions.update import update
 from .functions.update import update
 from .page import page
 from .page import page
 from .page_layout import Drawer as drawer
 from .page_layout import Drawer as drawer