holoviz/param

Initialization changes constant attribute.

Opened this issue · 3 comments

Thanks for contacting us! Please read and follow these instructions carefully, then delete this introductory text to keep your issue easy to read. Note that the issue tracker is NOT the place for usage questions and technical assistance; post those at Discourse instead. Issues without the required information below may be closed immediately.

ALL software version info

panel==1.4.0
param==2.1.0
Python 3.10.12

Description of expected behavior and the observed behavior

Expecting normal initialization. Unfortunately, constant is being set to False on my parameter.

I would expect invariant_coef to remain constant.

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

import param as pm
import panel as pn
pn.extension()

class BondingCurve(pm.Parameterized):
    supply = pm.Number(80)
    reserve = pm.Number(40)
    kappa = pm.Number(2)
    invariant_coef = pm.Number(constant=True)
    price = pm.Number(constant=True)
    
    # def __init__(self, **params):
    #     super().__init__(**params)
    #     self.set_invariant_coef()
    
    @pm.depends(on_init=True, watch=True)
    def set_invariant_coef(self):
        with pm.edit_constant(self):
            self.invariant_coef = self.supply ** self.kappa / self.reserve

bc = BondingCurve()

pn.panel(bc)

bc.param['invariant_coef'].constant

False

image

This context manager seems to work not sure about what 'existing' does

import param as pm
import panel as pn
from contextlib import contextmanager


@contextmanager
def edit_constant(parameterized):
    """
    Temporarily set parameters on Parameterized object to constant=False
    to allow editing them.
    """
    params = parameterized.param.objects().values()  # changed from: 
    # params = parameterized.param.objects('existing').values()
    constants = [p.constant for p in params]
    for p in params:
        p.constant = False
    try:
        yield
    finally:
        for p, const in zip(params, constants):
            p.constant = const


class BondingCurve(pm.Parameterized):
    price = pm.Number(constant=True)

    @pm.depends(on_init=True, watch=True)
    def set_ex(self):
        with edit_constant(self):
            self.price = 1


bc = BondingCurve()

bc.param.price.constant, bc.price

Hi is this a bug in the library?

Again, I'm trying to use constants and edit_constant but am having this bug with the library.

That does look like a bug, yes.