From c8a67181e43ea45ca716ee35c462415121fc19b7 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Thu, 6 Oct 2022 19:24:18 +0200 Subject: [PATCH 1/7] Correctly handle resource mode in conversion --- panel/io/convert.py | 19 ++++++------------- panel/models/tabulator.py | 2 +- panel/widgets/tables.py | 5 +++-- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/panel/io/convert.py b/panel/io/convert.py index 9f417f268d..0c4cbec293 100644 --- a/panel/io/convert.py +++ b/panel/io/convert.py @@ -18,7 +18,6 @@ from bokeh.embed.elements import script_for_render_items from bokeh.embed.util import RenderItem, standalone_docs_json_and_render_items from bokeh.embed.wrappers import wrap_in_script_tag -from bokeh.settings import settings as _settings from bokeh.util.serialization import make_id from typing_extensions import Literal @@ -27,7 +26,7 @@ from .mime_render import find_imports from .resources import ( CDN_DIST, DIST_DIR, INDEX_TEMPLATE, Resources, _env as _pn_env, - bundle_resources, + bundle_resources, set_resource_mode, ) from .state import set_curdoc, state @@ -188,9 +187,6 @@ def script_to_html( panel_version: 'auto' | str The panel release version to use in the exported HTML. """ - # Configure resources - _settings.resources.set_value('cdn') - # Run script path = pathlib.Path(filename) name = '.'.join(path.name.split('.')[:-1]) @@ -324,10 +320,6 @@ def script_to_html( html = (html .replace('', f'') ) - - # Reset resources - _settings.resources.unset_value() - return html, web_worker @@ -341,10 +333,11 @@ def convert_app( verbose: bool = True, ): try: - html, js_worker = script_to_html( - app, requirements=requirements, runtime=runtime, - prerender=prerender, manifest=manifest - ) + with set_resource_mode('cdn'): + html, js_worker = script_to_html( + app, requirements=requirements, runtime=runtime, + prerender=prerender, manifest=manifest + ) except KeyboardInterrupt: return except Exception as e: diff --git a/panel/models/tabulator.py b/panel/models/tabulator.py index 1bd0bd7a32..560c9f6ee3 100644 --- a/panel/models/tabulator.py +++ b/panel/models/tabulator.py @@ -23,7 +23,7 @@ THEME_PATH = f"tabulator-tables@{TABULATOR_VERSION}/dist/css/" THEME_URL = f"{config.npm_cdn}/{THEME_PATH}" -PANEL_CDN = f"{config.npm_cdn}/@holoviz/panel/dist/bundled/{THEME_PATH}" +PANEL_CDN = f"{config.npm_cdn}/@holoviz/panel/dist/bundled/datatabulator/{THEME_PATH}" TABULATOR_THEMES = [ 'default', 'site', 'simple', 'midnight', 'modern', 'bootstrap', 'bootstrap4', 'materialize', 'bulma', 'semantic-ui', 'fast' diff --git a/panel/widgets/tables.py b/panel/widgets/tables.py index b4bdcbeea4..dd687973cc 100644 --- a/panel/widgets/tables.py +++ b/panel/widgets/tables.py @@ -1188,14 +1188,15 @@ def _process_event(self, event): def _get_theme(self, theme, resources=None): from ..io.resources import RESOURCE_MODE from ..models.tabulator import ( - _TABULATOR_THEMES_MAPPING, THEME_PATH, THEME_URL, _get_theme_url, + _TABULATOR_THEMES_MAPPING, PANEL_CDN, THEME_PATH, THEME_URL, + _get_theme_url, ) if RESOURCE_MODE == 'server' and resources in (None, 'server'): theme_url = f'{LOCAL_DIST}bundled/datatabulator/{THEME_PATH}' if state.rel_path: theme_url = f'{state.rel_path}/{theme_url}' else: - theme_url = THEME_URL + theme_url = PANEL_CDN # Ensure theme_url updates before theme cdn_url = _get_theme_url(THEME_URL, theme) theme_url = _get_theme_url(theme_url, theme) From 85501695f80ca5a7fbf4ba3987958f313c6144a9 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Fri, 7 Oct 2022 12:30:21 +0200 Subject: [PATCH 2/7] Test pyodide against local wheels --- .github/workflows/test.yaml | 4 ++ panel/io/convert.py | 20 ++++++--- panel/io/resources.py | 8 ++-- panel/models/tabulator.py | 4 +- panel/tests/ui/io/test_convert.py | 71 +++++++++++++++++++++++-------- 5 files changed, 79 insertions(+), 28 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ce135b22d5..27f092d734 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -116,6 +116,10 @@ jobs: cache: true playwright: true id: install + - name: build pyodide wheels + run: | + conda activate test-environment + python scripts/build_pyodide_wheels.py - name: launch jupyter run: | conda activate test-environment diff --git a/panel/io/convert.py b/panel/io/convert.py index 0c4cbec293..ccb6896959 100644 --- a/panel/io/convert.py +++ b/panel/io/convert.py @@ -38,6 +38,8 @@ PANEL_ROOT = pathlib.Path(__file__).parent.parent BOKEH_VERSION = '2.4.3' PY_VERSION = base_version(__version__) +PANEL_LOCAL_WHL = f'{DIST_DIR}/wheels/panel-{__version__.replace("-dirty", "")}-py3-none-any.whl' +BOKEH_LOCAL_WHL = f'{DIST_DIR}/wheels/bokeh-{BOKEH_VERSION}-py3-none-any.whl' PANEL_CDN_WHL = f'{CDN_DIST}wheels/panel-{PY_VERSION}-py3-none-any.whl' BOKEH_CDN_WHL = f'{CDN_DIST}wheels/bokeh-{BOKEH_VERSION}-py3-none-any.whl' PYODIDE_URL = 'https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.js' @@ -163,7 +165,7 @@ def script_to_html( css_resources: Literal['auto'] | List[str] | None = None, runtime: Runtimes = 'pyodide', prerender: bool = True, - panel_version: Literal['auto'] | str = 'auto', + panel_version: Literal['auto', 'local'] | str = 'auto', manifest: str | None = None ) -> str: """ @@ -221,7 +223,10 @@ def script_to_html( ) # Environment - if panel_version == 'auto': + if panel_version == 'local': + panel_req = './' + PANEL_LOCAL_WHL.split('/')[-1] + bokeh_req = './' + BOKEH_LOCAL_WHL.split('/')[-1] + elif panel_version == 'auto': panel_req = PANEL_CDN_WHL bokeh_req = BOKEH_CDN_WHL else: @@ -330,13 +335,15 @@ def convert_app( runtime: Runtimes = 'pyodide-worker', prerender: bool = True, manifest: str | None = None, + panel_version: Literal['auto', 'local'] | str = 'auto', verbose: bool = True, ): try: with set_resource_mode('cdn'): html, js_worker = script_to_html( app, requirements=requirements, runtime=runtime, - prerender=prerender, manifest=manifest + prerender=prerender, manifest=manifest, + panel_version=panel_version ) except KeyboardInterrupt: return @@ -365,8 +372,9 @@ def convert_apps( build_index: bool = True, build_pwa: bool = True, pwa_config: Dict[Any, Any] = {}, + max_workers: int = 4, + panel_version: Literal['auto', 'local'] | str = 'auto', verbose: bool = True, - max_workers: int = 4 ): """ Arguments @@ -400,6 +408,8 @@ def convert_apps( - theme_color: The theme color of the application max_workers: int The maximum number of parallel workers + panel_version: 'auto' | 'local'] | str +' The panel version to include. """ if isinstance(apps, str): apps = [apps] @@ -419,7 +429,7 @@ def convert_apps( f = executor.submit( convert_app, app, dest_path, requirements=requirements, runtime=runtime, prerender=prerender, manifest=manifest, - verbose=verbose + panel_version=panel_version, verbose=verbose ) futures.append(f) for future in concurrent.futures.as_completed(futures): diff --git a/panel/io/resources.py b/panel/io/resources.py index fa24f160fe..c80828034f 100644 --- a/panel/io/resources.py +++ b/panel/io/resources.py @@ -16,8 +16,8 @@ import param from bokeh.embed.bundle import ( - Bundle as BkBundle, _bundle_extensions, _use_mathjax, bundle_models, - extension_dirs, + CSS_RESOURCES as BkCSS_RESOURCES, Bundle as BkBundle, _bundle_extensions, + _use_mathjax, bundle_models, extension_dirs, ) from bokeh.resources import Resources as BkResources from bokeh.settings import settings as _settings @@ -376,7 +376,6 @@ def css_files(self): if self.mode == 'inline': break css_files.append(dist_dir + f'css/{os.path.basename(cssf)}') - return css_files @property @@ -424,6 +423,9 @@ def from_bokeh(cls, bk_bundle): hashes=bk_bundle.hashes, ) + def _render_css(self) -> str: + return BkCSS_RESOURCES.render(css_files=self._adjust_paths(self.css_files), css_raw=self.css_raw) + def _render_js(self): return JS_RESOURCES.render( js_raw=self.js_raw, js_files=self._adjust_paths(self.js_files), diff --git a/panel/models/tabulator.py b/panel/models/tabulator.py index 560c9f6ee3..60ff56c7b0 100644 --- a/panel/models/tabulator.py +++ b/panel/models/tabulator.py @@ -13,7 +13,7 @@ from bokeh.models.widgets.tables import TableColumn from ..config import config -from ..io.resources import bundled_files +from ..io.resources import JS_VERSION, bundled_files from ..util import classproperty TABULATOR_VERSION = "5.3.2" @@ -23,7 +23,7 @@ THEME_PATH = f"tabulator-tables@{TABULATOR_VERSION}/dist/css/" THEME_URL = f"{config.npm_cdn}/{THEME_PATH}" -PANEL_CDN = f"{config.npm_cdn}/@holoviz/panel/dist/bundled/datatabulator/{THEME_PATH}" +PANEL_CDN = f"{config.npm_cdn}/@holoviz/panel@{JS_VERSION}/dist/bundled/datatabulator/{THEME_PATH}" TABULATOR_THEMES = [ 'default', 'site', 'simple', 'midnight', 'modern', 'bootstrap', 'bootstrap4', 'materialize', 'bulma', 'semantic-ui', 'fast' diff --git a/panel/tests/ui/io/test_convert.py b/panel/tests/ui/io/test_convert.py index 6f8f3461c4..dd76c4ed45 100644 --- a/panel/tests/ui/io/test_convert.py +++ b/panel/tests/ui/io/test_convert.py @@ -1,3 +1,4 @@ +import os import pathlib import tempfile import time @@ -15,7 +16,7 @@ pytestmark = pytest.mark.ui from panel.config import config -from panel.io.convert import convert_apps +from panel.io.convert import BOKEH_LOCAL_WHL, PANEL_LOCAL_WHL, convert_apps button_app = """ import panel as pn @@ -36,6 +37,19 @@ pn.Row(slider, pn.bind(lambda v: v, slider)).servable(); """ +tabulator_app = """ +import panel as pn +import pandas as pd +tabulator = pn.widgets.Tabulator(pd._testing.makeMixedDataFrame()) + +def on_click(e): + tabulator.theme = 'fast' + +button = pn.widgets.Button() +button.on_click(on_click) + +pn.Row(button, tabulator).servable(); +""" def write_app(app): """ @@ -44,6 +58,19 @@ def write_app(app): nf = tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) nf.write(app) nf.flush() + dest = pathlib.Path(nf.name).parent + pn_whl = pathlib.Path(PANEL_LOCAL_WHL) + bk_whl = pathlib.Path(BOKEH_LOCAL_WHL) + if not (pn_whl.is_file() and bk_whl.is_file()): + raise RuntimeError( + "Build local wheels for pyodide using `python scripts/build_pyodide_wheels.py`." + ) + if (dest / pn_whl.name).is_file(): + os.unlink(dest / pn_whl.name) + os.link(PANEL_LOCAL_WHL, dest / pn_whl.name) + if (dest / bk_whl.name).is_file(): + os.unlink(dest / bk_whl.name) + os.link(BOKEH_LOCAL_WHL, dest / bk_whl.name) return nf @pytest.fixture(scope="module") @@ -52,7 +79,7 @@ def start_server(): def start(path): process = Popen( - ["python", "-m", "http.server", "8123", "--directory", str(path.parent)], stdout=PIPE + ["python", "-m", "http.server", "8123", "--directory", str(path)], stdout=PIPE ) retries = 5 while retries > 0: @@ -79,9 +106,12 @@ def start(path): def test_pyodide_test_convert_button_app(page, runtime, start_server): nf = write_app(button_app) app_path = pathlib.Path(nf.name) - start_server(app_path) + start_server(app_path.parent) + + convert_apps([app_path], app_path.parent, runtime=runtime, build_pwa=False, build_index=False, prerender=False, panel_version='local') - convert_apps([app_path], app_path.parent, runtime=runtime, build_pwa=False, build_index=False, prerender=False) + msgs = [] + page.on("console", lambda msg: msgs.append(msg)) page.goto(f"http://localhost:8123/{app_path.name[:-3]}.html") @@ -95,14 +125,18 @@ def test_pyodide_test_convert_button_app(page, runtime, start_server): expect(page.locator(".bk.bk-clearfix")).to_have_text('1') + assert [msg for msg in msgs if msg.type == 'error' and 'favicon' not in msg.location['url']] == [] @pytest.mark.parametrize('runtime', ['pyodide', 'pyscript', 'pyodide-worker']) def test_pyodide_test_convert_slider_app(page, runtime, start_server): nf = write_app(slider_app) app_path = pathlib.Path(nf.name) - start_server(app_path) + start_server(app_path.parent) - convert_apps([app_path], app_path.parent, runtime=runtime, build_pwa=False, build_index=False, prerender=False) + convert_apps([app_path], app_path.parent, runtime=runtime, build_pwa=False, build_index=False, prerender=False, panel_version='local') + + msgs = [] + page.on("console", lambda msg: msgs.append(msg)) page.goto(f"http://localhost:8123/{app_path.name[:-3]}.html") @@ -117,27 +151,28 @@ def test_pyodide_test_convert_slider_app(page, runtime, start_server): expect(page.locator(".bk.bk-clearfix")).to_have_text('0.1') + assert [msg for msg in msgs if msg.type == 'error' and 'favicon' not in msg.location['url']] == [] + @pytest.mark.parametrize('runtime', ['pyodide-worker']) -def test_pyodide_test_convert_location_app(page, runtime, start_server): - nf = write_app(location_app) +def test_pyodide_test_convert_tabulator_app(page, runtime, start_server): + nf = write_app(tabulator_app) app_path = pathlib.Path(nf.name) - start_server(app_path) + start_server(app_path.parent) - convert_apps([app_path], app_path.parent, runtime=runtime, build_pwa=False, build_index=False, prerender=False) + convert_apps([app_path], app_path.parent, runtime=runtime, build_pwa=False, build_index=False, prerender=False, panel_version='local') - app_url = f"http://localhost:8123/{app_path.name[:-3]}.html" - page.goto(f"{app_url}?value=3.14") + msgs = [] + page.on("console", lambda msg: msgs.append(msg)) + + page.goto(f"http://localhost:8123/{app_path.name[:-3]}.html") cls = f'bk pn-loading {config.loading_spinner}' expect(page.locator('body')).to_have_class(cls) expect(page.locator('body')).not_to_have_class(cls, timeout=60 * 1000) - expect(page.locator(".bk.bk-clearfix")).to_have_text('3.14') - - page.click('.noUi-handle') - page.keyboard.press('ArrowRight') + page.click('.bk.bk-btn') - expect(page.locator(".bk.bk-clearfix")).to_have_text('3.2') + time.sleep(1) - assert page.url == f"{app_url}?value=3.2" + assert [msg for msg in msgs if msg.type == 'error' and 'favicon' not in msg.location['url']] == [] From 3d538bd40bf9fffb69ea5d65a7294aca8acb8e2c Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Fri, 7 Oct 2022 13:21:22 +0200 Subject: [PATCH 3/7] Fix paths for windows --- panel/io/convert.py | 8 ++++---- panel/tests/ui/io/test_convert.py | 16 +++++++--------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/panel/io/convert.py b/panel/io/convert.py index ccb6896959..bf4e22b1df 100644 --- a/panel/io/convert.py +++ b/panel/io/convert.py @@ -38,8 +38,8 @@ PANEL_ROOT = pathlib.Path(__file__).parent.parent BOKEH_VERSION = '2.4.3' PY_VERSION = base_version(__version__) -PANEL_LOCAL_WHL = f'{DIST_DIR}/wheels/panel-{__version__.replace("-dirty", "")}-py3-none-any.whl' -BOKEH_LOCAL_WHL = f'{DIST_DIR}/wheels/bokeh-{BOKEH_VERSION}-py3-none-any.whl' +PANEL_LOCAL_WHL = DIST_DIR / 'wheels' / f'panel-{__version__.replace("-dirty", "")}-py3-none-any.whl' +BOKEH_LOCAL_WHL = DIST_DIR / 'wheels' / f'bokeh-{BOKEH_VERSION}-py3-none-any.whl' PANEL_CDN_WHL = f'{CDN_DIST}wheels/panel-{PY_VERSION}-py3-none-any.whl' BOKEH_CDN_WHL = f'{CDN_DIST}wheels/bokeh-{BOKEH_VERSION}-py3-none-any.whl' PYODIDE_URL = 'https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.js' @@ -224,8 +224,8 @@ def script_to_html( # Environment if panel_version == 'local': - panel_req = './' + PANEL_LOCAL_WHL.split('/')[-1] - bokeh_req = './' + BOKEH_LOCAL_WHL.split('/')[-1] + panel_req = './' + str(PANEL_LOCAL_WHL).split('/')[-1] + bokeh_req = './' + str(BOKEH_LOCAL_WHL).split('/')[-1] elif panel_version == 'auto': panel_req = PANEL_CDN_WHL bokeh_req = BOKEH_CDN_WHL diff --git a/panel/tests/ui/io/test_convert.py b/panel/tests/ui/io/test_convert.py index dd76c4ed45..717797f35e 100644 --- a/panel/tests/ui/io/test_convert.py +++ b/panel/tests/ui/io/test_convert.py @@ -59,18 +59,16 @@ def write_app(app): nf.write(app) nf.flush() dest = pathlib.Path(nf.name).parent - pn_whl = pathlib.Path(PANEL_LOCAL_WHL) - bk_whl = pathlib.Path(BOKEH_LOCAL_WHL) - if not (pn_whl.is_file() and bk_whl.is_file()): + if not (PANEL_LOCAL_WHL.is_file() and BOKEH_LOCAL_WHL.is_file()): raise RuntimeError( "Build local wheels for pyodide using `python scripts/build_pyodide_wheels.py`." ) - if (dest / pn_whl.name).is_file(): - os.unlink(dest / pn_whl.name) - os.link(PANEL_LOCAL_WHL, dest / pn_whl.name) - if (dest / bk_whl.name).is_file(): - os.unlink(dest / bk_whl.name) - os.link(BOKEH_LOCAL_WHL, dest / bk_whl.name) + if (dest / PANEL_LOCAL_WHL.name).is_file(): + os.unlink(dest / PANEL_LOCAL_WHL.name) + os.link(PANEL_LOCAL_WHL, dest / PANEL_LOCAL_WHL.name) + if (dest / BOKEH_LOCAL_WHL.name).is_file(): + os.unlink(dest / BOKEH_LOCAL_WHL.name) + os.link(BOKEH_LOCAL_WHL, dest / BOKEH_LOCAL_WHL.name) return nf @pytest.fixture(scope="module") From d082888efe89674b355a992eb3b1372752d896e4 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Fri, 7 Oct 2022 15:25:25 +0200 Subject: [PATCH 4/7] Use shutil.copy instead of symlinking wheels --- panel/tests/ui/io/test_convert.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/panel/tests/ui/io/test_convert.py b/panel/tests/ui/io/test_convert.py index 717797f35e..0eeebe53a7 100644 --- a/panel/tests/ui/io/test_convert.py +++ b/panel/tests/ui/io/test_convert.py @@ -1,5 +1,5 @@ -import os import pathlib +import shutil import tempfile import time @@ -63,12 +63,14 @@ def write_app(app): raise RuntimeError( "Build local wheels for pyodide using `python scripts/build_pyodide_wheels.py`." ) - if (dest / PANEL_LOCAL_WHL.name).is_file(): - os.unlink(dest / PANEL_LOCAL_WHL.name) - os.link(PANEL_LOCAL_WHL, dest / PANEL_LOCAL_WHL.name) - if (dest / BOKEH_LOCAL_WHL.name).is_file(): - os.unlink(dest / BOKEH_LOCAL_WHL.name) - os.link(BOKEH_LOCAL_WHL, dest / BOKEH_LOCAL_WHL.name) + try: + shutil.copy(PANEL_LOCAL_WHL, dest / PANEL_LOCAL_WHL.name) + except shutil.SameFileError: + pass + try: + shutil.copy(BOKEH_LOCAL_WHL, dest / BOKEH_LOCAL_WHL.name) + except shutil.SameFileError: + pass return nf @pytest.fixture(scope="module") From 11a03dff06844b684592f4b93658f98849dcf4cc Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Sat, 8 Oct 2022 10:53:07 +0200 Subject: [PATCH 5/7] Cleanup --- panel/tests/ui/io/test_convert.py | 53 ++++++++++++++++--------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/panel/tests/ui/io/test_convert.py b/panel/tests/ui/io/test_convert.py index 0eeebe53a7..86c33a023a 100644 --- a/panel/tests/ui/io/test_convert.py +++ b/panel/tests/ui/io/test_convert.py @@ -1,3 +1,5 @@ +import glob +import os import pathlib import shutil import tempfile @@ -18,6 +20,13 @@ from panel.config import config from panel.io.convert import BOKEH_LOCAL_WHL, PANEL_LOCAL_WHL, convert_apps +if not (PANEL_LOCAL_WHL.is_file() and BOKEH_LOCAL_WHL.is_file()): + pytest.skip( + "Skipped because pyodide wheels are not available for current " + "version. Build wheels for pyodide using `python scripts/build_pyodide_wheels.py`.", + allow_module_level=True + ) + button_app = """ import panel as pn button = pn.widgets.Button() @@ -55,14 +64,10 @@ def write_app(app): """ Writes app to temporary file and returns path. """ - nf = tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) + nf = tempfile.NamedTemporaryFile(mode='w', suffix='.py', encoding='utf-8', delete=False) nf.write(app) nf.flush() dest = pathlib.Path(nf.name).parent - if not (PANEL_LOCAL_WHL.is_file() and BOKEH_LOCAL_WHL.is_file()): - raise RuntimeError( - "Build local wheels for pyodide using `python scripts/build_pyodide_wheels.py`." - ) try: shutil.copy(PANEL_LOCAL_WHL, dest / PANEL_LOCAL_WHL.name) except shutil.SameFileError: @@ -74,21 +79,23 @@ def write_app(app): return nf @pytest.fixture(scope="module") -def start_server(): +def launch_app(): _PROCESSES = [] - def start(path): + def start(code): + nf = write_app(code) + app_path = pathlib.Path(nf.name) process = Popen( - ["python", "-m", "http.server", "8123", "--directory", str(path)], stdout=PIPE + ["python", "-m", "http.server", "8123", "--directory", str(app_path.parent)], stdout=PIPE ) retries = 5 while retries > 0: conn = HTTPConnection("localhost:8123") try: - conn.request("HEAD", str(path.name)) + conn.request("HEAD", str(app_path.name)) response = conn.getresponse() if response is not None: - _PROCESSES.append(process) + _PROCESSES.append((process, nf.name)) break except ConnectionRefusedError: time.sleep(1) @@ -96,17 +103,18 @@ def start(path): if not retries: raise RuntimeError("Failed to start http server") + return app_path yield start - for process in _PROCESSES: + for process, name in _PROCESSES: process.terminate() process.wait() + for f in glob.glob(f'{name[:-3]}*'): + os.remove(f) @pytest.mark.parametrize('runtime', ['pyodide', 'pyscript', 'pyodide-worker']) -def test_pyodide_test_convert_button_app(page, runtime, start_server): - nf = write_app(button_app) - app_path = pathlib.Path(nf.name) - start_server(app_path.parent) +def test_pyodide_test_convert_button_app(page, runtime, launch_app): + app_path = launch_app(button_app) convert_apps([app_path], app_path.parent, runtime=runtime, build_pwa=False, build_index=False, prerender=False, panel_version='local') @@ -128,10 +136,8 @@ def test_pyodide_test_convert_button_app(page, runtime, start_server): assert [msg for msg in msgs if msg.type == 'error' and 'favicon' not in msg.location['url']] == [] @pytest.mark.parametrize('runtime', ['pyodide', 'pyscript', 'pyodide-worker']) -def test_pyodide_test_convert_slider_app(page, runtime, start_server): - nf = write_app(slider_app) - app_path = pathlib.Path(nf.name) - start_server(app_path.parent) +def test_pyodide_test_convert_slider_app(page, runtime, launch_app): + app_path = launch_app(slider_app) convert_apps([app_path], app_path.parent, runtime=runtime, build_pwa=False, build_index=False, prerender=False, panel_version='local') @@ -153,12 +159,9 @@ def test_pyodide_test_convert_slider_app(page, runtime, start_server): assert [msg for msg in msgs if msg.type == 'error' and 'favicon' not in msg.location['url']] == [] - -@pytest.mark.parametrize('runtime', ['pyodide-worker']) -def test_pyodide_test_convert_tabulator_app(page, runtime, start_server): - nf = write_app(tabulator_app) - app_path = pathlib.Path(nf.name) - start_server(app_path.parent) +@pytest.mark.parametrize('runtime', ['pyodide', 'pyscript', 'pyodide-worker']) +def test_pyodide_test_convert_tabulator_app(page, runtime, launch_app): + app_path = launch_app(tabulator_app) convert_apps([app_path], app_path.parent, runtime=runtime, build_pwa=False, build_index=False, prerender=False, panel_version='local') From 627266207330e955ef7b309242ee641b2a19c889 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Sat, 8 Oct 2022 19:28:27 +0200 Subject: [PATCH 6/7] Attempt changing the IO encoding --- .github/workflows/test.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 27f092d734..6f52665e4b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -47,6 +47,7 @@ jobs: PYTHON_VERSION: ${{ matrix.python-version }} SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" DISPLAY: ":99.0" + PYTHONIOENCODING: "utf-8" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Without this env var `doit env_create ...` uses by default # the `pyviz` channel, except that we don't want to configure @@ -99,6 +100,7 @@ jobs: shell: bash -l {0} env: DESC: "Python ${{ matrix.python-version }} tests" + PYTHONIOENCODING: "utf-8" PANEL_LOG_LEVEL: info GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SETUPTOOLS_ENABLE_FEATURES: "legacy-editable" From 063008d4e5702eec50355379f303ee954d1e0a69 Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Sat, 8 Oct 2022 20:11:16 +0200 Subject: [PATCH 7/7] Fix windows local wheel path separator --- panel/io/convert.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/panel/io/convert.py b/panel/io/convert.py index bf4e22b1df..a25ab780b6 100644 --- a/panel/io/convert.py +++ b/panel/io/convert.py @@ -224,8 +224,8 @@ def script_to_html( # Environment if panel_version == 'local': - panel_req = './' + str(PANEL_LOCAL_WHL).split('/')[-1] - bokeh_req = './' + str(BOKEH_LOCAL_WHL).split('/')[-1] + panel_req = './' + str(PANEL_LOCAL_WHL.as_posix()).split('/')[-1] + bokeh_req = './' + str(BOKEH_LOCAL_WHL.as_posix()).split('/')[-1] elif panel_version == 'auto': panel_req = PANEL_CDN_WHL bokeh_req = BOKEH_CDN_WHL