function resolve_dependent_value
Recursively resolves parameter dependencies in a value by evaluating parameterized methods, functions, and widgets, including those nested in collections (lists, tuples, dicts, slices).
/tf/active/vicechatdev/patches/util.py
1550 - 1600
moderate
Purpose
This function is designed to work with the param library and Panel framework to resolve dynamic parameter dependencies. It traverses data structures to find and evaluate: param.Parameter objects, parameterized methods with dependencies, functions decorated with dependency information, and Panel widgets. This is essential for reactive programming patterns where values depend on other parameters that need to be evaluated at runtime.
Source Code
def resolve_dependent_value(value):
"""Resolves parameter dependencies on the supplied value
Resolves parameter values, Parameterized instance methods,
parameterized functions with dependencies on the supplied value,
including such parameters embedded in a list, tuple, dictionary, or slice.
Args:
value: A value which will be resolved
Returns:
A new value where any parameter dependencies have been
resolved.
"""
range_widget = False
if isinstance(value, list):
value = [resolve_dependent_value(v) for v in value]
elif isinstance(value, tuple):
value = tuple(resolve_dependent_value(v) for v in value)
elif isinstance(value, dict):
value = {
resolve_dependent_value(k): resolve_dependent_value(v) for k, v in value.items()
}
elif isinstance(value, slice):
value = slice(
resolve_dependent_value(value.start),
resolve_dependent_value(value.stop),
resolve_dependent_value(value.step),
)
if 'panel' in sys.modules:
from panel.widgets import RangeSlider, Widget
range_widget = isinstance(value, RangeSlider)
try:
from panel.depends import param_value_if_widget
value = param_value_if_widget(value)
except Exception:
if isinstance(value, Widget):
value = value.param.value
if is_param_method(value, has_deps=True):
value = value()
elif isinstance(value, param.Parameter) and isinstance(value.owner, param.Parameterized):
value = getattr(value.owner, value.name)
elif isinstance(value, FunctionType) and hasattr(value, '_dinfo'):
deps = value._dinfo
args = (getattr(p.owner, p.name) for p in deps.get('dependencies', []))
kwargs = {k: getattr(p.owner, p.name) for k, p in deps.get('kw', {}).items()}
value = value(*args, **kwargs)
if isinstance(value, tuple) and range_widget:
value = slice(*value)
return value
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
value |
- | - | positional_or_keyword |
Parameter Details
value: Any Python value that may contain parameter dependencies. Can be a primitive type, param.Parameter, parameterized method, function with dependencies, Panel widget, or nested collection (list, tuple, dict, slice) containing such values. The function will recursively traverse collections to resolve all dependencies.
Return Value
Returns a new value where all parameter dependencies have been resolved to their current values. For collections, returns a new collection of the same type with all nested dependencies resolved. For Panel RangeSlider widgets that return tuples, converts the tuple to a slice object. For all other values, returns the evaluated/dereferenced value.
Dependencies
sysparampanel
Required Imports
import sys
from types import FunctionType
import param
Conditional/Optional Imports
These imports are only needed under specific conditions:
from panel.widgets import RangeSlider, Widget
Condition: only if 'panel' module is available in sys.modules and value is a Panel widget
Optionalfrom panel.depends import param_value_if_widget
Condition: only if 'panel' module is available and attempting to extract widget values
OptionalUsage Example
import param
from types import FunctionType
import sys
# Example 1: Resolving a param.Parameter
class MyParams(param.Parameterized):
x = param.Number(default=5)
y = param.Number(default=10)
obj = MyParams()
param_ref = obj.param.x
resolved = resolve_dependent_value(param_ref)
print(resolved) # Output: 5
# Example 2: Resolving nested collections
data = {
'values': [obj.param.x, obj.param.y],
'range': slice(obj.param.x, obj.param.y)
}
resolved_data = resolve_dependent_value(data)
print(resolved_data) # Output: {'values': [5, 10], 'range': slice(5, 10, None)}
# Example 3: Resolving parameterized method
class MyClass(param.Parameterized):
value = param.Number(default=42)
@param.depends('value')
def get_doubled(self):
return self.value * 2
instance = MyClass()
result = resolve_dependent_value(instance.get_doubled)
print(result) # Output: 84
Best Practices
- This function is designed for use within the HoloViz ecosystem (param/Panel) and may not work correctly outside that context
- The function modifies collections by creating new instances rather than mutating in place
- Panel widget resolution is wrapped in a try-except block to handle cases where panel.depends may not be available
- Be aware that calling this function will trigger evaluation of all dependent methods and functions, which may have side effects
- The function checks for 'panel' in sys.modules before attempting widget resolution, making Panel an optional dependency
- For RangeSlider widgets, the returned tuple is automatically converted to a slice object for convenience
- The function uses hasattr checks and isinstance guards to safely handle different value types without raising exceptions
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function resolve_dependent_kwargs 73.8% similar
-
function get_param_values 42.9% similar
-
function _eval_panel 40.8% similar
-
function is_param_method 40.6% similar
-
function get_config_value 37.8% similar