Skip to content

Allow callable (dynamic) values for Date and CalendarDate#1163

Open
gaoflow wants to merge 1 commit into
holoviz:mainfrom
gaoflow:fix-date-callable-dynamic
Open

Allow callable (dynamic) values for Date and CalendarDate#1163
gaoflow wants to merge 1 commit into
holoviz:mainfrom
gaoflow:fix-date-callable-dynamic

Conversation

@gaoflow

@gaoflow gaoflow commented Jul 7, 2026

Copy link
Copy Markdown

Date and CalendarDate subclass Number, and all of them ultimately subclass Dynamic — whose contract is that a parameter may be set to a callable that is invoked to produce the value on get:

import datetime, param

class P(param.Parameterized):
    n = param.Number()
    d = param.Date()

p = P()
p.n = lambda: 42          # fine
p.d = lambda: datetime.datetime.now()
# ValueError: Date parameter 'P.d' only takes datetime and date types, not <class 'function'>

Number._validate_value explicitly allows a callable (callable(value) and not inspect.isgeneratorfunction(value)), and Integer inherits it — but the Date and CalendarDate overrides drop that guard and go straight to the datetime type check, so they reject a callable that their sibling parameters accept.

The dynamic machinery itself already handles callable dates correctly — with the guard added, p.d resolves to the datetime and re-evaluates on each access like any other Dynamic value; only _validate_value was rejecting them.

Fix. Add the same callable guard Number uses to Date._validate_value and CalendarDate._validate_value, so all Dynamic siblings behave uniformly.

Test. TestDynamicCallableAcrossNumberSiblings (in tests/testdynamicparams.py) parametrizes over Number, Integer, Date, CalendarDate and asserts each accepts a callable and resolves it on get, both via assignment and via constructor default=. Full suite (testdynamicparams, testdateparam, testcalendardateparam, testnumberparameter): 104 passed.

Date and CalendarDate subclass Number, whose Dynamic contract is that a
parameter may be set to a callable that is invoked to produce the value
on get. Number._validate_value honours this (callable(value) and not
inspect.isgeneratorfunction(value) -> return), but the Date and
CalendarDate overrides dropped the guard and went straight to the
datetime type check, raising ValueError on a callable that the Number
and Integer siblings accept.

The dynamic machinery already resolves callable dates correctly on get;
only validation rejected them. Add the same callable guard so all
Dynamic siblings behave uniformly. Adds a parametrized regression test
asserting Number/Integer/Date/CalendarDate all accept a callable and
resolve it on get, via both assignment and constructor default.
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

Successfully merging this pull request may close these issues.

1 participant