Skip to content

Commit

Permalink
Ensure edit_constant resets class and instance level parameters (#1015)
Browse files Browse the repository at this point in the history
  • Loading branch information
maximlt authored Feb 21, 2025
1 parent 058f77a commit f9ac897
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 6 deletions.
20 changes: 14 additions & 6 deletions param/parameterized.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,15 +340,23 @@ def edit_constant(parameterized):
Temporarily set parameters on Parameterized object to constant=False
to allow editing them.
"""
params = parameterized.param.objects('existing').values()
constants = [p.constant for p in params]
for p in params:
p.constant = False
kls_params = parameterized.param.objects(instance=False)
inst_params = parameterized._param__private.params
updated = []
for pname, pobj in (kls_params | inst_params).items():
if pobj.constant:
pobj.constant = False
updated.append(pname)
try:
yield
finally:
for (p, const) in zip(params, constants):
p.constant = const
for pname in updated:
# Some operations trigger a parameter instantiation (copy),
# we ensure both the class and instance parameters are reset.
if pname in kls_params:
type(parameterized).param[pname].constant=True
if pname in inst_params:
parameterized.param[pname].constant = True


@contextmanager
Expand Down
12 changes: 12 additions & 0 deletions tests/testparameterizedobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
ParamOverrides,
Undefined,
default_label_formatter,
edit_constant,
no_instance_params,
shared_parameters,
)
Expand Down Expand Up @@ -313,6 +314,17 @@ def test_constant_parameter(self):
testpo = TestPO()
self.assertEqual(testpo.const,9)

def test_edit_constant(self):
testpo = TestPO(const=670)
# Checking no parameter was already instantiated
assert not testpo._param__private.params
with edit_constant(testpo):
testpo.const = 891
assert testpo.const == 891
assert testpo.param['const'].constant
assert TestPO.param['const'].constant
assert TestPO.param['const'].default not in (670, 891)

def test_readonly_parameter(self):
"""Test that you can't set a read-only parameter on construction or as an attribute."""
testpo = TestPO()
Expand Down

0 comments on commit f9ac897

Please sign in to comment.