diff --git a/panel/param.py b/panel/param.py index 4129a18ef8..a180b5dade 100644 --- a/panel/param.py +++ b/panel/param.py @@ -775,7 +775,8 @@ def __init__(self, object=None, **params): self._link_object_params() if object is not None: self._validate_object() - self._replace_pane() + if not self.defer_load: + self._replace_pane() @param.depends('object', watch=True) def _validate_object(self): diff --git a/panel/tests/conftest.py b/panel/tests/conftest.py index a20da0c56a..da56bca0e7 100644 --- a/panel/tests/conftest.py +++ b/panel/tests/conftest.py @@ -312,6 +312,7 @@ def server_cleanup(): state._locations.clear() state._templates.clear() state._views.clear() + state._loaded.clear() state.cache.clear() state._scheduled.clear() if state._thread_pool is not None: diff --git a/panel/tests/test_param.py b/panel/tests/test_param.py index 171c7e65cf..a3479fa80e 100644 --- a/panel/tests/test_param.py +++ b/panel/tests/test_param.py @@ -10,9 +10,10 @@ TextInput as BkTextInput, Toggle, ) +from panel.io.state import set_curdoc, state from panel.layout import Row, Tabs from panel.pane import ( - HTML, Bokeh, Matplotlib, Pane, PaneBase, panel, + HTML, Bokeh, Matplotlib, Pane, PaneBase, Str, panel, ) from panel.param import ( JSONInit, Param, ParamFunction, ParamMethod, @@ -1055,6 +1056,42 @@ def view(a): assert inner_pane._models == {} +def test_param_function_pane_defer_load(document, comm): + test = View() + + @param.depends(test.param.a) + def view(a): + return Div(text='%d' % a) + + pane = panel(view, defer_load=True) + inner_pane = pane._pane + assert isinstance(inner_pane, Str) + + # Ensure pane thinks page is not loaded + state._loaded[document] = False + + # Create pane + with set_curdoc(document): + row = pane.get_root(document, comm=comm) + assert isinstance(row, BkRow) + assert len(row.children) == 1 + model = row.children[0] + assert pane._models[row.ref['id']][0] is row + assert isinstance(model, Div) + assert model.text == '<pre> </pre>' + + # Test on_load + state._on_load(document) + model = row.children[0] + assert isinstance(model, Div) + assert model.text == '0' + + # Cleanup pane + pane._cleanup(row) + assert pane._models == {} + assert inner_pane._models == {} + + def test_param_function_pane_update(document, comm): test = View() diff --git a/panel/tests/ui/test_param.py b/panel/tests/ui/test_param.py new file mode 100644 index 0000000000..f6548f0ead --- /dev/null +++ b/panel/tests/ui/test_param.py @@ -0,0 +1,29 @@ +import time + +import pytest + +pytestmark = pytest.mark.ui + +from panel.io.server import serve +from panel.pane import panel + + +def test_param_defer_load(page, port): + def defer_load(): + time.sleep(0.5) + return 'I render after load!' + + component = panel(defer_load, defer_load=True) + + serve(component, port=port, threaded=True, show=False) + + time.sleep(0.2) + + page.goto(f"http://localhost:{port}") + + assert page.locator(".bk.pn-loading") + assert page.locator('.bk.markdown').count() == 0 + + time.sleep(0.5) + + assert page.text_content('.bk.markdown') == 'I render after load!'