Skip to content

Bug with multiple pn.state.location.sync calls #8654

Description

@hyamanieu

ALL software version info

panel==1.5.4
No change of code on this area until v1.9.3

Description of expected behavior and the observed behavior

When calling pn.state.location.sync twice in the same class, the synchronization of parameters between the class and the URI doesn't work for all parameters in the second call. An error is thrown whenever we change a parameter from the second list.

Complete, minimal, self-contained example code that reproduces the issue

test_sync.py file content:

import panel as pn
import param

class Main_App(param.Parameterized):
    theme = param.Selector(
        default="light",
        objects=["light", "dark"],
    )
    font_size = param.Integer(default=12)

    def __init__(self, **params):
        super().__init__(**params)
        if pn.state.location:
            pn.state.location.sync(
                self,
                ["theme", "font_size"],
            )

    def panel(self):
        return pn.Param(self)

class UserSettings(Main_App):
    language = param.Selector(
        default="en",
        objects=["en", "fr", "es"],
    )
    notifications = param.Boolean(default=True)

    def __init__(self, **params):
        super().__init__(**params)
        if pn.state.location:
            pn.state.location.sync(
                self,
                ["language", "notifications"],
            )

    def panel(self):
        return pn.Param(self)

# Create an instance of UserSettings
user_settings = UserSettings()

# Serve the panel
user_settings.panel().servable()

Execute the following:

panel serve test_sync.py

Stack traceback and/or browser JavaScript console output

Access http://localhost:5006/test_sync then change the language.

Following error appears:

Traceback (most recent call last):
  File "<...>/.pixi/envs/default/lib/python3.10/site-packages/panel/io/location.py", line 212, in _update_query
    serialized[matches[0][e.name]] = val
KeyError: 'language'

PR proposition

I would turn the private parameter pn.state.location._synced into a dict where the key is the variable parameterized from pn.state.location.sync, I think it would also simplify other functions like _server_destroy and unsync

Metadata

Metadata

Assignees

No one assigned

    Labels

    TRIAGEDefault label for untriaged issues

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions