Skip to content
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

Use of WidgetBase raises ParamFutureWarning #968

Open
MarcSkovMadsen opened this issue Sep 13, 2024 · 3 comments
Open

Use of WidgetBase raises ParamFutureWarning #968

MarcSkovMadsen opened this issue Sep 13, 2024 · 3 comments

Comments

@MarcSkovMadsen
Copy link
Collaborator

MarcSkovMadsen commented Sep 13, 2024

I'm on panel==1.5.0rc2 and param==2.1.1.

I have a custom CompositeWidget that I noticed started raising a ParamFutureWarning. After some inspection I can see the problem is is caused by the fact that the WidgetBase.value is a Parameter while my CustomWidget.value is a String.

I think this will be cause general problems as WidgetBase is now intended to be mixed into all kinds of custom widgets.

Reproduce

import panel as pn
from panel.widgets.base import WidgetBase
import param

class CustomWidget(pn.viewable.Viewer, WidgetBase):
    value = param.String()

    def __panel__(self):
        return self.param.value

CustomWidget(value="Hello World").servable()
/home/jovyan/repos/mt-pm-reporting/script.py:5: ParamFutureWarning: String parameter 'CustomWidget.value' failed to validate its default value on class creation, this is going to raise an error in the future. The Parameter type changed between class 'CustomWidget' and one of its parent classes (Viewer, WidgetBase) which made it invalid. Please fix the Parameter type.
Validation failed with:
String parameter 'CustomWidget.value' only takes a string value, not value of <class 'NoneType'>.
  value = param.String()

Workaround

Change param.String() to param.String(""). Then the ParamFutureWarning will not be raised.

@MarcSkovMadsen MarcSkovMadsen added TRIAGE User-submitted issue that hasn't been triaged yet. and removed TRIAGE User-submitted issue that hasn't been triaged yet. labels Sep 13, 2024
@philippjfr
Copy link
Member

This is not a bug, this is a param level warning and it's indicating a real potential issue. One could argue that if no default is set on the baseclass then the overriding class should override the default but we can't do anything about that in Panel, so moving to param.

@philippjfr philippjfr transferred this issue from holoviz/panel Sep 13, 2024
@philippjfr
Copy link
Member

@jbednar @maximlt pinging you for visibility.

@maximlt
Copy link
Member

maximlt commented Sep 13, 2024

It's also due to allow_None being computed dynamically. It's set to True in the superclass but, in that case, wrongly overridden at the sub-class level

import param

class A(param.Parameterized):
    x = param.Parameter()

class B(A):
    x = param.String()

print(A.x)
print(A.param.x.allow_None)
print(B.x)
print(B.param.x.allow_None)
None
True
None
False

They are a couple of tests that capture this (somewhat buggy) behavior:

def test_inheritance_allow_None_behavior():
class A(param.Parameterized):
p = param.Parameter(default=1)
class B(A):
p = param.Parameter()
# A computes allow_None to False, B sets it to True.
assert A.param.p.allow_None != B.param.p.allow_None
assert B.param.p.allow_None is True
a = A()
b = B()
assert a.param.p.allow_None != b.param.p.allow_None
assert b.param.p.allow_None is True
def test_inheritance_allow_None_behavior2():
class A(param.Parameterized):
p = param.Parameter(allow_None=False)
class B(A):
p = param.Parameter(default=None)
# A says None is not allowed, B sets the default to None and recomputes
# allow_None.
assert B.param.p.allow_None is True
b = B()
assert b.param.p.allow_None is True

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants