Skip to content

Deprecate setting a parameter value before full instance initialization #1025

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/reference/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ List of currently deprecated APIs:

| Warning | Description |
|-|-|
| `ParamPendingDeprecationWarning` since `2.3.0` | `param.parameterized` module / Setting a parameter value before full instance initialization |
| `ParamFutureWarning` since `2.2.0`, `ParamDeprecationWarning` since `2.0.0` | Parameter slots / `List._class`: use instead `item_type` |
| `ParamFutureWarning` since `2.2.0`, `ParamDeprecationWarning` since `2.0.0` | Parameter slots / `Number.set_hook`: no replacement |
| `ParamFutureWarning` since `2.2.0`, `ParamDeprecationWarning` since `2.0.0` | `param.__init__` module / `param.produce_value`: no replacement |
Expand Down
10 changes: 10 additions & 0 deletions param/parameterized.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from ._utils import (
DEFAULT_SIGNATURE,
ParamFutureWarning as _ParamFutureWarning,
ParamPendingDeprecationWarning as _ParamPendingDeprecationWarning,
Skip,
_deprecated,
_deprecate_positional_args,
Expand Down Expand Up @@ -1574,6 +1575,15 @@ def __set__(self, obj, val):
else:
# When setting a Parameter before calling super.
if not isinstance(obj._param__private, _InstancePrivate):
warnings.warn(
f"Setting the Parameter {self.name!r} to {val!r} before "
f"the Parameterized class {type(obj).__name__!r} is fully "
"instantiated is deprecated and will raise an error in "
"a future version. Ensure the value is set after calling "
"`super().__init__(**params)` in the constructor.",
category=_ParamPendingDeprecationWarning,
stacklevel=4,
)
obj._param__private = _InstancePrivate(
explicit_no_refs=type(obj)._param__private.explicit_no_refs
)
Expand Down
10 changes: 10 additions & 0 deletions tests/testdeprecations.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ def test_deprecate_all_equal(self):
with pytest.raises(param._utils.ParamFutureWarning):
param.parameterized.all_equal(1, 1)

def test_deprecate_setting_parameter_before_init(self):
class P(param.Parameterized):
x = param.Parameter()

def __init__(self, **params):
self.x = 10
super().__init__(**params)
with pytest.raises(param._utils.ParamPendingDeprecationWarning):
P()


class TestDeprecateParameters:

Expand Down
13 changes: 10 additions & 3 deletions tests/testparameterizedobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import inspect
import re
import unittest
import warnings

import param
import numbergen
Expand Down Expand Up @@ -400,7 +401,9 @@ def cb(self):
nonlocal count
count += 1

p = P()
with warnings.catch_warnings():
warnings.filterwarnings('ignore', message='Setting the Parameter', category=param._utils.ParamPendingDeprecationWarning)
p = P()

assert p.x == 1
assert count == 0
Expand All @@ -417,7 +420,9 @@ def __init__(self, depth=0):
self.sub = P(depth+1)
super().__init__()

p = P()
with warnings.catch_warnings():
warnings.filterwarnings('ignore', message='Setting the Parameter', category=param._utils.ParamPendingDeprecationWarning)
p = P()

assert p.value == 'B'
assert p.sub.value == 'B'
Expand All @@ -442,7 +447,9 @@ def __init__(self, batched=True, **params):

# When b is instantiated the `batched` Parameter of B is set before
# Parameterized.__init__ is called.
b = B()
with warnings.catch_warnings():
warnings.filterwarnings('ignore', message='Setting the Parameter', category=param._utils.ParamPendingDeprecationWarning)
b = B()
assert b.batched is True

def test_instantiation_param_objects_before_super_subclass(self):
Expand Down
Loading