Skip to content

Commit

Permalink
Dynamically create Variables classes to avoid shared state (#413)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr authored Dec 15, 2022
1 parent 82b545c commit fac5b72
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
4 changes: 2 additions & 2 deletions lumen/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ def spec(self, spec: Dict[str, Any]):
def variables(self) -> Variables:
from .variables import Variables
if self._variable is None:
self._variable = Variables()
self._variable = Variables.create_variables()
if pn.state.curdoc is None:
return self._variable # type: ignore
elif pn.state.curdoc not in self._variables:
self._variables[pn.state.curdoc] = variables = Variables()
self._variables[pn.state.curdoc] = variables = Variables.create_variables()
for var in self._variable._vars.values(): # type: ignore
variables.add_variable(var)
return self._variables[pn.state.curdoc]
Expand Down
11 changes: 10 additions & 1 deletion lumen/variables/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class Variables(param.Parameterized):
components to easily watch changes in a variable.
"""

_counter: ClassVar[int] = 0

def __init__(self, **params):
super().__init__(**params)
self._vars = {}
Expand All @@ -41,9 +43,15 @@ def __init__(self, **params):
def keys(self):
return self._vars.keys()

@classmethod
def create_variables(cls):
new_cls = type(f'Variables{cls._counter}', (cls,), {})()
cls._counter += 1
return new_cls

@classmethod
def from_spec(cls, spec):
variables = cls()
variables = cls.create_variables()
if pn.state.curdoc:
state._variables[pn.state.curdoc] = variables
for name, var_spec in spec.items():
Expand Down Expand Up @@ -134,6 +142,7 @@ def add_variable(self, var: 'Variable' | _PnWidget | param.Parameter) -> 'Variab
variable.param.unwatch(self._watchers.pop(var.name))
self._vars[var.name] = var
self.param.add_parameter(var.name, param.Parameter(default=var.value))
self.param.update(**{var.name: var.value})
self._watchers[var.name] = var.param.watch(
partial(self._update_value, var.name), 'value'
)
Expand Down

0 comments on commit fac5b72

Please sign in to comment.