Summary
When assigning values to Parameters, Param automatically resolves ref-like objects (e.g. Parameters, reactive expressions, async generators). Sometimes, however, users need to store these ref-like values themselves — for forwarding, serialization, inspection, or deferred evaluation — rather than immediately resolving them.
This issue proposes adding a minimal wrapper, raw, that marks a value to be stored as-is. Alternative names considered: constant, const, or literal.
Problem
Param’s assignment model is designed for convenience — ref-like values are automatically resolved when assigned to a Parameter.
However, there are valid use cases where the reference object itself should be stored, not the resolved value:
- Keeping a
Parameter or reactive object to be connected later.
- Holding an expression or generator for deferred computation.
- Serializing configurations that intentionally contain unresolved refs.
- Preserving symbolic or lazy evaluation constructs for inspection.
Proposed API
import param
# Store a ref-like value *as itself*, skipping resolution:
obj.some_param = param.Raw(ref_like)
# or the convenience function:
obj.some_param = param.raw(ref_like)
Alternative names under consideration:
param.const(value)
param.constant(value)
param.literal(value)
All would convey the same semantics: assign without resolving.
Semantics
-
raw(x) is a transient assignment wrapper.
-
During assignment, if a value is an instance of Raw, Param:
- Unwraps it (
x = x.value), and
- Skips any resolution logic that would normally occur.
-
The stored value becomes the underlying ref-like object, not the wrapper.
-
Reading the value simply returns whatever was stored.
Examples
Keep a reactive or param reference
class C(param.Parameterized):
value = param.Parameter()
ref_like = another_obj.param.some_param
c = C()
c.value = param.raw(ref_like)
assert c.value is ref_like
Keep a reactive expression or async generator
expr = rx.map(source, lambda v: v * 2)
c.value = param.raw(expr) # store expression, not resolved value
async def stream(): yield 1
c.value = param.raw(stream()) # store generator, not consumed
Containers are stored verbatim
c.value = param.raw([rx.expr1, param.Parameter(), async_gen])
Implementation sketch
class Raw:
__slots__ = ("value",)
def __init__(self, value): self.value = value
def __repr__(self): return f"Raw({self.value!r})"
def raw(value):
return Raw(value)
In Parameter.__set__ (or equivalent):
if isinstance(new, Raw):
new = new.value
skip_ref_resolution = True
if not skip_ref_resolution:
new = maybe_resolve(new) # existing logic
Typing (optional)
from typing import Generic, TypeVar
T = TypeVar("T")
class Raw(Generic[T]):
value: T
Backward compatibility
- Fully backward compatible: no change unless users explicitly use
Raw.
- The wrapper is transient and does not appear in serialized state.
- Stored value is the inner object.
Summary
When assigning values to Parameters, Param automatically resolves ref-like objects (e.g. Parameters, reactive expressions, async generators). Sometimes, however, users need to store these ref-like values themselves — for forwarding, serialization, inspection, or deferred evaluation — rather than immediately resolving them.
This issue proposes adding a minimal wrapper,
raw, that marks a value to be stored as-is. Alternative names considered:constant,const, orliteral.Problem
Param’s assignment model is designed for convenience — ref-like values are automatically resolved when assigned to a Parameter.
However, there are valid use cases where the reference object itself should be stored, not the resolved value:
Parameteror reactive object to be connected later.Proposed API
Alternative names under consideration:
param.const(value)param.constant(value)param.literal(value)All would convey the same semantics: assign without resolving.
Semantics
raw(x)is a transient assignment wrapper.During assignment, if a value is an instance of
Raw, Param:x = x.value), andThe stored value becomes the underlying ref-like object, not the wrapper.
Reading the value simply returns whatever was stored.
Examples
Keep a reactive or param reference
Keep a reactive expression or async generator
Containers are stored verbatim
Implementation sketch
In
Parameter.__set__(or equivalent):Typing (optional)
Backward compatibility
Raw.