Skip to content

Core

signified.core

Core reactive programming functionality.

__all__ module-attribute

__all__ = ['Observer', 'ReactiveMixIn', 'Variable', 'Signal', 'Computed', 'computed', 'unref', 'has_value', 'deep_unref', 'reactive_method', 'as_signal']

InstanceMethod

InstanceMethod = Callable[Concatenate[Any, P], T]

ReactiveMethod

ReactiveMethod = Callable[Concatenate[Any, P], Computed[T]]

ReactiveMixIn

Methods for easily creating reactive values.

value property

value

The current value of the reactive object.

notify

notify()

Notify all observers by calling their update method.

__getattr__

__getattr__(name: Literal['value', '_value']) -> T
__getattr__(name: str) -> Computed[Any]
__getattr__(name)

Create a reactive value for retrieving an attribute from self.value.

Parameters:

Name Type Description Default
name str

The name of the attribute to access.

required

Returns:

Type Description
Union[T, Computed[Any]]

A reactive value for the attribute access.

Raises:

Type Description
AttributeError

If the attribute doesn't exist.

Note

Type inference is poor whenever __getattr__ is used.

Example
>>> class Person:
...     def __init__(self, name):
...         self.name = name
>>> s = Signal(Person("Alice"))
>>> result = s.name
>>> result.value
'Alice'
>>> s.value = Person("Bob")
>>> result.value
'Bob'

__call__

__call__(*args, **kwargs)

Create a reactive value for calling self.value(*args, **kwargs).

Parameters:

Name Type Description Default
*args P.args

Positional arguments to pass to the callable value.

()
**kwargs P.kwargs

Keyword arguments to pass to the callable value.

{}

Returns:

Type Description
Computed[R]

A reactive value for the function call.

Raises:

Type Description
ValueError

If the value is not callable.

Example
>>> class Person:
...     def __init__(self, name):
...         self.name = name
...     def greet(self):
...         return f"Hi, I'm {self.name}!"
>>> s = Signal(Person("Alice"))
>>> result = s.greet()
>>> result.value
"Hi, I'm Alice!"
>>> s.name = "Bob"
>>> result.value
"Hi, I'm Bob!"

__abs__

__abs__() -> Computed[float]
__abs__() -> Computed[int]
__abs__() -> Computed[T]
__abs__()

Return a reactive value for the absolute value of self.

Returns:

Type Description
Computed[T] | Computed[float] | Computed[int]

A reactive value for abs(self.value).

Example
>>> s = Signal(-5)
>>> result = abs(s)
>>> result.value
5
>>> s.value = -10
>>> result.value
10

as_bool

as_bool()

Return a reactive value for the boolean value of self.

Note

__bool__ cannot be implemented to return a non-bool, so it is provided as a method.

Returns:

Type Description
Computed[bool]

A reactive value for bool(self.value).

Example
>>> s = Signal(1)
>>> result = s.as_bool()
>>> result.value
True
>>> s.value = 0
>>> result.value
False

__str__

__str__()

Return a string of the current value.

Note

This is not reactive.

Returns:

Type Description
str

A string representation of self.value.

__round__

__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[int]
__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[int]
__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[float]
__round__(ndigits: int | None = None) -> Computed[int] | Computed[float]
__round__(ndigits=None)

Return a reactive value for the rounded value of self.

Parameters:

Name Type Description Default
ndigits int | None

Number of decimal places to round to.

None

Returns:

Type Description
Computed[int] | Computed[float]

A reactive value for round(self.value, ndigits).

Example
>>> s = Signal(3.14159)
>>> result = round(s, 2)
>>> result.value
3.14
>>> s.value = 2.71828
>>> result.value
2.72

__ceil__

__ceil__()

Return a reactive value for the ceiling of self.

Returns:

Type Description
Computed[int]

A reactive value for math.ceil(self.value).

Example
>>> from math import ceil
>>> s = Signal(3.14)
>>> result = ceil(s)
>>> result.value
4
>>> s.value = 2.01
>>> result.value
3

__floor__

__floor__()

Return a reactive value for the floor of self.

Returns:

Type Description
Computed[int]

A reactive value for math.floor(self.value).

Example
>>> from math import floor
>>> s = Signal(3.99)
>>> result = floor(s)
>>> result.value
3
>>> s.value = 4.01
>>> result.value
4

__invert__

__invert__() -> Computed[int]
__invert__() -> Computed[T]
__invert__()

Return a reactive value for the bitwise inversion of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for ~self.value.

Example
>>> s = Signal(5)
>>> result = ~s
>>> result.value
-6
>>> s.value = -3
>>> result.value
2

__neg__

__neg__() -> Computed[int]
__neg__() -> Computed[T]
__neg__()

Return a reactive value for the negation of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for -self.value.

Example
>>> s = Signal(5)
>>> result = -s
>>> result.value
-5
>>> s.value = -3
>>> result.value
3

__pos__

__pos__() -> Computed[int]
__pos__() -> Computed[T]
__pos__()

Return a reactive value for the positive of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for +self.value.

Example
>>> s = Signal(-5)
>>> result = +s
>>> result.value
-5
>>> s.value = 3
>>> result.value
3

__trunc__

__trunc__() -> Computed[int]
__trunc__() -> Computed[int]
__trunc__() -> Computed[int]
__trunc__() -> Computed[T]
__trunc__()

Return a reactive value for the truncated value of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for math.trunc(self.value).

Example
>>> from math import trunc
>>> s = Signal(3.99)
>>> result = trunc(s)
>>> result.value
3
>>> s.value = -4.01
>>> result.value
-4

__add__

__add__(other: HasValue[int] | HasValue[float]) -> Computed[float]
__add__(other: HasValue[float]) -> Computed[float]
__add__(other: HasValue[Y]) -> Computed[R]
__add__(other: Any) -> Computed[Any]
__add__(other)

Return a reactive value for the sum of self and other.

Parameters:

Name Type Description Default
other Any

The value to add.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value + other.value.

Example
>>> s = Signal(5)
>>> result = s + 3
>>> result.value
8
>>> s.value = 10
>>> result.value
13

__and__

__and__(other)

Return a reactive value for the bitwise AND of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to AND with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value & other.value.

Example
>>> s = Signal(True)
>>> result = s & False
>>> result.value
False
>>> s.value = True
>>> result.value
False

contains

contains(other)

Return a reactive value for whether other is in self.

Parameters:

Name Type Description Default
other Any

The value to check for containment.

required

Returns:

Type Description
Computed[bool]

A reactive value for other in self.value.

Example
>>> s = Signal([1, 2, 3, 4])
>>> result = s.contains(3)
>>> result.value
True
>>> s.value = [5, 6, 7, 8]
>>> result.value
False

__divmod__

__divmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__divmod__(other: HasValue[bool] | HasValue[int]) -> Computed[tuple[int, int]]
__divmod__(other: Any) -> Computed[tuple[float, float]]
__divmod__(other)

Return a reactive value for the divmod of self and other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[tuple[int, int]] | Computed[tuple[float, float]]

A reactive value for divmod(self.value, other).

Example
>>> s = Signal(10)
>>> result = divmod(s, 3)
>>> result.value
(3, 1)
>>> s.value = 20
>>> result.value
(6, 2)

is_not

is_not(other)

Return a reactive value for whether self is not other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value is not other.

Example
>>> s = Signal(10)
>>> other = None
>>> result = s.is_not(other)
>>> result.value
True
>>> s.value = None
>>> result.value
False

eq

eq(other)

Return a reactive value for whether self equals other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value == other.

Note

We can't overload __eq__ because it interferes with basic Python operations.

Example
>>> s = Signal(10)
>>> result = s.eq(10)
>>> result.value
True
>>> s.value = 25
>>> result.value
False

__floordiv__

__floordiv__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__floordiv__(other: HasValue[Y]) -> Computed[T | Y]
__floordiv__(other)

Return a reactive value for the floor division of self by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value // other.value.

Example
>>> s = Signal(20)
>>> result = s // 3
>>> result.value
6
>>> s.value = 25
>>> result.value
8

__ge__

__ge__(other)

Return a reactive value for whether self is greater than or equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value >= other.

Example
>>> s = Signal(10)
>>> result = s >= 5
>>> result.value
True
>>> s.value = 3
>>> result.value
False

__gt__

__gt__(other)

Return a reactive value for whether self is greater than other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value > other.

Example
>>> s = Signal(10)
>>> result = s > 5
>>> result.value
True
>>> s.value = 3
>>> result.value
False

__le__

__le__(other)

Return a reactive value for whether self is less than or equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value <= other.

Example
>>> s = Signal(5)
>>> result = s <= 5
>>> result.value
True
>>> s.value = 6
>>> result.value
False

__lt__

__lt__(other)

Return a reactive value for whether self is less than other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value < other.

Example
>>> s = Signal(5)
>>> result = s < 10
>>> result.value
True
>>> s.value = 15
>>> result.value
False

__lshift__

__lshift__(other)

Return a reactive value for self left-shifted by other.

Parameters:

Name Type Description Default
other HasValue[Y]

The number of positions to shift.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value << other.value.

Example
>>> s = Signal(8)
>>> result = s << 2
>>> result.value
32
>>> s.value = 3
>>> result.value
12

__matmul__

__matmul__(other)

Return a reactive value for the matrix multiplication of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to multiply with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value @ other.value.

Example
>>> import numpy as np
>>> s = Signal(np.array([1, 2]))
>>> result = s @ np.array([[1, 2], [3, 4]])
>>> result.value
array([ 7, 10])
>>> s.value = np.array([2, 3])
>>> result.value
array([11, 16])

__mod__

__mod__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__mod__(other: HasValue[Y]) -> Computed[T | Y]
__mod__(other)

Return a reactive value for self modulo other.

Parameters:

Name Type Description Default
other Any

The divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value % other.value.

Example
>>> s = Signal(17)
>>> result = s % 5
>>> result.value
2
>>> s.value = 23
>>> result.value
3

__mul__

__mul__(other: HasValue[int]) -> Computed[str]
__mul__(other: HasValue[int]) -> Computed[list[V]]
__mul__(other: HasValue[Y]) -> Computed[T | Y]
__mul__(other)

Return a reactive value for the product of self and other.

Parameters:

Name Type Description Default
other Any

The value to multiply with.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value * other.value.

Example
>>> s = Signal(4)
>>> result = s * 3
>>> result.value
12
>>> s.value = 5
>>> result.value
15

__ne__

__ne__(other)

Return a reactive value for whether self is not equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value != other.

Example
>>> s = Signal(5)
>>> result = s != 5
>>> result.value
False
>>> s.value = 6
>>> result.value
True

__or__

__or__(other)

Return a reactive value for the bitwise OR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to OR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value or other.value.

Example
>>> s = Signal(False)
>>> result = s | True
>>> result.value
True
>>> s.value = True
>>> result.value
True

__rshift__

__rshift__(other)

Return a reactive value for self right-shifted by other.

Parameters:

Name Type Description Default
other HasValue[Y]

The number of positions to shift.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value >> other.value.

Example
>>> s = Signal(32)
>>> result = s >> 2
>>> result.value
8
>>> s.value = 24
>>> result.value
6

__pow__

__pow__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__pow__(other: HasValue[Y]) -> Computed[T | Y]
__pow__(other)

Return a reactive value for self raised to the power of other.

Parameters:

Name Type Description Default
other Any

The exponent.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value ** other.value.

Example
>>> s = Signal(2)
>>> result = s ** 3
>>> result.value
8
>>> s.value = 3
>>> result.value
27

__sub__

__sub__(other)

Return a reactive value for the difference of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to subtract.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value - other.value.

Example
>>> s = Signal(10)
>>> result = s - 3
>>> result.value
7
>>> s.value = 15
>>> result.value
12

__truediv__

__truediv__(other: HasValue[int]) -> Computed[float]
__truediv__(other: HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[int]) -> Computed[float]
__truediv__(other: HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[bool] | HasValue[int] | HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[Y]) -> Computed[T | Y]
__truediv__(other)

Return a reactive value for self divided by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value / other.value.

Example
>>> s = Signal(20)
>>> result = s / 4
>>> result.value
5.0
>>> s.value = 30
>>> result.value
7.5

__xor__

__xor__(other)

Return a reactive value for the bitwise XOR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to XOR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value ^ other.value.

Example
>>> s = Signal(True)
>>> result = s ^ False
>>> result.value
True
>>> s.value = False
>>> result.value
False

__radd__

__radd__(other: HasValue[int] | HasValue[float]) -> Computed[float]
__radd__(other: HasValue[_SupportsAdd[T, R]]) -> Computed[R]
__radd__(other: Any) -> Computed[Any]
__radd__(other)

Return a reactive value for the sum of self and other.

Parameters:

Name Type Description Default
other Any

The value to add.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value + other.value.

Example
>>> s = Signal(5)
>>> result = 3 + s
>>> result.value
8
>>> s.value = 10
>>> result.value
13

__rand__

__rand__(other)

Return a reactive value for the bitwise AND of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to AND with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value and other.value.

Example
>>> s = Signal(True)
>>> result = False & s
>>> result.value
False
>>> s.value = True
>>> result.value
False

__rdivmod__

__rdivmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__rdivmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__rdivmod__(other: HasValue[bool]) -> Computed[tuple[int, int]]
__rdivmod__(other: Any) -> Computed[tuple[float, float]]
__rdivmod__(other)

Return a reactive value for the divmod of self and other.

Parameters:

Name Type Description Default
other Any

The value to use as the numerator.

required

Returns:

Type Description
Computed[tuple[int, int]] | Computed[tuple[float, float]]

A reactive value for divmod(other, self.value).

Example
>>> s = Signal(3)
>>> result = divmod(10, s)
>>> result.value
(3, 1)
>>> s.value = 4
>>> result.value
(2, 2)

__rfloordiv__

__rfloordiv__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rfloordiv__(other: HasValue[Y]) -> Computed[T | Y]
__rfloordiv__(other)

Return a reactive value for the floor division of other by self.

Parameters:

Name Type Description Default
other Any

The value to use as the numerator.

required

Returns:

Type Description
Computed[Any]

A reactive value for other.value // self.value.

Example
>>> s = Signal(3)
>>> result = 10 // s
>>> result.value
3
>>> s.value = 4
>>> result.value
2

__rmod__

__rmod__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rmod__(other: HasValue[Y]) -> Computed[T | Y]
__rmod__(other)

Return a reactive value for other modulo self.

Parameters:

Name Type Description Default
other Any

The dividend.

required

Returns:

Type Description
Computed[Any]

A reactive value for other.value % self.value.

Example
>>> s = Signal(3)
>>> result = 10 % s
>>> result.value
1
>>> s.value = 4
>>> result.value
2

__rmul__

__rmul__(other: HasValue[int]) -> Computed[str]
__rmul__(other: HasValue[int]) -> Computed[list[V]]
__rmul__(other: HasValue[Y]) -> Computed[T | Y]
__rmul__(other)

Return a reactive value for the product of self and other.

Parameters:

Name Type Description Default
other Any

The value to multiply with.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value * other.value.

Example
>>> s = Signal(4)
>>> result = 3 * s
>>> result.value
12
>>> s.value = 5
>>> result.value
15

__ror__

__ror__(other)

Return a reactive value for the bitwise OR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to OR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value or other.value.

Example
>>> s = Signal(False)
>>> result = True | s
>>> result.value
True
>>> s.value = True
>>> result.value
True

__rpow__

__rpow__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rpow__(other: HasValue[Y]) -> Computed[T | Y]
__rpow__(other)

Return a reactive value for self raised to the power of other.

Parameters:

Name Type Description Default
other Any

The base.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value ** other.value.

Example
>>> s = Signal(2)
>>> result = 3 ** s
>>> result.value
9
>>> s.value = 3
>>> result.value
27

__rsub__

__rsub__(other)

Return a reactive value for the difference of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to subtract from.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for other.value - self.value.

Example
>>> s = Signal(10)
>>> result = 15 - s
>>> result.value
5
>>> s.value = 15
>>> result.value
0

__rtruediv__

__rtruediv__(other: HasValue[int]) -> Computed[float]
__rtruediv__(other: HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[int]) -> Computed[float]
__rtruediv__(other: HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[bool] | HasValue[int] | HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[Y]) -> Computed[T | Y]
__rtruediv__(other)

Return a reactive value for self divided by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value / other.value.

Example
>>> s = Signal(2)
>>> result = 30 / s
>>> result.value
15.0
>>> s.value = 3
>>> result.value
10.0

__rxor__

__rxor__(other)

Return a reactive value for the bitwise XOR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to XOR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value ^ other.value.

Example
>>> s = Signal(True)
>>> result = False ^ s
>>> result.value
True
>>> s.value = False
>>> result.value
False

__getitem__

__getitem__(key: slice) -> Computed[list[V]]
__getitem__(key: slice) -> Computed[tuple[V, ...]]
__getitem__(key: slice) -> Computed[str]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[V]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[V]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[str]
__getitem__(key: HasValue[K]) -> Computed[V]
__getitem__(key: HasValue[K]) -> Computed[V]
__getitem__(key: Any) -> Computed[Any]
__getitem__(key)

Return a reactive value for the item or slice of self.

Parameters:

Name Type Description Default
key Any

The index or slice to retrieve.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value[key].

Example
>>> s = Signal([1, 2, 3, 4, 5])
>>> result = s[2]
>>> result.value
3
>>> s.value = [10, 20, 30, 40, 50]
>>> result.value
30

__setattr__

__setattr__(name, value)

Set an attribute on the underlying self.value.

Note

It is necessary to set the attribute via the Signal, rather than the underlying signal.value, to properly notify downstream observers of changes. Reason being, mutable objects that, for example, fallback to id comparison for equality checks will appear as if nothing changed even if one of its attributes changed.

Parameters:

Name Type Description Default
name str

The name of the attribute to access.

required
value Any

The value to set it to.

required
Example
    >>> class Person:
    ...    def __init__(self, name: str):
    ...        self.name = name
    ...    def greet(self) -> str:
    ...        return f"Hi, I'm {self.name}!"
    >>> s = Signal(Person("Alice"))
    >>> result = s.greet()
    >>> result.value
    "Hi, I'm Alice!"
    >>> s.name = "Bob"  # Modify attribute on Person instance through the reactive value s
    >>> result.value
    "Hi, I'm Bob!"

__setitem__

__setitem__(key, value)

Set an item on the underlying self.value.

Note

It is necessary to set the item via the Signal, rather than the underlying signal.value, to properly notify downstream observers of changes. Reason being, mutable objects that, for example, fallback to id comparison for equality checks will appear as if nothing changed even an element of the object is changed.

Parameters:

Name Type Description Default
key Any

The key to change.

required
value Any

The value to set it to.

required
Example

```py

s = Signal([1, 2, 3]) result = computed(sum)(s) result.value 6 s[1] = 4 result.value 8

where

where(a, b)

Return a reactive value for a if self is True, else b.

Parameters:

Name Type Description Default
a HasValue[A]

The value to return if self is True.

required
b HasValue[B]

The value to return if self is False.

required

Returns:

Type Description
Computed[A | B]

A reactive value for a if self.value else b.

Example
>>> condition = Signal(True)
>>> result = condition.where("Yes", "No")
>>> result.value
'Yes'
>>> condition.value = False
>>> result.value
'No'

Observer

Bases: Protocol

update

update()

Variable

Bases: ABC, ReactiveMixIn[T]

An abstract base class for reactive values.

A reactive value is an object that can be observed by observer for changes and can notify observers when its value changes. This class implements both the observer and observable patterns.

This class implements both the observer and observable pattern.

Subclasses should implement the update method.

Attributes:

Name Type Description
_observers list[Observer]

List of observers subscribed to this variable.

__slots__ class-attribute instance-attribute

__slots__ = ['_observers', '__name', '__weakref__']

__name instance-attribute

__name = ''

value property

value

The current value of the reactive object.

__init__

__init__()

Initialize the variable.

subscribe

subscribe(observer)

Subscribe an observer to this variable.

Parameters:

Name Type Description Default
observer Observer

The observer to subscribe.

required

unsubscribe

unsubscribe(observer)

Unsubscribe an observer from this variable.

Parameters:

Name Type Description Default
observer Observer

The observer to unsubscribe.

required

observe

observe(items)

Subscribe the observer (self) to all items that are Observable.

This method handles arbitrarily nested iterables.

Parameters:

Name Type Description Default
items Any

A single item, an iterable, or a nested structure of items to potentially subscribe to.

required

Returns:

Type Description
Self

self

unobserve

unobserve(items)

Unsubscribe the observer (self) from all items that are Observable.

Parameters:

Name Type Description Default
items Any

A single item or an iterable of items to potentially unsubscribe from.

required

Returns:

Type Description
Self

self

notify

notify()

Notify all observers by calling their update method.

__repr__

__repr__()

Represent the object in a way that shows the inner value.

update abstractmethod

update()

Update method to be overridden by subclasses.

Raises:

Type Description
NotImplementedError

If not overridden by a subclass.

add_name

add_name(name)

__format__

__format__(format_spec)

Format the variable with custom display options.

Format options: :n - just the name (or type+id if unnamed) :d - full debug info empty - just the value in brackets (default)

__getattr__

__getattr__(name: Literal['value', '_value']) -> T
__getattr__(name: str) -> Computed[Any]
__getattr__(name)

Create a reactive value for retrieving an attribute from self.value.

Parameters:

Name Type Description Default
name str

The name of the attribute to access.

required

Returns:

Type Description
Union[T, Computed[Any]]

A reactive value for the attribute access.

Raises:

Type Description
AttributeError

If the attribute doesn't exist.

Note

Type inference is poor whenever __getattr__ is used.

Example
>>> class Person:
...     def __init__(self, name):
...         self.name = name
>>> s = Signal(Person("Alice"))
>>> result = s.name
>>> result.value
'Alice'
>>> s.value = Person("Bob")
>>> result.value
'Bob'

__call__

__call__(*args, **kwargs)

Create a reactive value for calling self.value(*args, **kwargs).

Parameters:

Name Type Description Default
*args P.args

Positional arguments to pass to the callable value.

()
**kwargs P.kwargs

Keyword arguments to pass to the callable value.

{}

Returns:

Type Description
Computed[R]

A reactive value for the function call.

Raises:

Type Description
ValueError

If the value is not callable.

Example
>>> class Person:
...     def __init__(self, name):
...         self.name = name
...     def greet(self):
...         return f"Hi, I'm {self.name}!"
>>> s = Signal(Person("Alice"))
>>> result = s.greet()
>>> result.value
"Hi, I'm Alice!"
>>> s.name = "Bob"
>>> result.value
"Hi, I'm Bob!"

__abs__

__abs__() -> Computed[float]
__abs__() -> Computed[int]
__abs__() -> Computed[T]
__abs__()

Return a reactive value for the absolute value of self.

Returns:

Type Description
Computed[T] | Computed[float] | Computed[int]

A reactive value for abs(self.value).

Example
>>> s = Signal(-5)
>>> result = abs(s)
>>> result.value
5
>>> s.value = -10
>>> result.value
10

as_bool

as_bool()

Return a reactive value for the boolean value of self.

Note

__bool__ cannot be implemented to return a non-bool, so it is provided as a method.

Returns:

Type Description
Computed[bool]

A reactive value for bool(self.value).

Example
>>> s = Signal(1)
>>> result = s.as_bool()
>>> result.value
True
>>> s.value = 0
>>> result.value
False

__str__

__str__()

Return a string of the current value.

Note

This is not reactive.

Returns:

Type Description
str

A string representation of self.value.

__round__

__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[int]
__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[int]
__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[float]
__round__(ndigits: int | None = None) -> Computed[int] | Computed[float]
__round__(ndigits=None)

Return a reactive value for the rounded value of self.

Parameters:

Name Type Description Default
ndigits int | None

Number of decimal places to round to.

None

Returns:

Type Description
Computed[int] | Computed[float]

A reactive value for round(self.value, ndigits).

Example
>>> s = Signal(3.14159)
>>> result = round(s, 2)
>>> result.value
3.14
>>> s.value = 2.71828
>>> result.value
2.72

__ceil__

__ceil__()

Return a reactive value for the ceiling of self.

Returns:

Type Description
Computed[int]

A reactive value for math.ceil(self.value).

Example
>>> from math import ceil
>>> s = Signal(3.14)
>>> result = ceil(s)
>>> result.value
4
>>> s.value = 2.01
>>> result.value
3

__floor__

__floor__()

Return a reactive value for the floor of self.

Returns:

Type Description
Computed[int]

A reactive value for math.floor(self.value).

Example
>>> from math import floor
>>> s = Signal(3.99)
>>> result = floor(s)
>>> result.value
3
>>> s.value = 4.01
>>> result.value
4

__invert__

__invert__() -> Computed[int]
__invert__() -> Computed[T]
__invert__()

Return a reactive value for the bitwise inversion of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for ~self.value.

Example
>>> s = Signal(5)
>>> result = ~s
>>> result.value
-6
>>> s.value = -3
>>> result.value
2

__neg__

__neg__() -> Computed[int]
__neg__() -> Computed[T]
__neg__()

Return a reactive value for the negation of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for -self.value.

Example
>>> s = Signal(5)
>>> result = -s
>>> result.value
-5
>>> s.value = -3
>>> result.value
3

__pos__

__pos__() -> Computed[int]
__pos__() -> Computed[T]
__pos__()

Return a reactive value for the positive of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for +self.value.

Example
>>> s = Signal(-5)
>>> result = +s
>>> result.value
-5
>>> s.value = 3
>>> result.value
3

__trunc__

__trunc__() -> Computed[int]
__trunc__() -> Computed[int]
__trunc__() -> Computed[int]
__trunc__() -> Computed[T]
__trunc__()

Return a reactive value for the truncated value of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for math.trunc(self.value).

Example
>>> from math import trunc
>>> s = Signal(3.99)
>>> result = trunc(s)
>>> result.value
3
>>> s.value = -4.01
>>> result.value
-4

__add__

__add__(other: HasValue[int] | HasValue[float]) -> Computed[float]
__add__(other: HasValue[float]) -> Computed[float]
__add__(other: HasValue[Y]) -> Computed[R]
__add__(other: Any) -> Computed[Any]
__add__(other)

Return a reactive value for the sum of self and other.

Parameters:

Name Type Description Default
other Any

The value to add.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value + other.value.

Example
>>> s = Signal(5)
>>> result = s + 3
>>> result.value
8
>>> s.value = 10
>>> result.value
13

__and__

__and__(other)

Return a reactive value for the bitwise AND of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to AND with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value & other.value.

Example
>>> s = Signal(True)
>>> result = s & False
>>> result.value
False
>>> s.value = True
>>> result.value
False

contains

contains(other)

Return a reactive value for whether other is in self.

Parameters:

Name Type Description Default
other Any

The value to check for containment.

required

Returns:

Type Description
Computed[bool]

A reactive value for other in self.value.

Example
>>> s = Signal([1, 2, 3, 4])
>>> result = s.contains(3)
>>> result.value
True
>>> s.value = [5, 6, 7, 8]
>>> result.value
False

__divmod__

__divmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__divmod__(other: HasValue[bool] | HasValue[int]) -> Computed[tuple[int, int]]
__divmod__(other: Any) -> Computed[tuple[float, float]]
__divmod__(other)

Return a reactive value for the divmod of self and other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[tuple[int, int]] | Computed[tuple[float, float]]

A reactive value for divmod(self.value, other).

Example
>>> s = Signal(10)
>>> result = divmod(s, 3)
>>> result.value
(3, 1)
>>> s.value = 20
>>> result.value
(6, 2)

is_not

is_not(other)

Return a reactive value for whether self is not other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value is not other.

Example
>>> s = Signal(10)
>>> other = None
>>> result = s.is_not(other)
>>> result.value
True
>>> s.value = None
>>> result.value
False

eq

eq(other)

Return a reactive value for whether self equals other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value == other.

Note

We can't overload __eq__ because it interferes with basic Python operations.

Example
>>> s = Signal(10)
>>> result = s.eq(10)
>>> result.value
True
>>> s.value = 25
>>> result.value
False

__floordiv__

__floordiv__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__floordiv__(other: HasValue[Y]) -> Computed[T | Y]
__floordiv__(other)

Return a reactive value for the floor division of self by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value // other.value.

Example
>>> s = Signal(20)
>>> result = s // 3
>>> result.value
6
>>> s.value = 25
>>> result.value
8

__ge__

__ge__(other)

Return a reactive value for whether self is greater than or equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value >= other.

Example
>>> s = Signal(10)
>>> result = s >= 5
>>> result.value
True
>>> s.value = 3
>>> result.value
False

__gt__

__gt__(other)

Return a reactive value for whether self is greater than other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value > other.

Example
>>> s = Signal(10)
>>> result = s > 5
>>> result.value
True
>>> s.value = 3
>>> result.value
False

__le__

__le__(other)

Return a reactive value for whether self is less than or equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value <= other.

Example
>>> s = Signal(5)
>>> result = s <= 5
>>> result.value
True
>>> s.value = 6
>>> result.value
False

__lt__

__lt__(other)

Return a reactive value for whether self is less than other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value < other.

Example
>>> s = Signal(5)
>>> result = s < 10
>>> result.value
True
>>> s.value = 15
>>> result.value
False

__lshift__

__lshift__(other)

Return a reactive value for self left-shifted by other.

Parameters:

Name Type Description Default
other HasValue[Y]

The number of positions to shift.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value << other.value.

Example
>>> s = Signal(8)
>>> result = s << 2
>>> result.value
32
>>> s.value = 3
>>> result.value
12

__matmul__

__matmul__(other)

Return a reactive value for the matrix multiplication of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to multiply with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value @ other.value.

Example
>>> import numpy as np
>>> s = Signal(np.array([1, 2]))
>>> result = s @ np.array([[1, 2], [3, 4]])
>>> result.value
array([ 7, 10])
>>> s.value = np.array([2, 3])
>>> result.value
array([11, 16])

__mod__

__mod__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__mod__(other: HasValue[Y]) -> Computed[T | Y]
__mod__(other)

Return a reactive value for self modulo other.

Parameters:

Name Type Description Default
other Any

The divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value % other.value.

Example
>>> s = Signal(17)
>>> result = s % 5
>>> result.value
2
>>> s.value = 23
>>> result.value
3

__mul__

__mul__(other: HasValue[int]) -> Computed[str]
__mul__(other: HasValue[int]) -> Computed[list[V]]
__mul__(other: HasValue[Y]) -> Computed[T | Y]
__mul__(other)

Return a reactive value for the product of self and other.

Parameters:

Name Type Description Default
other Any

The value to multiply with.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value * other.value.

Example
>>> s = Signal(4)
>>> result = s * 3
>>> result.value
12
>>> s.value = 5
>>> result.value
15

__ne__

__ne__(other)

Return a reactive value for whether self is not equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value != other.

Example
>>> s = Signal(5)
>>> result = s != 5
>>> result.value
False
>>> s.value = 6
>>> result.value
True

__or__

__or__(other)

Return a reactive value for the bitwise OR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to OR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value or other.value.

Example
>>> s = Signal(False)
>>> result = s | True
>>> result.value
True
>>> s.value = True
>>> result.value
True

__rshift__

__rshift__(other)

Return a reactive value for self right-shifted by other.

Parameters:

Name Type Description Default
other HasValue[Y]

The number of positions to shift.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value >> other.value.

Example
>>> s = Signal(32)
>>> result = s >> 2
>>> result.value
8
>>> s.value = 24
>>> result.value
6

__pow__

__pow__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__pow__(other: HasValue[Y]) -> Computed[T | Y]
__pow__(other)

Return a reactive value for self raised to the power of other.

Parameters:

Name Type Description Default
other Any

The exponent.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value ** other.value.

Example
>>> s = Signal(2)
>>> result = s ** 3
>>> result.value
8
>>> s.value = 3
>>> result.value
27

__sub__

__sub__(other)

Return a reactive value for the difference of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to subtract.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value - other.value.

Example
>>> s = Signal(10)
>>> result = s - 3
>>> result.value
7
>>> s.value = 15
>>> result.value
12

__truediv__

__truediv__(other: HasValue[int]) -> Computed[float]
__truediv__(other: HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[int]) -> Computed[float]
__truediv__(other: HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[bool] | HasValue[int] | HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[Y]) -> Computed[T | Y]
__truediv__(other)

Return a reactive value for self divided by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value / other.value.

Example
>>> s = Signal(20)
>>> result = s / 4
>>> result.value
5.0
>>> s.value = 30
>>> result.value
7.5

__xor__

__xor__(other)

Return a reactive value for the bitwise XOR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to XOR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value ^ other.value.

Example
>>> s = Signal(True)
>>> result = s ^ False
>>> result.value
True
>>> s.value = False
>>> result.value
False

__radd__

__radd__(other: HasValue[int] | HasValue[float]) -> Computed[float]
__radd__(other: HasValue[_SupportsAdd[T, R]]) -> Computed[R]
__radd__(other: Any) -> Computed[Any]
__radd__(other)

Return a reactive value for the sum of self and other.

Parameters:

Name Type Description Default
other Any

The value to add.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value + other.value.

Example
>>> s = Signal(5)
>>> result = 3 + s
>>> result.value
8
>>> s.value = 10
>>> result.value
13

__rand__

__rand__(other)

Return a reactive value for the bitwise AND of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to AND with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value and other.value.

Example
>>> s = Signal(True)
>>> result = False & s
>>> result.value
False
>>> s.value = True
>>> result.value
False

__rdivmod__

__rdivmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__rdivmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__rdivmod__(other: HasValue[bool]) -> Computed[tuple[int, int]]
__rdivmod__(other: Any) -> Computed[tuple[float, float]]
__rdivmod__(other)

Return a reactive value for the divmod of self and other.

Parameters:

Name Type Description Default
other Any

The value to use as the numerator.

required

Returns:

Type Description
Computed[tuple[int, int]] | Computed[tuple[float, float]]

A reactive value for divmod(other, self.value).

Example
>>> s = Signal(3)
>>> result = divmod(10, s)
>>> result.value
(3, 1)
>>> s.value = 4
>>> result.value
(2, 2)

__rfloordiv__

__rfloordiv__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rfloordiv__(other: HasValue[Y]) -> Computed[T | Y]
__rfloordiv__(other)

Return a reactive value for the floor division of other by self.

Parameters:

Name Type Description Default
other Any

The value to use as the numerator.

required

Returns:

Type Description
Computed[Any]

A reactive value for other.value // self.value.

Example
>>> s = Signal(3)
>>> result = 10 // s
>>> result.value
3
>>> s.value = 4
>>> result.value
2

__rmod__

__rmod__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rmod__(other: HasValue[Y]) -> Computed[T | Y]
__rmod__(other)

Return a reactive value for other modulo self.

Parameters:

Name Type Description Default
other Any

The dividend.

required

Returns:

Type Description
Computed[Any]

A reactive value for other.value % self.value.

Example
>>> s = Signal(3)
>>> result = 10 % s
>>> result.value
1
>>> s.value = 4
>>> result.value
2

__rmul__

__rmul__(other: HasValue[int]) -> Computed[str]
__rmul__(other: HasValue[int]) -> Computed[list[V]]
__rmul__(other: HasValue[Y]) -> Computed[T | Y]
__rmul__(other)

Return a reactive value for the product of self and other.

Parameters:

Name Type Description Default
other Any

The value to multiply with.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value * other.value.

Example
>>> s = Signal(4)
>>> result = 3 * s
>>> result.value
12
>>> s.value = 5
>>> result.value
15

__ror__

__ror__(other)

Return a reactive value for the bitwise OR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to OR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value or other.value.

Example
>>> s = Signal(False)
>>> result = True | s
>>> result.value
True
>>> s.value = True
>>> result.value
True

__rpow__

__rpow__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rpow__(other: HasValue[Y]) -> Computed[T | Y]
__rpow__(other)

Return a reactive value for self raised to the power of other.

Parameters:

Name Type Description Default
other Any

The base.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value ** other.value.

Example
>>> s = Signal(2)
>>> result = 3 ** s
>>> result.value
9
>>> s.value = 3
>>> result.value
27

__rsub__

__rsub__(other)

Return a reactive value for the difference of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to subtract from.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for other.value - self.value.

Example
>>> s = Signal(10)
>>> result = 15 - s
>>> result.value
5
>>> s.value = 15
>>> result.value
0

__rtruediv__

__rtruediv__(other: HasValue[int]) -> Computed[float]
__rtruediv__(other: HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[int]) -> Computed[float]
__rtruediv__(other: HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[bool] | HasValue[int] | HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[Y]) -> Computed[T | Y]
__rtruediv__(other)

Return a reactive value for self divided by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value / other.value.

Example
>>> s = Signal(2)
>>> result = 30 / s
>>> result.value
15.0
>>> s.value = 3
>>> result.value
10.0

__rxor__

__rxor__(other)

Return a reactive value for the bitwise XOR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to XOR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value ^ other.value.

Example
>>> s = Signal(True)
>>> result = False ^ s
>>> result.value
True
>>> s.value = False
>>> result.value
False

__getitem__

__getitem__(key: slice) -> Computed[list[V]]
__getitem__(key: slice) -> Computed[tuple[V, ...]]
__getitem__(key: slice) -> Computed[str]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[V]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[V]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[str]
__getitem__(key: HasValue[K]) -> Computed[V]
__getitem__(key: HasValue[K]) -> Computed[V]
__getitem__(key: Any) -> Computed[Any]
__getitem__(key)

Return a reactive value for the item or slice of self.

Parameters:

Name Type Description Default
key Any

The index or slice to retrieve.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value[key].

Example
>>> s = Signal([1, 2, 3, 4, 5])
>>> result = s[2]
>>> result.value
3
>>> s.value = [10, 20, 30, 40, 50]
>>> result.value
30

__setattr__

__setattr__(name, value)

Set an attribute on the underlying self.value.

Note

It is necessary to set the attribute via the Signal, rather than the underlying signal.value, to properly notify downstream observers of changes. Reason being, mutable objects that, for example, fallback to id comparison for equality checks will appear as if nothing changed even if one of its attributes changed.

Parameters:

Name Type Description Default
name str

The name of the attribute to access.

required
value Any

The value to set it to.

required
Example
    >>> class Person:
    ...    def __init__(self, name: str):
    ...        self.name = name
    ...    def greet(self) -> str:
    ...        return f"Hi, I'm {self.name}!"
    >>> s = Signal(Person("Alice"))
    >>> result = s.greet()
    >>> result.value
    "Hi, I'm Alice!"
    >>> s.name = "Bob"  # Modify attribute on Person instance through the reactive value s
    >>> result.value
    "Hi, I'm Bob!"

__setitem__

__setitem__(key, value)

Set an item on the underlying self.value.

Note

It is necessary to set the item via the Signal, rather than the underlying signal.value, to properly notify downstream observers of changes. Reason being, mutable objects that, for example, fallback to id comparison for equality checks will appear as if nothing changed even an element of the object is changed.

Parameters:

Name Type Description Default
key Any

The key to change.

required
value Any

The value to set it to.

required
Example

```py

s = Signal([1, 2, 3]) result = computed(sum)(s) result.value 6 s[1] = 4 result.value 8

where

where(a, b)

Return a reactive value for a if self is True, else b.

Parameters:

Name Type Description Default
a HasValue[A]

The value to return if self is True.

required
b HasValue[B]

The value to return if self is False.

required

Returns:

Type Description
Computed[A | B]

A reactive value for a if self.value else b.

Example
>>> condition = Signal(True)
>>> result = condition.where("Yes", "No")
>>> result.value
'Yes'
>>> condition.value = False
>>> result.value
'No'

Signal

Bases: Variable[T]

Mutable source-of-truth reactive value.

Signal stores a value and notifies subscribers when that value changes. It is typically used for application state that should be observed by derived :class:Computed values.

The value property is read/write: - reading value returns the resolved plain value - assigning value updates dependencies and notifies observers when the value changed

Signals can also proxy mutation operations (for example __setattr__ and __setitem__) so in-place updates on wrapped objects can still trigger reactivity.

Parameters:

Name Type Description Default
value HasValue[T]

Initial value to wrap. May be plain or reactive.

required
Example
>>> count = Signal(1)
>>> doubled = count * 2
>>> doubled.value
2
>>> count.value = 3
>>> doubled.value
6

__slots__ class-attribute instance-attribute

__slots__ = ['_value']

value property writable

value

Get or set the current value.

__name instance-attribute

__name = ''

__init__

__init__(value: ReactiveValue[T]) -> None
__init__(value: T) -> None
__init__(value)

at

at(value)

Temporarily set the signal to a given value within a context.

update

update()

Update the signal and notify subscribers.

notify

notify()

Notify all observers by calling their update method.

__getattr__

__getattr__(name: Literal['value', '_value']) -> T
__getattr__(name: str) -> Computed[Any]
__getattr__(name)

Create a reactive value for retrieving an attribute from self.value.

Parameters:

Name Type Description Default
name str

The name of the attribute to access.

required

Returns:

Type Description
Union[T, Computed[Any]]

A reactive value for the attribute access.

Raises:

Type Description
AttributeError

If the attribute doesn't exist.

Note

Type inference is poor whenever __getattr__ is used.

Example
>>> class Person:
...     def __init__(self, name):
...         self.name = name
>>> s = Signal(Person("Alice"))
>>> result = s.name
>>> result.value
'Alice'
>>> s.value = Person("Bob")
>>> result.value
'Bob'

__call__

__call__(*args, **kwargs)

Create a reactive value for calling self.value(*args, **kwargs).

Parameters:

Name Type Description Default
*args P.args

Positional arguments to pass to the callable value.

()
**kwargs P.kwargs

Keyword arguments to pass to the callable value.

{}

Returns:

Type Description
Computed[R]

A reactive value for the function call.

Raises:

Type Description
ValueError

If the value is not callable.

Example
>>> class Person:
...     def __init__(self, name):
...         self.name = name
...     def greet(self):
...         return f"Hi, I'm {self.name}!"
>>> s = Signal(Person("Alice"))
>>> result = s.greet()
>>> result.value
"Hi, I'm Alice!"
>>> s.name = "Bob"
>>> result.value
"Hi, I'm Bob!"

__abs__

__abs__() -> Computed[float]
__abs__() -> Computed[int]
__abs__() -> Computed[T]
__abs__()

Return a reactive value for the absolute value of self.

Returns:

Type Description
Computed[T] | Computed[float] | Computed[int]

A reactive value for abs(self.value).

Example
>>> s = Signal(-5)
>>> result = abs(s)
>>> result.value
5
>>> s.value = -10
>>> result.value
10

as_bool

as_bool()

Return a reactive value for the boolean value of self.

Note

__bool__ cannot be implemented to return a non-bool, so it is provided as a method.

Returns:

Type Description
Computed[bool]

A reactive value for bool(self.value).

Example
>>> s = Signal(1)
>>> result = s.as_bool()
>>> result.value
True
>>> s.value = 0
>>> result.value
False

__str__

__str__()

Return a string of the current value.

Note

This is not reactive.

Returns:

Type Description
str

A string representation of self.value.

__round__

__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[int]
__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[int]
__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[float]
__round__(ndigits: int | None = None) -> Computed[int] | Computed[float]
__round__(ndigits=None)

Return a reactive value for the rounded value of self.

Parameters:

Name Type Description Default
ndigits int | None

Number of decimal places to round to.

None

Returns:

Type Description
Computed[int] | Computed[float]

A reactive value for round(self.value, ndigits).

Example
>>> s = Signal(3.14159)
>>> result = round(s, 2)
>>> result.value
3.14
>>> s.value = 2.71828
>>> result.value
2.72

__ceil__

__ceil__()

Return a reactive value for the ceiling of self.

Returns:

Type Description
Computed[int]

A reactive value for math.ceil(self.value).

Example
>>> from math import ceil
>>> s = Signal(3.14)
>>> result = ceil(s)
>>> result.value
4
>>> s.value = 2.01
>>> result.value
3

__floor__

__floor__()

Return a reactive value for the floor of self.

Returns:

Type Description
Computed[int]

A reactive value for math.floor(self.value).

Example
>>> from math import floor
>>> s = Signal(3.99)
>>> result = floor(s)
>>> result.value
3
>>> s.value = 4.01
>>> result.value
4

__invert__

__invert__() -> Computed[int]
__invert__() -> Computed[T]
__invert__()

Return a reactive value for the bitwise inversion of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for ~self.value.

Example
>>> s = Signal(5)
>>> result = ~s
>>> result.value
-6
>>> s.value = -3
>>> result.value
2

__neg__

__neg__() -> Computed[int]
__neg__() -> Computed[T]
__neg__()

Return a reactive value for the negation of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for -self.value.

Example
>>> s = Signal(5)
>>> result = -s
>>> result.value
-5
>>> s.value = -3
>>> result.value
3

__pos__

__pos__() -> Computed[int]
__pos__() -> Computed[T]
__pos__()

Return a reactive value for the positive of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for +self.value.

Example
>>> s = Signal(-5)
>>> result = +s
>>> result.value
-5
>>> s.value = 3
>>> result.value
3

__trunc__

__trunc__() -> Computed[int]
__trunc__() -> Computed[int]
__trunc__() -> Computed[int]
__trunc__() -> Computed[T]
__trunc__()

Return a reactive value for the truncated value of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for math.trunc(self.value).

Example
>>> from math import trunc
>>> s = Signal(3.99)
>>> result = trunc(s)
>>> result.value
3
>>> s.value = -4.01
>>> result.value
-4

__add__

__add__(other: HasValue[int] | HasValue[float]) -> Computed[float]
__add__(other: HasValue[float]) -> Computed[float]
__add__(other: HasValue[Y]) -> Computed[R]
__add__(other: Any) -> Computed[Any]
__add__(other)

Return a reactive value for the sum of self and other.

Parameters:

Name Type Description Default
other Any

The value to add.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value + other.value.

Example
>>> s = Signal(5)
>>> result = s + 3
>>> result.value
8
>>> s.value = 10
>>> result.value
13

__and__

__and__(other)

Return a reactive value for the bitwise AND of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to AND with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value & other.value.

Example
>>> s = Signal(True)
>>> result = s & False
>>> result.value
False
>>> s.value = True
>>> result.value
False

contains

contains(other)

Return a reactive value for whether other is in self.

Parameters:

Name Type Description Default
other Any

The value to check for containment.

required

Returns:

Type Description
Computed[bool]

A reactive value for other in self.value.

Example
>>> s = Signal([1, 2, 3, 4])
>>> result = s.contains(3)
>>> result.value
True
>>> s.value = [5, 6, 7, 8]
>>> result.value
False

__divmod__

__divmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__divmod__(other: HasValue[bool] | HasValue[int]) -> Computed[tuple[int, int]]
__divmod__(other: Any) -> Computed[tuple[float, float]]
__divmod__(other)

Return a reactive value for the divmod of self and other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[tuple[int, int]] | Computed[tuple[float, float]]

A reactive value for divmod(self.value, other).

Example
>>> s = Signal(10)
>>> result = divmod(s, 3)
>>> result.value
(3, 1)
>>> s.value = 20
>>> result.value
(6, 2)

is_not

is_not(other)

Return a reactive value for whether self is not other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value is not other.

Example
>>> s = Signal(10)
>>> other = None
>>> result = s.is_not(other)
>>> result.value
True
>>> s.value = None
>>> result.value
False

eq

eq(other)

Return a reactive value for whether self equals other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value == other.

Note

We can't overload __eq__ because it interferes with basic Python operations.

Example
>>> s = Signal(10)
>>> result = s.eq(10)
>>> result.value
True
>>> s.value = 25
>>> result.value
False

__floordiv__

__floordiv__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__floordiv__(other: HasValue[Y]) -> Computed[T | Y]
__floordiv__(other)

Return a reactive value for the floor division of self by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value // other.value.

Example
>>> s = Signal(20)
>>> result = s // 3
>>> result.value
6
>>> s.value = 25
>>> result.value
8

__ge__

__ge__(other)

Return a reactive value for whether self is greater than or equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value >= other.

Example
>>> s = Signal(10)
>>> result = s >= 5
>>> result.value
True
>>> s.value = 3
>>> result.value
False

__gt__

__gt__(other)

Return a reactive value for whether self is greater than other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value > other.

Example
>>> s = Signal(10)
>>> result = s > 5
>>> result.value
True
>>> s.value = 3
>>> result.value
False

__le__

__le__(other)

Return a reactive value for whether self is less than or equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value <= other.

Example
>>> s = Signal(5)
>>> result = s <= 5
>>> result.value
True
>>> s.value = 6
>>> result.value
False

__lt__

__lt__(other)

Return a reactive value for whether self is less than other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value < other.

Example
>>> s = Signal(5)
>>> result = s < 10
>>> result.value
True
>>> s.value = 15
>>> result.value
False

__lshift__

__lshift__(other)

Return a reactive value for self left-shifted by other.

Parameters:

Name Type Description Default
other HasValue[Y]

The number of positions to shift.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value << other.value.

Example
>>> s = Signal(8)
>>> result = s << 2
>>> result.value
32
>>> s.value = 3
>>> result.value
12

__matmul__

__matmul__(other)

Return a reactive value for the matrix multiplication of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to multiply with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value @ other.value.

Example
>>> import numpy as np
>>> s = Signal(np.array([1, 2]))
>>> result = s @ np.array([[1, 2], [3, 4]])
>>> result.value
array([ 7, 10])
>>> s.value = np.array([2, 3])
>>> result.value
array([11, 16])

__mod__

__mod__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__mod__(other: HasValue[Y]) -> Computed[T | Y]
__mod__(other)

Return a reactive value for self modulo other.

Parameters:

Name Type Description Default
other Any

The divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value % other.value.

Example
>>> s = Signal(17)
>>> result = s % 5
>>> result.value
2
>>> s.value = 23
>>> result.value
3

__mul__

__mul__(other: HasValue[int]) -> Computed[str]
__mul__(other: HasValue[int]) -> Computed[list[V]]
__mul__(other: HasValue[Y]) -> Computed[T | Y]
__mul__(other)

Return a reactive value for the product of self and other.

Parameters:

Name Type Description Default
other Any

The value to multiply with.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value * other.value.

Example
>>> s = Signal(4)
>>> result = s * 3
>>> result.value
12
>>> s.value = 5
>>> result.value
15

__ne__

__ne__(other)

Return a reactive value for whether self is not equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value != other.

Example
>>> s = Signal(5)
>>> result = s != 5
>>> result.value
False
>>> s.value = 6
>>> result.value
True

__or__

__or__(other)

Return a reactive value for the bitwise OR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to OR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value or other.value.

Example
>>> s = Signal(False)
>>> result = s | True
>>> result.value
True
>>> s.value = True
>>> result.value
True

__rshift__

__rshift__(other)

Return a reactive value for self right-shifted by other.

Parameters:

Name Type Description Default
other HasValue[Y]

The number of positions to shift.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value >> other.value.

Example
>>> s = Signal(32)
>>> result = s >> 2
>>> result.value
8
>>> s.value = 24
>>> result.value
6

__pow__

__pow__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__pow__(other: HasValue[Y]) -> Computed[T | Y]
__pow__(other)

Return a reactive value for self raised to the power of other.

Parameters:

Name Type Description Default
other Any

The exponent.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value ** other.value.

Example
>>> s = Signal(2)
>>> result = s ** 3
>>> result.value
8
>>> s.value = 3
>>> result.value
27

__sub__

__sub__(other)

Return a reactive value for the difference of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to subtract.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value - other.value.

Example
>>> s = Signal(10)
>>> result = s - 3
>>> result.value
7
>>> s.value = 15
>>> result.value
12

__truediv__

__truediv__(other: HasValue[int]) -> Computed[float]
__truediv__(other: HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[int]) -> Computed[float]
__truediv__(other: HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[bool] | HasValue[int] | HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[Y]) -> Computed[T | Y]
__truediv__(other)

Return a reactive value for self divided by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value / other.value.

Example
>>> s = Signal(20)
>>> result = s / 4
>>> result.value
5.0
>>> s.value = 30
>>> result.value
7.5

__xor__

__xor__(other)

Return a reactive value for the bitwise XOR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to XOR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value ^ other.value.

Example
>>> s = Signal(True)
>>> result = s ^ False
>>> result.value
True
>>> s.value = False
>>> result.value
False

__radd__

__radd__(other: HasValue[int] | HasValue[float]) -> Computed[float]
__radd__(other: HasValue[_SupportsAdd[T, R]]) -> Computed[R]
__radd__(other: Any) -> Computed[Any]
__radd__(other)

Return a reactive value for the sum of self and other.

Parameters:

Name Type Description Default
other Any

The value to add.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value + other.value.

Example
>>> s = Signal(5)
>>> result = 3 + s
>>> result.value
8
>>> s.value = 10
>>> result.value
13

__rand__

__rand__(other)

Return a reactive value for the bitwise AND of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to AND with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value and other.value.

Example
>>> s = Signal(True)
>>> result = False & s
>>> result.value
False
>>> s.value = True
>>> result.value
False

__rdivmod__

__rdivmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__rdivmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__rdivmod__(other: HasValue[bool]) -> Computed[tuple[int, int]]
__rdivmod__(other: Any) -> Computed[tuple[float, float]]
__rdivmod__(other)

Return a reactive value for the divmod of self and other.

Parameters:

Name Type Description Default
other Any

The value to use as the numerator.

required

Returns:

Type Description
Computed[tuple[int, int]] | Computed[tuple[float, float]]

A reactive value for divmod(other, self.value).

Example
>>> s = Signal(3)
>>> result = divmod(10, s)
>>> result.value
(3, 1)
>>> s.value = 4
>>> result.value
(2, 2)

__rfloordiv__

__rfloordiv__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rfloordiv__(other: HasValue[Y]) -> Computed[T | Y]
__rfloordiv__(other)

Return a reactive value for the floor division of other by self.

Parameters:

Name Type Description Default
other Any

The value to use as the numerator.

required

Returns:

Type Description
Computed[Any]

A reactive value for other.value // self.value.

Example
>>> s = Signal(3)
>>> result = 10 // s
>>> result.value
3
>>> s.value = 4
>>> result.value
2

__rmod__

__rmod__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rmod__(other: HasValue[Y]) -> Computed[T | Y]
__rmod__(other)

Return a reactive value for other modulo self.

Parameters:

Name Type Description Default
other Any

The dividend.

required

Returns:

Type Description
Computed[Any]

A reactive value for other.value % self.value.

Example
>>> s = Signal(3)
>>> result = 10 % s
>>> result.value
1
>>> s.value = 4
>>> result.value
2

__rmul__

__rmul__(other: HasValue[int]) -> Computed[str]
__rmul__(other: HasValue[int]) -> Computed[list[V]]
__rmul__(other: HasValue[Y]) -> Computed[T | Y]
__rmul__(other)

Return a reactive value for the product of self and other.

Parameters:

Name Type Description Default
other Any

The value to multiply with.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value * other.value.

Example
>>> s = Signal(4)
>>> result = 3 * s
>>> result.value
12
>>> s.value = 5
>>> result.value
15

__ror__

__ror__(other)

Return a reactive value for the bitwise OR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to OR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value or other.value.

Example
>>> s = Signal(False)
>>> result = True | s
>>> result.value
True
>>> s.value = True
>>> result.value
True

__rpow__

__rpow__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rpow__(other: HasValue[Y]) -> Computed[T | Y]
__rpow__(other)

Return a reactive value for self raised to the power of other.

Parameters:

Name Type Description Default
other Any

The base.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value ** other.value.

Example
>>> s = Signal(2)
>>> result = 3 ** s
>>> result.value
9
>>> s.value = 3
>>> result.value
27

__rsub__

__rsub__(other)

Return a reactive value for the difference of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to subtract from.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for other.value - self.value.

Example
>>> s = Signal(10)
>>> result = 15 - s
>>> result.value
5
>>> s.value = 15
>>> result.value
0

__rtruediv__

__rtruediv__(other: HasValue[int]) -> Computed[float]
__rtruediv__(other: HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[int]) -> Computed[float]
__rtruediv__(other: HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[bool] | HasValue[int] | HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[Y]) -> Computed[T | Y]
__rtruediv__(other)

Return a reactive value for self divided by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value / other.value.

Example
>>> s = Signal(2)
>>> result = 30 / s
>>> result.value
15.0
>>> s.value = 3
>>> result.value
10.0

__rxor__

__rxor__(other)

Return a reactive value for the bitwise XOR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to XOR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value ^ other.value.

Example
>>> s = Signal(True)
>>> result = False ^ s
>>> result.value
True
>>> s.value = False
>>> result.value
False

__getitem__

__getitem__(key: slice) -> Computed[list[V]]
__getitem__(key: slice) -> Computed[tuple[V, ...]]
__getitem__(key: slice) -> Computed[str]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[V]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[V]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[str]
__getitem__(key: HasValue[K]) -> Computed[V]
__getitem__(key: HasValue[K]) -> Computed[V]
__getitem__(key: Any) -> Computed[Any]
__getitem__(key)

Return a reactive value for the item or slice of self.

Parameters:

Name Type Description Default
key Any

The index or slice to retrieve.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value[key].

Example
>>> s = Signal([1, 2, 3, 4, 5])
>>> result = s[2]
>>> result.value
3
>>> s.value = [10, 20, 30, 40, 50]
>>> result.value
30

__setattr__

__setattr__(name, value)

Set an attribute on the underlying self.value.

Note

It is necessary to set the attribute via the Signal, rather than the underlying signal.value, to properly notify downstream observers of changes. Reason being, mutable objects that, for example, fallback to id comparison for equality checks will appear as if nothing changed even if one of its attributes changed.

Parameters:

Name Type Description Default
name str

The name of the attribute to access.

required
value Any

The value to set it to.

required
Example
    >>> class Person:
    ...    def __init__(self, name: str):
    ...        self.name = name
    ...    def greet(self) -> str:
    ...        return f"Hi, I'm {self.name}!"
    >>> s = Signal(Person("Alice"))
    >>> result = s.greet()
    >>> result.value
    "Hi, I'm Alice!"
    >>> s.name = "Bob"  # Modify attribute on Person instance through the reactive value s
    >>> result.value
    "Hi, I'm Bob!"

__setitem__

__setitem__(key, value)

Set an item on the underlying self.value.

Note

It is necessary to set the item via the Signal, rather than the underlying signal.value, to properly notify downstream observers of changes. Reason being, mutable objects that, for example, fallback to id comparison for equality checks will appear as if nothing changed even an element of the object is changed.

Parameters:

Name Type Description Default
key Any

The key to change.

required
value Any

The value to set it to.

required
Example

```py

s = Signal([1, 2, 3]) result = computed(sum)(s) result.value 6 s[1] = 4 result.value 8

where

where(a, b)

Return a reactive value for a if self is True, else b.

Parameters:

Name Type Description Default
a HasValue[A]

The value to return if self is True.

required
b HasValue[B]

The value to return if self is False.

required

Returns:

Type Description
Computed[A | B]

A reactive value for a if self.value else b.

Example
>>> condition = Signal(True)
>>> result = condition.where("Yes", "No")
>>> result.value
'Yes'
>>> condition.value = False
>>> result.value
'No'

subscribe

subscribe(observer)

Subscribe an observer to this variable.

Parameters:

Name Type Description Default
observer Observer

The observer to subscribe.

required

unsubscribe

unsubscribe(observer)

Unsubscribe an observer from this variable.

Parameters:

Name Type Description Default
observer Observer

The observer to unsubscribe.

required

observe

observe(items)

Subscribe the observer (self) to all items that are Observable.

This method handles arbitrarily nested iterables.

Parameters:

Name Type Description Default
items Any

A single item, an iterable, or a nested structure of items to potentially subscribe to.

required

Returns:

Type Description
Self

self

unobserve

unobserve(items)

Unsubscribe the observer (self) from all items that are Observable.

Parameters:

Name Type Description Default
items Any

A single item or an iterable of items to potentially unsubscribe from.

required

Returns:

Type Description
Self

self

__repr__

__repr__()

Represent the object in a way that shows the inner value.

add_name

add_name(name)

__format__

__format__(format_spec)

Format the variable with custom display options.

Format options: :n - just the name (or type+id if unnamed) :d - full debug info empty - just the value in brackets (default)

Computed

Bases: Variable[T]

Read-only reactive value derived from a computation.

Computed recalculates its value whenever one of its observed dependencies updates. In most usage, instances are created implicitly via :func:computed, operator overloads, or helper APIs such as :func:reactive_method.

Unlike :class:Signal, Computed.value is read-only and is updated by re-running the stored function.

Parameters:

Name Type Description Default
f Callable[[], T]

Zero-argument function used to compute the current value.

required
dependencies Any

Dependencies to observe. May be a single item or nested container structure.

None
Example
>>> count = Signal(2)
>>> squared = Computed(lambda: count.value ** 2, dependencies=count)
>>> squared.value
4
>>> count.value = 5
>>> squared.value
25

__slots__ class-attribute instance-attribute

__slots__ = ['f', '_value']

f instance-attribute

f = f

value property

value

Get the current value.

__name instance-attribute

__name = ''

__init__

__init__(f, dependencies=None)

update

update()

Update the value by re-evaluating the function.

notify

notify()

Notify all observers by calling their update method.

__getattr__

__getattr__(name: Literal['value', '_value']) -> T
__getattr__(name: str) -> Computed[Any]
__getattr__(name)

Create a reactive value for retrieving an attribute from self.value.

Parameters:

Name Type Description Default
name str

The name of the attribute to access.

required

Returns:

Type Description
Union[T, Computed[Any]]

A reactive value for the attribute access.

Raises:

Type Description
AttributeError

If the attribute doesn't exist.

Note

Type inference is poor whenever __getattr__ is used.

Example
>>> class Person:
...     def __init__(self, name):
...         self.name = name
>>> s = Signal(Person("Alice"))
>>> result = s.name
>>> result.value
'Alice'
>>> s.value = Person("Bob")
>>> result.value
'Bob'

__call__

__call__(*args, **kwargs)

Create a reactive value for calling self.value(*args, **kwargs).

Parameters:

Name Type Description Default
*args P.args

Positional arguments to pass to the callable value.

()
**kwargs P.kwargs

Keyword arguments to pass to the callable value.

{}

Returns:

Type Description
Computed[R]

A reactive value for the function call.

Raises:

Type Description
ValueError

If the value is not callable.

Example
>>> class Person:
...     def __init__(self, name):
...         self.name = name
...     def greet(self):
...         return f"Hi, I'm {self.name}!"
>>> s = Signal(Person("Alice"))
>>> result = s.greet()
>>> result.value
"Hi, I'm Alice!"
>>> s.name = "Bob"
>>> result.value
"Hi, I'm Bob!"

__abs__

__abs__() -> Computed[float]
__abs__() -> Computed[int]
__abs__() -> Computed[T]
__abs__()

Return a reactive value for the absolute value of self.

Returns:

Type Description
Computed[T] | Computed[float] | Computed[int]

A reactive value for abs(self.value).

Example
>>> s = Signal(-5)
>>> result = abs(s)
>>> result.value
5
>>> s.value = -10
>>> result.value
10

as_bool

as_bool()

Return a reactive value for the boolean value of self.

Note

__bool__ cannot be implemented to return a non-bool, so it is provided as a method.

Returns:

Type Description
Computed[bool]

A reactive value for bool(self.value).

Example
>>> s = Signal(1)
>>> result = s.as_bool()
>>> result.value
True
>>> s.value = 0
>>> result.value
False

__str__

__str__()

Return a string of the current value.

Note

This is not reactive.

Returns:

Type Description
str

A string representation of self.value.

__round__

__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[int]
__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[int]
__round__() -> Computed[int]
__round__(ndigits: None) -> Computed[int]
__round__(ndigits: int) -> Computed[float]
__round__(ndigits: int | None = None) -> Computed[int] | Computed[float]
__round__(ndigits=None)

Return a reactive value for the rounded value of self.

Parameters:

Name Type Description Default
ndigits int | None

Number of decimal places to round to.

None

Returns:

Type Description
Computed[int] | Computed[float]

A reactive value for round(self.value, ndigits).

Example
>>> s = Signal(3.14159)
>>> result = round(s, 2)
>>> result.value
3.14
>>> s.value = 2.71828
>>> result.value
2.72

__ceil__

__ceil__()

Return a reactive value for the ceiling of self.

Returns:

Type Description
Computed[int]

A reactive value for math.ceil(self.value).

Example
>>> from math import ceil
>>> s = Signal(3.14)
>>> result = ceil(s)
>>> result.value
4
>>> s.value = 2.01
>>> result.value
3

__floor__

__floor__()

Return a reactive value for the floor of self.

Returns:

Type Description
Computed[int]

A reactive value for math.floor(self.value).

Example
>>> from math import floor
>>> s = Signal(3.99)
>>> result = floor(s)
>>> result.value
3
>>> s.value = 4.01
>>> result.value
4

__invert__

__invert__() -> Computed[int]
__invert__() -> Computed[T]
__invert__()

Return a reactive value for the bitwise inversion of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for ~self.value.

Example
>>> s = Signal(5)
>>> result = ~s
>>> result.value
-6
>>> s.value = -3
>>> result.value
2

__neg__

__neg__() -> Computed[int]
__neg__() -> Computed[T]
__neg__()

Return a reactive value for the negation of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for -self.value.

Example
>>> s = Signal(5)
>>> result = -s
>>> result.value
-5
>>> s.value = -3
>>> result.value
3

__pos__

__pos__() -> Computed[int]
__pos__() -> Computed[T]
__pos__()

Return a reactive value for the positive of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for +self.value.

Example
>>> s = Signal(-5)
>>> result = +s
>>> result.value
-5
>>> s.value = 3
>>> result.value
3

__trunc__

__trunc__() -> Computed[int]
__trunc__() -> Computed[int]
__trunc__() -> Computed[int]
__trunc__() -> Computed[T]
__trunc__()

Return a reactive value for the truncated value of self.

Returns:

Type Description
Computed[T] | Computed[int]

A reactive value for math.trunc(self.value).

Example
>>> from math import trunc
>>> s = Signal(3.99)
>>> result = trunc(s)
>>> result.value
3
>>> s.value = -4.01
>>> result.value
-4

__add__

__add__(other: HasValue[int] | HasValue[float]) -> Computed[float]
__add__(other: HasValue[float]) -> Computed[float]
__add__(other: HasValue[Y]) -> Computed[R]
__add__(other: Any) -> Computed[Any]
__add__(other)

Return a reactive value for the sum of self and other.

Parameters:

Name Type Description Default
other Any

The value to add.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value + other.value.

Example
>>> s = Signal(5)
>>> result = s + 3
>>> result.value
8
>>> s.value = 10
>>> result.value
13

__and__

__and__(other)

Return a reactive value for the bitwise AND of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to AND with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value & other.value.

Example
>>> s = Signal(True)
>>> result = s & False
>>> result.value
False
>>> s.value = True
>>> result.value
False

contains

contains(other)

Return a reactive value for whether other is in self.

Parameters:

Name Type Description Default
other Any

The value to check for containment.

required

Returns:

Type Description
Computed[bool]

A reactive value for other in self.value.

Example
>>> s = Signal([1, 2, 3, 4])
>>> result = s.contains(3)
>>> result.value
True
>>> s.value = [5, 6, 7, 8]
>>> result.value
False

__divmod__

__divmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__divmod__(other: HasValue[bool] | HasValue[int]) -> Computed[tuple[int, int]]
__divmod__(other: Any) -> Computed[tuple[float, float]]
__divmod__(other)

Return a reactive value for the divmod of self and other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[tuple[int, int]] | Computed[tuple[float, float]]

A reactive value for divmod(self.value, other).

Example
>>> s = Signal(10)
>>> result = divmod(s, 3)
>>> result.value
(3, 1)
>>> s.value = 20
>>> result.value
(6, 2)

is_not

is_not(other)

Return a reactive value for whether self is not other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value is not other.

Example
>>> s = Signal(10)
>>> other = None
>>> result = s.is_not(other)
>>> result.value
True
>>> s.value = None
>>> result.value
False

eq

eq(other)

Return a reactive value for whether self equals other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value == other.

Note

We can't overload __eq__ because it interferes with basic Python operations.

Example
>>> s = Signal(10)
>>> result = s.eq(10)
>>> result.value
True
>>> s.value = 25
>>> result.value
False

__floordiv__

__floordiv__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__floordiv__(other: HasValue[Y]) -> Computed[T | Y]
__floordiv__(other)

Return a reactive value for the floor division of self by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value // other.value.

Example
>>> s = Signal(20)
>>> result = s // 3
>>> result.value
6
>>> s.value = 25
>>> result.value
8

__ge__

__ge__(other)

Return a reactive value for whether self is greater than or equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value >= other.

Example
>>> s = Signal(10)
>>> result = s >= 5
>>> result.value
True
>>> s.value = 3
>>> result.value
False

__gt__

__gt__(other)

Return a reactive value for whether self is greater than other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value > other.

Example
>>> s = Signal(10)
>>> result = s > 5
>>> result.value
True
>>> s.value = 3
>>> result.value
False

__le__

__le__(other)

Return a reactive value for whether self is less than or equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value <= other.

Example
>>> s = Signal(5)
>>> result = s <= 5
>>> result.value
True
>>> s.value = 6
>>> result.value
False

__lt__

__lt__(other)

Return a reactive value for whether self is less than other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value < other.

Example
>>> s = Signal(5)
>>> result = s < 10
>>> result.value
True
>>> s.value = 15
>>> result.value
False

__lshift__

__lshift__(other)

Return a reactive value for self left-shifted by other.

Parameters:

Name Type Description Default
other HasValue[Y]

The number of positions to shift.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value << other.value.

Example
>>> s = Signal(8)
>>> result = s << 2
>>> result.value
32
>>> s.value = 3
>>> result.value
12

__matmul__

__matmul__(other)

Return a reactive value for the matrix multiplication of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to multiply with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value @ other.value.

Example
>>> import numpy as np
>>> s = Signal(np.array([1, 2]))
>>> result = s @ np.array([[1, 2], [3, 4]])
>>> result.value
array([ 7, 10])
>>> s.value = np.array([2, 3])
>>> result.value
array([11, 16])

__mod__

__mod__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__mod__(other: HasValue[Y]) -> Computed[T | Y]
__mod__(other)

Return a reactive value for self modulo other.

Parameters:

Name Type Description Default
other Any

The divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value % other.value.

Example
>>> s = Signal(17)
>>> result = s % 5
>>> result.value
2
>>> s.value = 23
>>> result.value
3

__mul__

__mul__(other: HasValue[int]) -> Computed[str]
__mul__(other: HasValue[int]) -> Computed[list[V]]
__mul__(other: HasValue[Y]) -> Computed[T | Y]
__mul__(other)

Return a reactive value for the product of self and other.

Parameters:

Name Type Description Default
other Any

The value to multiply with.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value * other.value.

Example
>>> s = Signal(4)
>>> result = s * 3
>>> result.value
12
>>> s.value = 5
>>> result.value
15

__ne__

__ne__(other)

Return a reactive value for whether self is not equal to other.

Parameters:

Name Type Description Default
other Any

The value to compare against.

required

Returns:

Type Description
Computed[bool]

A reactive value for self.value != other.

Example
>>> s = Signal(5)
>>> result = s != 5
>>> result.value
False
>>> s.value = 6
>>> result.value
True

__or__

__or__(other)

Return a reactive value for the bitwise OR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to OR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value or other.value.

Example
>>> s = Signal(False)
>>> result = s | True
>>> result.value
True
>>> s.value = True
>>> result.value
True

__rshift__

__rshift__(other)

Return a reactive value for self right-shifted by other.

Parameters:

Name Type Description Default
other HasValue[Y]

The number of positions to shift.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value >> other.value.

Example
>>> s = Signal(32)
>>> result = s >> 2
>>> result.value
8
>>> s.value = 24
>>> result.value
6

__pow__

__pow__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__pow__(other: HasValue[Y]) -> Computed[T | Y]
__pow__(other)

Return a reactive value for self raised to the power of other.

Parameters:

Name Type Description Default
other Any

The exponent.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value ** other.value.

Example
>>> s = Signal(2)
>>> result = s ** 3
>>> result.value
8
>>> s.value = 3
>>> result.value
27

__sub__

__sub__(other)

Return a reactive value for the difference of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to subtract.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value - other.value.

Example
>>> s = Signal(10)
>>> result = s - 3
>>> result.value
7
>>> s.value = 15
>>> result.value
12

__truediv__

__truediv__(other: HasValue[int]) -> Computed[float]
__truediv__(other: HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[int]) -> Computed[float]
__truediv__(other: HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[bool] | HasValue[int] | HasValue[float]) -> Computed[float]
__truediv__(other: HasValue[Y]) -> Computed[T | Y]
__truediv__(other)

Return a reactive value for self divided by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value / other.value.

Example
>>> s = Signal(20)
>>> result = s / 4
>>> result.value
5.0
>>> s.value = 30
>>> result.value
7.5

__xor__

__xor__(other)

Return a reactive value for the bitwise XOR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to XOR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value ^ other.value.

Example
>>> s = Signal(True)
>>> result = s ^ False
>>> result.value
True
>>> s.value = False
>>> result.value
False

__radd__

__radd__(other: HasValue[int] | HasValue[float]) -> Computed[float]
__radd__(other: HasValue[_SupportsAdd[T, R]]) -> Computed[R]
__radd__(other: Any) -> Computed[Any]
__radd__(other)

Return a reactive value for the sum of self and other.

Parameters:

Name Type Description Default
other Any

The value to add.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value + other.value.

Example
>>> s = Signal(5)
>>> result = 3 + s
>>> result.value
8
>>> s.value = 10
>>> result.value
13

__rand__

__rand__(other)

Return a reactive value for the bitwise AND of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to AND with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value and other.value.

Example
>>> s = Signal(True)
>>> result = False & s
>>> result.value
False
>>> s.value = True
>>> result.value
False

__rdivmod__

__rdivmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__rdivmod__(other: HasValue[int]) -> Computed[tuple[int, int]]
__rdivmod__(other: HasValue[bool]) -> Computed[tuple[int, int]]
__rdivmod__(other: Any) -> Computed[tuple[float, float]]
__rdivmod__(other)

Return a reactive value for the divmod of self and other.

Parameters:

Name Type Description Default
other Any

The value to use as the numerator.

required

Returns:

Type Description
Computed[tuple[int, int]] | Computed[tuple[float, float]]

A reactive value for divmod(other, self.value).

Example
>>> s = Signal(3)
>>> result = divmod(10, s)
>>> result.value
(3, 1)
>>> s.value = 4
>>> result.value
(2, 2)

__rfloordiv__

__rfloordiv__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rfloordiv__(other: HasValue[Y]) -> Computed[T | Y]
__rfloordiv__(other)

Return a reactive value for the floor division of other by self.

Parameters:

Name Type Description Default
other Any

The value to use as the numerator.

required

Returns:

Type Description
Computed[Any]

A reactive value for other.value // self.value.

Example
>>> s = Signal(3)
>>> result = 10 // s
>>> result.value
3
>>> s.value = 4
>>> result.value
2

__rmod__

__rmod__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rmod__(other: HasValue[Y]) -> Computed[T | Y]
__rmod__(other)

Return a reactive value for other modulo self.

Parameters:

Name Type Description Default
other Any

The dividend.

required

Returns:

Type Description
Computed[Any]

A reactive value for other.value % self.value.

Example
>>> s = Signal(3)
>>> result = 10 % s
>>> result.value
1
>>> s.value = 4
>>> result.value
2

__rmul__

__rmul__(other: HasValue[int]) -> Computed[str]
__rmul__(other: HasValue[int]) -> Computed[list[V]]
__rmul__(other: HasValue[Y]) -> Computed[T | Y]
__rmul__(other)

Return a reactive value for the product of self and other.

Parameters:

Name Type Description Default
other Any

The value to multiply with.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value * other.value.

Example
>>> s = Signal(4)
>>> result = 3 * s
>>> result.value
12
>>> s.value = 5
>>> result.value
15

__ror__

__ror__(other)

Return a reactive value for the bitwise OR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to OR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value or other.value.

Example
>>> s = Signal(False)
>>> result = True | s
>>> result.value
True
>>> s.value = True
>>> result.value
True

__rpow__

__rpow__(other: HasValue[bool] | HasValue[int]) -> Computed[int]
__rpow__(other: HasValue[Y]) -> Computed[T | Y]
__rpow__(other)

Return a reactive value for self raised to the power of other.

Parameters:

Name Type Description Default
other Any

The base.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value ** other.value.

Example
>>> s = Signal(2)
>>> result = 3 ** s
>>> result.value
9
>>> s.value = 3
>>> result.value
27

__rsub__

__rsub__(other)

Return a reactive value for the difference of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to subtract from.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for other.value - self.value.

Example
>>> s = Signal(10)
>>> result = 15 - s
>>> result.value
5
>>> s.value = 15
>>> result.value
0

__rtruediv__

__rtruediv__(other: HasValue[int]) -> Computed[float]
__rtruediv__(other: HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[int]) -> Computed[float]
__rtruediv__(other: HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[bool] | HasValue[int] | HasValue[float]) -> Computed[float]
__rtruediv__(other: HasValue[Y]) -> Computed[T | Y]
__rtruediv__(other)

Return a reactive value for self divided by other.

Parameters:

Name Type Description Default
other Any

The value to use as the divisor.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value / other.value.

Example
>>> s = Signal(2)
>>> result = 30 / s
>>> result.value
15.0
>>> s.value = 3
>>> result.value
10.0

__rxor__

__rxor__(other)

Return a reactive value for the bitwise XOR of self and other.

Parameters:

Name Type Description Default
other HasValue[Y]

The value to XOR with.

required

Returns:

Type Description
Computed[T | Y]

A reactive value for self.value ^ other.value.

Example
>>> s = Signal(True)
>>> result = False ^ s
>>> result.value
True
>>> s.value = False
>>> result.value
False

__getitem__

__getitem__(key: slice) -> Computed[list[V]]
__getitem__(key: slice) -> Computed[tuple[V, ...]]
__getitem__(key: slice) -> Computed[str]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[V]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[V]
__getitem__(key: HasValue[SupportsIndex] | HasValue[int]) -> Computed[str]
__getitem__(key: HasValue[K]) -> Computed[V]
__getitem__(key: HasValue[K]) -> Computed[V]
__getitem__(key: Any) -> Computed[Any]
__getitem__(key)

Return a reactive value for the item or slice of self.

Parameters:

Name Type Description Default
key Any

The index or slice to retrieve.

required

Returns:

Type Description
Computed[Any]

A reactive value for self.value[key].

Example
>>> s = Signal([1, 2, 3, 4, 5])
>>> result = s[2]
>>> result.value
3
>>> s.value = [10, 20, 30, 40, 50]
>>> result.value
30

__setattr__

__setattr__(name, value)

Set an attribute on the underlying self.value.

Note

It is necessary to set the attribute via the Signal, rather than the underlying signal.value, to properly notify downstream observers of changes. Reason being, mutable objects that, for example, fallback to id comparison for equality checks will appear as if nothing changed even if one of its attributes changed.

Parameters:

Name Type Description Default
name str

The name of the attribute to access.

required
value Any

The value to set it to.

required
Example
    >>> class Person:
    ...    def __init__(self, name: str):
    ...        self.name = name
    ...    def greet(self) -> str:
    ...        return f"Hi, I'm {self.name}!"
    >>> s = Signal(Person("Alice"))
    >>> result = s.greet()
    >>> result.value
    "Hi, I'm Alice!"
    >>> s.name = "Bob"  # Modify attribute on Person instance through the reactive value s
    >>> result.value
    "Hi, I'm Bob!"

__setitem__

__setitem__(key, value)

Set an item on the underlying self.value.

Note

It is necessary to set the item via the Signal, rather than the underlying signal.value, to properly notify downstream observers of changes. Reason being, mutable objects that, for example, fallback to id comparison for equality checks will appear as if nothing changed even an element of the object is changed.

Parameters:

Name Type Description Default
key Any

The key to change.

required
value Any

The value to set it to.

required
Example

```py

s = Signal([1, 2, 3]) result = computed(sum)(s) result.value 6 s[1] = 4 result.value 8

where

where(a, b)

Return a reactive value for a if self is True, else b.

Parameters:

Name Type Description Default
a HasValue[A]

The value to return if self is True.

required
b HasValue[B]

The value to return if self is False.

required

Returns:

Type Description
Computed[A | B]

A reactive value for a if self.value else b.

Example
>>> condition = Signal(True)
>>> result = condition.where("Yes", "No")
>>> result.value
'Yes'
>>> condition.value = False
>>> result.value
'No'

subscribe

subscribe(observer)

Subscribe an observer to this variable.

Parameters:

Name Type Description Default
observer Observer

The observer to subscribe.

required

unsubscribe

unsubscribe(observer)

Unsubscribe an observer from this variable.

Parameters:

Name Type Description Default
observer Observer

The observer to unsubscribe.

required

observe

observe(items)

Subscribe the observer (self) to all items that are Observable.

This method handles arbitrarily nested iterables.

Parameters:

Name Type Description Default
items Any

A single item, an iterable, or a nested structure of items to potentially subscribe to.

required

Returns:

Type Description
Self

self

unobserve

unobserve(items)

Unsubscribe the observer (self) from all items that are Observable.

Parameters:

Name Type Description Default
items Any

A single item or an iterable of items to potentially unsubscribe from.

required

Returns:

Type Description
Self

self

__repr__

__repr__()

Represent the object in a way that shows the inner value.

add_name

add_name(name)

__format__

__format__(format_spec)

Format the variable with custom display options.

Format options: :n - just the name (or type+id if unnamed) :d - full debug info empty - just the value in brackets (default)

computed

computed(func)

Wrap a function so calls produce a reactive Computed result.

The returned wrapper accepts plain values, reactive values, or nested containers that include reactive values. On each recomputation, arguments are normalized with :func:deep_unref, so func receives plain Python values.

The created :class:Computed subscribes to reactive dependencies found in args and kwargs at call time. When any dependency updates, the function is re-evaluated and subscribers are notified.

Parameters:

Name Type Description Default
func Callable[..., R]

Function that computes a derived value from its inputs.

required

Returns:

Type Description
Callable[..., Computed[R]]

A wrapper that returns a :class:Computed when called.

Example
>>> @computed
... def total(price, quantity):
...     return price * quantity
>>> price = Signal(10)
>>> quantity = Signal(2)
>>> subtotal = total(price, quantity)
>>> subtotal.value
20
>>> quantity.value = 3
>>> subtotal.value
30

unref

unref(value)

Resolve a value by unwrapping reactive containers until plain data remains.

This utility repeatedly unwraps :class:Variable objects by following their internal _value references, allowing callers to operate on the underlying Python value regardless of nesting depth.

Parameters:

Name Type Description Default
value HasValue[T]

Plain value, reactive value, or nested reactive value.

required

Returns:

Type Description
T

The fully unwrapped value.

Example
>>> nested = Signal(Signal(5))
>>> unref(nested)
5

has_value

has_value(obj, type_)

Check whether an object's resolved value is an instance of type_.

This helper is a typed guard around :func:unref. It is useful when code accepts either plain values or reactive values and needs a narrowed type before continuing.

Parameters:

Name Type Description Default
obj Any

Value to inspect. May be plain or reactive.

required
type_ type[T]

Expected resolved value type.

required

Returns:

Type Description
TypeGuard[HasValue[T]]

True if unref(obj) is an instance of type_; otherwise

TypeGuard[HasValue[T]]

False.

Example
>>> candidate = Signal(42)
>>> has_value(candidate, int)
True
>>> has_value(candidate, str)
False

deep_unref

deep_unref(value)

Recursively resolve reactive values within nested containers.

deep_unref is the structural counterpart to :func:unref. It unwraps reactive values that appear inside supported containers while preserving the container type where practical.

Supported behavior: - scalar primitives are returned unchanged - reactive values are unwrapped recursively - dict, list, and tuple contents are recursively unwrapped - generic iterables are reconstructed when possible; otherwise returned as-is - numpy.ndarray values with dtype=object are recursively unwrapped element-wise

Parameters:

Name Type Description Default
value Any

Any value, possibly containing reactive values.

required

Returns:

Type Description
Any

Value with reactive nodes recursively replaced by plain values.

Example
>>> payload = {"a": Signal(1), "b": [Signal(2), 3]}
>>> deep_unref(payload)
{'a': 1, 'b': [2, 3]}

reactive_method

reactive_method(*dep_names)

Decorate an instance method so calls return a Computed value.

The decorated method keeps its original call signature but now returns a reactive value. Dependencies include: - instance attributes named in dep_names (when present), and - call-time args and kwargs.

This is useful for class APIs where a derived value depends on reactive fields owned by self.

Parameters:

Name Type Description Default
*dep_names str

Attribute names on self to observe as dependencies.

()

Returns:

Type Description
Callable[[InstanceMethod[P, T]], ReactiveMethod[P, T]]

A decorator that transforms an instance method into one that returns

Callable[[InstanceMethod[P, T]], ReactiveMethod[P, T]]

class:Computed.

Example
>>> from signified import Signal, reactive_method
>>> class Counter:
...     def __init__(self):
...         self.count = Signal(1)
...     @reactive_method("count")
...     def doubled(self):
...         return self.count.value * 2
>>> c = Counter()
>>> result = c.doubled()
>>> result.value
2
>>> c.count.value = 4
>>> result.value
8

as_signal

as_signal(val)

Normalize a value to a signal-compatible reactive object.

If val is already reactive, it is returned unchanged to avoid wrapping an existing reactive node. Otherwise a new :class:Signal is created.

Parameters:

Name Type Description Default
val HasValue[T]

Plain value or reactive value.

required

Returns:

Type Description
Signal[T]

A reactive value suitable for APIs expecting Signal-like behavior.

Note

Existing reactive values are returned as-is at runtime, including Computed instances.

Example
>>> from signified import Signal, as_signal
>>> as_signal(3).value
3
>>> s = Signal(4)
>>> as_signal(s) is s
True