diff --git a/doc/user_guide/Reactive_Expressions.ipynb b/doc/user_guide/Reactive_Expressions.ipynb index a5e720ee..a0294145 100644 --- a/doc/user_guide/Reactive_Expressions.ipynb +++ b/doc/user_guide/Reactive_Expressions.ipynb @@ -40,7 +40,7 @@ "import param\n", "import param.ipython\n", "\n", - "from param import reactive as rx" + "from param import rx" ] }, { @@ -515,7 +515,7 @@ "metadata": {}, "outputs": [], "source": [ - "string_template = param.reactive('Hello {name}!')\n", + "string_template = rx('Hello {name}!')\n", "\n", "string_template" ] @@ -535,7 +535,7 @@ "metadata": {}, "outputs": [], "source": [ - "name = param.reactive('world')\n", + "name = rx('world')\n", "\n", "str_expr = string_template.format(name=name)\n", "\n", @@ -625,7 +625,7 @@ "metadata": {}, "outputs": [], "source": [ - "param.reactive(1).rx.bool()" + "rx(1).rx.bool()" ] }, { @@ -645,7 +645,7 @@ "metadata": {}, "outputs": [], "source": [ - "param.reactive(2).rx.in_([1, 2, 3])" + "rx(2).rx.in_([1, 2, 3])" ] }, { @@ -665,7 +665,7 @@ "metadata": {}, "outputs": [], "source": [ - "param.reactive(None).rx.is_(None)" + "rx(None).rx.is_(None)" ] }, { @@ -685,7 +685,7 @@ "metadata": {}, "outputs": [], "source": [ - "param.reactive(None).rx.is_not(None)" + "rx(None).rx.is_not(None)" ] }, { @@ -705,7 +705,7 @@ "metadata": {}, "outputs": [], "source": [ - "param.reactive([1, 2, 3]).rx.len()" + "rx([1, 2, 3]).rx.len()" ] }, { @@ -725,7 +725,7 @@ "metadata": {}, "outputs": [], "source": [ - "param.reactive(1).rx.pipe(add, 2)" + "rx(1).rx.pipe(add, 2)" ] }, { @@ -735,7 +735,7 @@ "metadata": {}, "outputs": [], "source": [ - "param.reactive(8).rx.pipe(str)" + "rx(8).rx.pipe(str)" ] }, { @@ -855,7 +855,7 @@ "metadata": {}, "outputs": [], "source": [ - "condition = param.reactive(True)" + "condition = rx(True)" ] }, { diff --git a/param/__init__.py b/param/__init__.py index 5c0e5337..29ba64a2 100644 --- a/param/__init__.py +++ b/param/__init__.py @@ -3246,4 +3246,4 @@ def exceptions_summarized(): etype, value, tb = sys.exc_info() print(f"{etype.__name__}: {value}", file=sys.stderr) -from .reactive import bind, reactive # noqa: api import +from .reactive import bind, rx # noqa: api import diff --git a/param/ipython.py b/param/ipython.py index a75d21c4..32baf904 100644 --- a/param/ipython.py +++ b/param/ipython.py @@ -26,7 +26,7 @@ from param.depends import depends, register_display_accessor from param.parameterized import resolve_ref -from param.reactive import reactive +from param.reactive import rx # Whether to generate warnings when misformatted docstrings are found @@ -365,7 +365,7 @@ def __init__(self, reactive): self._reactive = reactive def __call__(self): - if isinstance(self._reactive, reactive): + if isinstance(self._reactive, rx): cb = self._reactive._callback @depends(*self._reactive._params, watch=True) def update_handle(*args, **kwargs): diff --git a/param/reactive.py b/param/reactive.py index 429c679e..641302dd 100644 --- a/param/reactive.py +++ b/param/reactive.py @@ -1,30 +1,30 @@ """ reactive API -`reactive` is a wrapper around a Python object that lets users create -reactive pipelines by calling existing APIs on an object with dynamic +`rx` is a wrapper around a Python object that lets users create +reactive expression pipelines by calling existing APIs on an object with dynamic parameters or widgets. -A `reactive` instance watches what operations are applied to the object +An `rx` instance watches what operations are applied to the object and records these on each instance, which are then strung together into a chain. -The original input to a `reactive` is stored in a mutable list and can be +The original input to an `rx` object is stored in a mutable list and can be accessed via the `_obj` property. The shared mutable data structure -ensures that all `reactive` instances created from the same object can +ensures that all `rx` instances created from the same object can hold a shared reference that can be updated, e.g. via the `.set` method or because the input was itself a reference to some object that can potentially be updated. -When an operation is applied to a `reactive` instance, it will +When an operation is applied to an `rx` instance, it will record the operation and create a new instance using `_clone` method, e.g. `dfi.head()` first records that the `'head'` attribute is accessed, which is achieved by overriding `__getattribute__`. A new reactive object is returned, which will then record that it is -being called, and that new object will be itself called as -`reactive` implements `__call__`. `__call__` returns another -`reactive` instance. To be able to watch all the potential -operations that may be applied to an object, `reactive` implements: +being called, and that new object will be itself called, as +`rx` implements `__call__`. `__call__` returns another +`rx` instance. To be able to watch all the potential +operations that may be applied to an object, `rx` implements: - `__getattribute__`: Watching for attribute accesses - `__call__`: Intercepting both actual calls or method calls if an @@ -33,7 +33,7 @@ - Operators: Implementing all valid operators `__gt__`, `__add__`, etc. - `__array_ufunc__`: Intercepting numpy universal function calls -The `reactive` object evaluates operations lazily but whenever the +The `rx` object evaluates operations lazily but whenever the current value is needed the operations are automatically evaluated. Note that even attribute access or tab-completion operations can result in evaluation of the pipeline. This is very @@ -55,23 +55,23 @@ reverse order. The `_depth` attribute starts at 0 and is incremented by 1 every time -a new `reactive` instance is created part of a chain. The root -instance in a reactive reactive has a `_depth` of 0. A reactive +a new `rx` instance is created part of a chain. The root +instance in a reactive expression has a `_depth` of 0. A reactive expression can consist of multiple chains, such as `dfi[dfi.A > 1]`, -as the `reactive` instance is referenced twice in the reactive. As a -consequence `_depth` is not the total count of `reactive` instance +as the `rx` instance is referenced twice in the expression. As a +consequence `_depth` is not the total count of `rx` instance creations of a pipeline, it is the count of instances created in the -outer chain. In the example, that would be `dfi[]`. Each `reactive` +outer chain. In the example, that would be `dfi[]`. Each `rx` instance keeps a reference to the previous instance in the chain and each instance tracks whether its current value is up-to-date via the `_dirty` attribute, which is set to False if any dependency changes. The `_method` attribute is a string that temporarily stores the method/attr accessed on the object, e.g. `_method` is 'head' in -`dfi.head()`, until the `reactive` instance created in the pipeline +`dfi.head()`, until the `rx` instance created in the pipeline is called at which point `_method` is reset to None. In cases such as `dfi.head` or `dfi.A`, `_method` is not (yet) reset to None. At this -stage the reactive instance returned has its `_current` attribute +stage the `rx` instance returned has its `_current` attribute not updated, e.g. `dfi.A._current` is still the original dataframe, not the 'A' series. Keeping `_method` is thus useful for instance to display `dfi.A`, as the evaluation of the object will check whether @@ -125,43 +125,43 @@ def __init__(self, reactive): self._reactive = reactive def __call__(self): - rx = self._reactive - return rx if isinstance(rx, reactive) else reactive(rx) + rxi = self._reactive + return rxi if isinstance(rx, rx) else rx(rxi) def bool(self): """ __bool__ cannot be implemented so it is provided as a method. """ - rx = self._reactive if isinstance(self._reactive, reactive) else self() - return rx._apply_operator(bool) + rxi = self._reactive if isinstance(self._reactive, rx) else self() + return rxi._apply_operator(bool) def in_(self, other): """ Replacement for the ``in`` statement. """ - rx = self._reactive if isinstance(self._reactive, reactive) else self() - return rx._apply_operator(operator.contains, other, reverse=True) + rxi = self._reactive if isinstance(self._reactive, rx) else self() + return rxi._apply_operator(operator.contains, other, reverse=True) def is_(self, other): """ Replacement for the ``is`` statement. """ - rx = self._reactive if isinstance(self._reactive, reactive) else self() - return rx._apply_operator(operator.is_, other) + rxi = self._reactive if isinstance(self._reactive, rx) else self() + return rxi._apply_operator(operator.is_, other) def is_not(self, other): """ Replacement for the ``is not`` statement. """ - rx = self._reactive if isinstance(self._reactive, reactive) else self() - return rx._apply_operator(operator.is_not, other) + rxi = self._reactive if isinstance(self._reactive, rx) else self() + return rxi._apply_operator(operator.is_not, other) def len(self): """ __len__ cannot be implemented so it is provided as a method. """ - rx = self._reactive if isinstance(self._reactive, reactive) else self() - return rx._apply_operator(len) + rxi = self._reactive if isinstance(self._reactive, rx) else self() + return rxi._apply_operator(len) def pipe(self, func, *args, **kwargs): """ @@ -176,17 +176,17 @@ def pipe(self, func, *args, **kwargs): kwargs: mapping, optional A dictionary of keywords to pass to `func`. """ - rx = self._reactive if isinstance(self._reactive, reactive) else self() - return rx._apply_operator(func, *args, **kwargs) + rxi = self._reactive if isinstance(self._reactive, rx) else self() + return rxi._apply_operator(func, *args, **kwargs) def when(self, *dependencies): """ - Returns a reactive object that emits the contents of this + Returns a reactive expression that emits the contents of this expression only when the condition changes. Arguments --------- - dependencies: param.Parameter | reactive + dependencies: param.Parameter | rx A dependency that will trigger an update in the output. """ return bind(lambda *_: self.resolve(), *dependencies).rx() @@ -225,10 +225,10 @@ def ternary(condition, event): def resolve(self): """ - Returns the current state of the reactive by evaluating the - pipeline. + Returns the current state of the reactive expression by + evaluating the pipeline. """ - if isinstance(self._reactive, reactive): + if isinstance(self._reactive, rx): return self._reactive._resolve() elif isinstance(self._reactive, Parameter): return getattr(self._reactive.owner, self._reactive.name) @@ -244,12 +244,12 @@ def set_input(self, new): "Parameter.rx.set_input() is not supported. Cannot override " "parameter value." ) - elif not isinstance(self._reactive, reactive): + elif not isinstance(self._reactive, rx): raise ValueError( "bind(...).rx.set_input() is not supported. Cannot override " "the output of a function." ) - if isinstance(new, reactive): + if isinstance(new, rx): new = new.resolve() prev = self._reactive while prev is not None: @@ -260,7 +260,7 @@ def set_input(self, new): if prev._wrapper is None: raise ValueError( - 'reactive.rx.set_input() is only supported if the ' + 'rx.rx.set_input() is only supported if the ' 'root object is a constant value. If the root is a ' 'Parameter or another dynamic value it must reflect ' 'the source and cannot be set.' @@ -276,7 +276,7 @@ def watch(self, fn): def cb(*args): fn(self.resolve()) - if isinstance(self._reactive, reactive): + if isinstance(self._reactive, rx): params = self._reactive._params else: params = resolve_ref(self._reactive) @@ -413,9 +413,9 @@ def wrapped(*wargs, **wkwargs): return wrapped -class reactive: +class rx: """ - `reactive` allows wrapping objects and then operating on them + `rx` allows wrapping objects and then operating on them interactively while recording any operations applied to them. By recording all arguments or operands in the operations the recorded pipeline can be replayed if an operand represents a dynamic value. @@ -429,7 +429,7 @@ class reactive: -------- Instantiate it from an object: - >>> ifloat = reactive(3.14) + >>> ifloat = rx(3.14) >>> ifloat * 2 6.28 @@ -438,7 +438,7 @@ class reactive: 2 """ - _accessors: dict[str, Callable[[reactive], Any]] = {} + _accessors: dict[str, Callable[[rx], Any]] = {} _display_options: tuple[str] = () @@ -448,19 +448,19 @@ class reactive: @classmethod def register_accessor( - cls, name: str, accessor: Callable[[reactive], Any], + cls, name: str, accessor: Callable[[rx], Any], predicate: Optional[Callable[[Any], bool]] = None ): """ - Registers an accessor that extends reactive with custom behavior. + Registers an accessor that extends rx with custom behavior. Arguments --------- name: str The name of the accessor will be attribute-accessible under. - accessor: Callable[[reactive], any] + accessor: Callable[[rx], any] A callable that will return the accessor namespace object - given the reactive object it is registered on. + given the rx object it is registered on. predicate: Callable[[Any], bool] | None """ cls._accessors[name] = (accessor, predicate) @@ -507,7 +507,7 @@ def __new__(cls, obj, **kwargs): else: wrapper = Wrapper(object=obj) fn = bind(lambda obj: obj, wrapper.param.object) - inst = super(reactive, cls).__new__(cls) + inst = super(rx, cls).__new__(cls) inst._fn = fn inst._shared_obj = kwargs.get('_shared_obj', None if obj is None else [obj]) inst._wrapper = wrapper @@ -536,7 +536,7 @@ def __init__( self._dirty_obj = False self._error_state = None self._current_ = None - if isinstance(obj, reactive) and not prev: + if isinstance(obj, rx) and not prev: self._prev = obj else: self._prev = prev @@ -546,7 +546,7 @@ def __init__( self._init = True for name, accessor in _display_accessors.items(): setattr(self, name, accessor(self)) - for name, (accessor, predicate) in reactive._accessors.items(): + for name, (accessor, predicate) in rx._accessors.items(): if predicate is None or predicate(self._current): setattr(self, name, accessor(self)) @@ -790,8 +790,8 @@ def __call__(self, *args, **kwargs): if method == '__call__' and self._depth == 0 and not hasattr(self._current, '__call__'): return self.set_display(*args, **kwargs) - if method in reactive._method_handlers: - handler = reactive._method_handlers[method] + if method in rx._method_handlers: + handler = rx._method_handlers[method] method = handler(self) new._method = None kwargs = dict(kwargs) @@ -804,7 +804,7 @@ def __call__(self, *args, **kwargs): return new._clone(operation) #---------------------------------------------------------------- - # reactive pipeline APIs + # rx pipeline APIs #---------------------------------------------------------------- def __array_ufunc__(self, ufunc, method, *args, **kwargs): @@ -973,9 +973,9 @@ def _eval_operation(self, obj, operation): return obj -def _reactive_transform(obj): - if not isinstance(obj, reactive): +def _rx_transform(obj): + if not isinstance(obj, rx): return obj return bind(lambda *_: obj.rx.resolve(), *obj._params) -register_reference_transform(_reactive_transform) +register_reference_transform(_rx_transform) diff --git a/tests/testreactive.py b/tests/testreactive.py index d4a40c4f..914d3171 100644 --- a/tests/testreactive.py +++ b/tests/testreactive.py @@ -22,7 +22,7 @@ import param import pytest -from param.reactive import bind, reactive +from param.reactive import bind, rx NUMERIC_BINARY_OPERATORS = ( operator.add, divmod, operator.floordiv, operator.mod, operator.mul, @@ -72,158 +72,158 @@ def multiply_integer(self): @pytest.mark.parametrize('op', NUMERIC_BINARY_OPERATORS) def test_reactive_numeric_binary_ops(op): - assert op(reactive(1), 2).rx.resolve() == op(1, 2) - assert op(reactive(2), 2).rx.resolve() == op(2, 2) + assert op(rx(1), 2).rx.resolve() == op(1, 2) + assert op(rx(2), 2).rx.resolve() == op(2, 2) @pytest.mark.parametrize('op', COMPARISON_OPERATORS) def test_reactive_numeric_comparison_ops(op): - assert op(reactive(1), 2).rx.resolve() == op(1, 2) - assert op(reactive(2), 1).rx.resolve() == op(2, 1) + assert op(rx(1), 2).rx.resolve() == op(1, 2) + assert op(rx(2), 1).rx.resolve() == op(2, 1) @pytest.mark.parametrize('op', NUMERIC_UNARY_OPERATORS) def test_reactive_numeric_unary_ops(op): - assert op(reactive(1)).rx.resolve() == op(1) - assert op(reactive(-1)).rx.resolve() == op(-1) - assert op(reactive(3.142)).rx.resolve() == op(3.142) + assert op(rx(1)).rx.resolve() == op(1) + assert op(rx(-1)).rx.resolve() == op(-1) + assert op(rx(3.142)).rx.resolve() == op(3.142) @pytest.mark.parametrize('op', NUMERIC_BINARY_OPERATORS) def test_reactive_numeric_binary_ops_reverse(op): - assert op(2, reactive(1)).rx.resolve() == op(2, 1) - assert op(2, reactive(2)).rx.resolve() == op(2, 2) + assert op(2, rx(1)).rx.resolve() == op(2, 1) + assert op(2, rx(2)).rx.resolve() == op(2, 2) @pytest.mark.parametrize('op', LOGIC_BINARY_OPERATORS) def test_reactive_logic_binary_ops(op): - assert op(reactive(True), True).rx.resolve() == op(True, True) - assert op(reactive(True), False).rx.resolve() == op(True, False) - assert op(reactive(False), True).rx.resolve() == op(False, True) - assert op(reactive(False), False).rx.resolve() == op(False, False) + assert op(rx(True), True).rx.resolve() == op(True, True) + assert op(rx(True), False).rx.resolve() == op(True, False) + assert op(rx(False), True).rx.resolve() == op(False, True) + assert op(rx(False), False).rx.resolve() == op(False, False) @pytest.mark.parametrize('op', LOGIC_UNARY_OPERATORS) def test_reactive_logic_unary_ops(op): - assert op(reactive(True)).rx.resolve() == op(True) - assert op(reactive(False)).rx.resolve() == op(False) + assert op(rx(True)).rx.resolve() == op(True) + assert op(rx(False)).rx.resolve() == op(False) @pytest.mark.parametrize('op', LOGIC_BINARY_OPERATORS) def test_reactive_logic_binary_ops_reverse(op): - assert op(True, reactive(True)).rx.resolve() == op(True, True) - assert op(True, reactive(False)).rx.resolve() == op(True, False) - assert op(False, reactive(True)).rx.resolve() == op(False, True) - assert op(False, reactive(False)).rx.resolve() == op(False, False) + assert op(True, rx(True)).rx.resolve() == op(True, True) + assert op(True, rx(False)).rx.resolve() == op(True, False) + assert op(False, rx(True)).rx.resolve() == op(False, True) + assert op(False, rx(False)).rx.resolve() == op(False, False) def test_reactive_getitem_dict(): - assert reactive({'A': 1})['A'].rx.resolve() == 1 - assert reactive({'A': 1, 'B': 2})['B'].rx.resolve() == 2 + assert rx({'A': 1})['A'].rx.resolve() == 1 + assert rx({'A': 1, 'B': 2})['B'].rx.resolve() == 2 def test_reactive_getitem_list(): - assert reactive([1, 2, 3])[1].rx.resolve() == 2 - assert reactive([1, 2, 3])[2].rx.resolve() == 3 + assert rx([1, 2, 3])[1].rx.resolve() == 2 + assert rx([1, 2, 3])[2].rx.resolve() == 3 @pytest.mark.parametrize('ufunc', NUMPY_UFUNCS) def test_numpy_ufunc(ufunc): l = [1, 2, 3] - assert ufunc(reactive(l)).rx.resolve() == ufunc(l) + assert ufunc(rx(l)).rx.resolve() == ufunc(l) array = np.ndarray([1, 2, 3]) - assert ufunc(reactive(array)).rx.resolve() == ufunc(array) + assert ufunc(rx(array)).rx.resolve() == ufunc(array) def test_reactive_set_new_value(): - i = reactive(1) + i = rx(1) assert i.rx.resolve() == 1 i.rx.set_input(2) assert i.rx.resolve() == 2 def test_reactive_pipeline_set_new_value(): - i = reactive(1) + 2 + i = rx(1) + 2 assert i.rx.resolve() == 3 i.rx.set_input(2) assert i.rx.resolve() == 4 def test_reactive_reflect_param_value(): P = Parameters(integer=1) - i = reactive(P.param.integer) + i = rx(P.param.integer) assert i.rx.resolve() == 1 P.integer = 2 assert i.rx.resolve() == 2 def test_reactive_pipeline_reflect_param_value(): P = Parameters(integer=1) - i = reactive(P.param.integer) + 2 + i = rx(P.param.integer) + 2 assert i.rx.resolve() == 3 P.integer = 2 assert i.rx.resolve() == 4 -def test_reactive_reactive_reflect_other_reactive(): - i = reactive(1) - j = reactive(i) +def test_reactive_reactive_reflect_other_rx(): + i = rx(1) + j = rx(i) assert j.rx.resolve() == 1 i.rx.set_input(2) assert j.rx.resolve() == 2 def test_reactive_pipeline_reflect_other_reactive_expr(): - i = reactive(1) + 2 - j = reactive(i) + i = rx(1) + 2 + j = rx(i) assert j.rx.resolve() == 3 i.rx.set_input(2) assert i.rx.resolve() == 4 def test_reactive_reflect_bound_method(): P = Parameters(integer=1) - i = reactive(P.multiply_integer) + i = rx(P.multiply_integer) assert i.rx.resolve() == 2 P.integer = 2 assert i.rx.resolve() == 4 def test_reactive_pipeline_reflect_bound_method(): P = Parameters(integer=1) - i = reactive(P.multiply_integer) + 2 + i = rx(P.multiply_integer) + 2 assert i.rx.resolve() == 4 P.integer = 2 assert i.rx.resolve() == 6 def test_reactive_reflect_bound_function(): P = Parameters(integer=1) - i = reactive(bind(lambda v: v * 2, P.param.integer)) + i = rx(bind(lambda v: v * 2, P.param.integer)) assert i.rx.resolve() == 2 P.integer = 2 assert i.rx.resolve() == 4 def test_reactive_pipeline_reflect_bound_function(): P = Parameters(integer=1) - i = reactive(bind(lambda v: v * 2, P.param.integer)) + 2 + i = rx(bind(lambda v: v * 2, P.param.integer)) + 2 assert i.rx.resolve() == 4 P.integer = 2 assert i.rx.resolve() == 6 def test_reactive_dataframe_method_chain(dataframe): - dfi = reactive(dataframe).groupby('str')[['float']].mean().reset_index() + dfi = rx(dataframe).groupby('str')[['float']].mean().reset_index() pd.testing.assert_frame_equal(dfi.rx.resolve(), dataframe.groupby('str')[['float']].mean().reset_index()) def test_reactive_dataframe_attribute_chain(dataframe): - array = reactive(dataframe).str.values.rx.resolve() + array = rx(dataframe).str.values.rx.resolve() np.testing.assert_array_equal(array, dataframe.str.values) def test_reactive_dataframe_param_value_method_chain(dataframe): P = Parameters(string='str') - dfi = reactive(dataframe).groupby(P.param.string)[['float']].mean().reset_index() + dfi = rx(dataframe).groupby(P.param.string)[['float']].mean().reset_index() pd.testing.assert_frame_equal(dfi.rx.resolve(), dataframe.groupby('str')[['float']].mean().reset_index()) P.string = 'int' pd.testing.assert_frame_equal(dfi.rx.resolve(), dataframe.groupby('int')[['float']].mean().reset_index()) def test_reactive_len(): - i = reactive([1, 2, 3]) + i = rx([1, 2, 3]) l = i.rx.len() assert l.rx.resolve() == 3 i.rx.set_input([1, 2]) assert l == 2 def test_reactive_bool(): - i = reactive(1) + i = rx(1) b = i.rx.bool() assert b.rx.resolve() is True i.rx.set_input(0) assert b.rx.resolve() is False def test_reactive_iter(): - i = reactive(('a', 'b')) + i = rx(('a', 'b')) a, b = i assert a.rx.resolve() == 'a' assert b.rx.resolve() == 'b' @@ -232,21 +232,21 @@ def test_reactive_iter(): assert b.rx.resolve() == 'a' def test_reactive_is(): - i = reactive(None) + i = rx(None) is_ = i.rx.is_(None) assert is_.rx.resolve() i.rx.set_input(False) assert not is_.rx.resolve() def test_reactive_in(): - i = reactive(2) + i = rx(2) in_ = i.rx.in_([1, 2, 3]) assert in_.rx.resolve() i.rx.set_input(4) assert not in_.rx.resolve() def test_reactive_is_not(): - i = reactive(None) + i = rx(None) is_ = i.rx.is_not(None) assert not is_.rx.resolve() i.rx.set_input(False) @@ -275,7 +275,7 @@ def test_reactive_where_expr_refs(): assert results == ['string', 'foo', 2.1] def test_reactive_watch_on_set_input(): - string = reactive('string') + string = rx('string') new_string = string + '!' items = [] new_string.rx.watch(items.append) diff --git a/tests/testrefs.py b/tests/testrefs.py index d286c33c..f1f6ea9b 100644 --- a/tests/testrefs.py +++ b/tests/testrefs.py @@ -1,7 +1,7 @@ import param import pytest -from param.reactive import bind, reactive +from param.reactive import bind, rx class Parameters(param.Parameterized): @@ -49,7 +49,7 @@ def test_bind_ref(): assert p2.string == 'new string!' def test_reactive_ref(): - string = reactive('string') + string = rx('string') rx_string = string+'!' p = Parameters(string=rx_string) assert p.string == 'string!'