Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### New features

* Closed #814: The functions `reactive.Calc` and `reactive.Effect` have been changed to have lowercase names: `reactive.calc`, and `reactive.effect`. The old capitalized names are now aliases to the new lowercase names, so existing code will continue to work. Similarly, the class `reactive.Value` has a new alias, `reactive.value`, but in this case, since the original was a class, it keeps the original capitalized name as the primary name. The examples have not been changed yet, but will be changed in a future release. (#822)

### Bug fixes

* Fix support for `shiny.ui.accordion(multiple=)` (#799).
Expand Down
3 changes: 3 additions & 0 deletions docs/_quartodoc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ quartodoc:
- title: Reactive programming
desc: ""
contents:
- reactive.calc
- reactive.effect
- reactive.value
- reactive.Calc
- reactive.Effect
- reactive.Value
Expand Down
6 changes: 6 additions & 0 deletions shiny/reactive/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
)
from ._poll import poll, file_reader
from ._reactives import ( # noqa: F401
value,
Value,
calc,
Calc,
Calc_, # pyright: ignore[reportUnusedImport]
CalcAsync_, # pyright: ignore[reportUnusedImport]
effect,
Effect,
Effect_, # pyright: ignore[reportUnusedImport]
event,
Expand All @@ -26,8 +29,11 @@
"on_flushed",
"poll",
"file_reader",
"value",
"Value",
"calc",
"Calc",
"effect",
"Effect",
"event",
)
6 changes: 3 additions & 3 deletions shiny/reactive/_poll.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def poll(
last_value: reactive.Value[Any] = reactive.Value(poll_func())
last_error: reactive.Value[Optional[Exception]] = reactive.Value(None)

@reactive.Effect(priority=priority, session=session)
@reactive.effect(priority=priority, session=session)
async def _():
try:
if _utils.is_async_callable(poll_func):
Expand Down Expand Up @@ -159,7 +159,7 @@ async def _():
def wrapper(fn: Callable[[], T]) -> Callable[[], T]:
if _utils.is_async_callable(fn):

@reactive.Calc(session=session)
@reactive.calc(session=session)
@functools.wraps(fn)
async def result_async() -> T:
# If an error occurred, raise it
Expand All @@ -182,7 +182,7 @@ async def result_async() -> T:

else:

@reactive.Calc(session=session)
@reactive.calc(session=session)
@functools.wraps(fn)
def result_sync() -> T:
# If an error occurred, raise it
Expand Down
35 changes: 27 additions & 8 deletions shiny/reactive/_reactives.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@

from __future__ import annotations

__all__ = ("Value", "Calc", "Calc_", "CalcAsync_", "Effect", "Effect_", "event")
__all__ = (
"value",
"Value",
"calc",
"Calc",
"Calc_",
"CalcAsync_",
"effect",
"Effect",
"Effect_",
"event",
)

import functools
import traceback
Expand Down Expand Up @@ -204,6 +215,8 @@ def freeze(self) -> None:
self._value = MISSING


value = Value

# ==============================================================================
# Calc
# ==============================================================================
Expand Down Expand Up @@ -343,12 +356,12 @@ async def __call__(self) -> T: # pyright: ignore[reportIncompatibleMethodOverri


@overload
def Calc(fn: CalcFunctionAsync[T]) -> CalcAsync_[T]:
def calc(fn: CalcFunctionAsync[T]) -> CalcAsync_[T]:
...


@overload
def Calc(fn: CalcFunction[T]) -> Calc_[T]:
def calc(fn: CalcFunction[T]) -> Calc_[T]:
...


Expand All @@ -373,14 +386,14 @@ def Calc(fn: CalcFunction[T]) -> Calc_[T]:
# __call__ method) or CalcAsync object (which has an async __call__ method), and it
# works out.
@overload
def Calc(
def calc(
*, session: "MISSING_TYPE | Session | None" = MISSING
) -> Callable[[CalcFunction[T]], Calc_[T]]:
...


@add_example()
def Calc(
def calc(
fn: Optional[CalcFunction[T] | CalcFunctionAsync[T]] = None,
*,
session: "MISSING_TYPE | Session | None" = MISSING,
Expand Down Expand Up @@ -434,6 +447,9 @@ def create_calc(fn: CalcFunction[T] | CalcFunctionAsync[T]) -> Calc_[T]:
return create_calc(fn)


# Alias for backward compatibility
Calc = calc

# ==============================================================================
# Effect
# ==============================================================================
Expand Down Expand Up @@ -630,12 +646,12 @@ def _on_session_ended_cb(self) -> None:


@overload
def Effect(fn: EffectFunction | EffectFunctionAsync) -> Effect_:
def effect(fn: EffectFunction | EffectFunctionAsync) -> Effect_:
...


@overload
def Effect(
def effect(
*,
suspended: bool = False,
priority: int = 0,
Expand All @@ -645,7 +661,7 @@ def Effect(


@add_example()
def Effect(
def effect(
fn: Optional[EffectFunction | EffectFunctionAsync] = None,
*,
suspended: bool = False,
Expand Down Expand Up @@ -706,6 +722,9 @@ def create_effect(fn: EffectFunction | EffectFunctionAsync) -> Effect_:
return create_effect(fn)


Effect = effect


# ==============================================================================
# event decorator
# ==============================================================================
Expand Down
8 changes: 4 additions & 4 deletions shiny/session/_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
if TYPE_CHECKING:
from .._app import App

from .. import _utils, render
from .. import _utils, reactive, render
from .._connection import Connection, ConnectionClosed
from .._docstring import add_example
from .._fileupload import FileInfo, FileUploadManager
Expand All @@ -46,7 +46,7 @@
from .._utils import wrap_async
from ..http_staticfiles import FileResponse
from ..input_handler import input_handlers
from ..reactive import Effect, Effect_, Value, flush, isolate
from ..reactive import Effect_, Value, effect, flush, isolate
from ..reactive._core import lock, on_flushed
from ..render.transformer import OutputRenderer
from ..types import SafeException, SilentCancelOutputException, SilentException
Expand Down Expand Up @@ -904,7 +904,7 @@ def __init__(
self._ns = ns

def __setitem__(self, key: str, value: Value[Any]) -> None:
if not isinstance(value, Value):
if not isinstance(value, reactive.Value):
raise TypeError("`value` must be a reactive.Value object.")

self._map[self._ns(key)] = value
Expand Down Expand Up @@ -1008,7 +1008,7 @@ def set_renderer(renderer_fn: OutputRenderer[OT]) -> OutputRenderer[OT]:

self._suspend_when_hidden[output_name] = suspend_when_hidden

@Effect(
@effect(
suspended=suspend_when_hidden and self._session._is_hidden(output_name),
priority=priority,
)
Expand Down
4 changes: 2 additions & 2 deletions tests/deploys/apps/plotly_app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def summary_data():
height="100%",
)

@reactive.Calc
@reactive.calc
def filtered_df():
selected_idx = list(req(input.summary_data_selected_rows()))
countries = summary_df["country"][selected_idx]
Expand Down Expand Up @@ -116,7 +116,7 @@ def synchronize_size(output_id):
def wrapper(func):
input = session.get_current_session().input

@reactive.Effect
@reactive.effect
def size_updater():
func(
input[f".clientdata_output_{output_id}_width"](),
Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/TODO/sidebar/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,24 @@ def server(input: Inputs, output: Outputs, session: Session) -> None:
def ui_content():
return f"Hello, {input.adjective()} {input.animal()}!"

@reactive.Effect
@reactive.effect
@reactive.event(input.open_all)
def _():
ui.update_sidebar("sidebar_inner", show=True)
ui.update_sidebar("sidebar_outer", show=True)

@reactive.Effect
@reactive.effect
@reactive.event(input.close_all)
def _():
ui.update_sidebar("sidebar_inner", show=False)
ui.update_sidebar("sidebar_outer", show=False)

@reactive.Effect
@reactive.effect
@reactive.event(input.toggle_inner)
def _():
ui.update_sidebar("sidebar_inner", show=not input.sidebar_inner())

@reactive.Effect
@reactive.effect
@reactive.event(input.toggle_outer)
def _():
ui.update_sidebar("sidebar_outer", show=not input.sidebar_outer())
Expand Down
6 changes: 3 additions & 3 deletions tests/e2e/TODO/update_popover/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@


def server(input: Inputs, output: Outputs, session: Session):
@reactive.Effect
@reactive.effect
def _():
# Immediately display popover
ui.update_popover("popover_id", show=True)

@reactive.Effect
@reactive.effect
@reactive.event(input.btn_update)
def _():
content = (
Expand All @@ -33,7 +33,7 @@ def _():
# show=True
)

@reactive.Effect
@reactive.effect
def _():
req(input.btn_w_popover())
ui.notification_show("Button clicked!", duration=3, type="message")
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/async/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async def hash_output():
content = await hash_result()
return content

@reactive.Calc()
@reactive.calc()
async def hash_result() -> str:
with ui.Progress() as p:
p.set(message="Calculating...")
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/bugs/0648-update-slider-datetime-value/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def txt():
else:
return input.times()

@reactive.Effect
@reactive.effect
@reactive.event(input.reset)
def reset_time():
ui.update_slider("times", min=min, max=max, value=value)
Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/bugs/0696-resolve-id/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def mod_x_server(
):
session_dict[session.ns] = session

@reactive.Calc
@reactive.calc
def n():
return int(letters.index(input.input_radio_buttons()))

Expand Down Expand Up @@ -394,7 +394,7 @@ def server(input: Inputs, output: Outputs, session: Session):
ui.update_popover("explanation", show=True)

# On button clicks, hide the explanation popover
@reactive.Effect(suspended=True)
@reactive.effect(suspended=True)
def _():
input.reset()
input.update_global()
Expand Down Expand Up @@ -482,7 +482,7 @@ def update_session(
for _input_key, session_key in module_keys:
offsets[session_key] = 0

@reactive.Effect
@reactive.effect
def _():
# trigger reactivity
input.reset()
Expand All @@ -492,7 +492,7 @@ def _():
update_session(session_dict[session_key], count=0)

def update_session_effect(*, input_key: str, session_key: str) -> None:
@reactive.Effect
@reactive.effect
@reactive.event(input[input_key])
def _():
update_session(
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/inputs/input_file/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


def server(input: Inputs, output: Outputs, session: Session):
@reactive.Calc
@reactive.calc
def parsed_file():
file: typing.Union[typing.List["FileInfo"], None] = input.file1()
if file is None:
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/navs/navset_hidden/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


def server(input: Inputs, output: Outputs, session: Session):
@reactive.Effect
@reactive.effect
@reactive.event(input.controller)
def _():
ui.update_navs("hidden_tabs", selected="panel" + str(input.controller()))
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/session/flush/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,11 @@ def _():
# Continuously trigger the reactive graph to ensure that the flush / flushed
# callbacks are called. If this Effect is not called, then the click counter will
# always be one higher than the flush/flushed values displayed.
@reactive.Effect
@reactive.effect
def _():
reactive.invalidate_later(0.25)

@reactive.Effect
@reactive.effect
@reactive.event(input.btn)
def _():
btn_count = input.btn()
Expand Down
Loading