Skip to content

Commit 997b384

Browse files
authored
Merge pull request #77 from rstudio/calc-effect-capitalize
2 parents eb948ca + 158878a commit 997b384

File tree

12 files changed

+121
-157
lines changed

12 files changed

+121
-157
lines changed

examples/bind_event/app.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,19 @@
2929
def server(input: Inputs, output: Outputs, session: Session):
3030

3131
# i.e., observeEvent(once=False)
32-
@reactive.effect()
32+
@reactive.Effect()
3333
@event(input.btn)
3434
def _():
3535
print("@effect() event: ", str(input.btn()))
3636

3737
# i.e., eventReactive()
38-
@reactive.calc()
38+
@reactive.Calc()
3939
@event(input.btn)
40-
def btn() -> int:
41-
return input.btn()
40+
async def btn() -> int:
41+
return input.btn() + 2
4242

43-
@reactive.effect()
44-
def _():
43+
@reactive.Effect()
44+
async def _():
4545
print("@calc() event: ", str(btn()))
4646

4747
@output()
@@ -53,19 +53,19 @@ def btn_value():
5353
# -----------------------------------------------------------------------------
5454
# Async
5555
# -----------------------------------------------------------------------------
56-
@reactive.effect()
56+
@reactive.Effect()
5757
@event(input.btn_async)
5858
async def _():
5959
await asyncio.sleep(0)
6060
print("async @effect() event: ", str(input.btn_async()))
6161

62-
@reactive.calc()
62+
@reactive.Calc()
6363
@event(input.btn_async)
6464
async def btn_async_r() -> int:
6565
await asyncio.sleep(0)
6666
return input.btn_async()
6767

68-
@reactive.effect()
68+
@reactive.Effect()
6969
async def _():
7070
val = await btn_async_r()
7171
print("async @calc() event: ", str(val))

examples/inputs-update/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989

9090

9191
def server(input: Inputs, output: Outputs, session: Session):
92-
@reactive.effect()
92+
@reactive.Effect()
9393
def _():
9494
# We'll use these multiple times, so use short var names for
9595
# convenience.

examples/inputs/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def image():
132132
img: ImgData = {"src": str(dir / "rstudio-logo.png"), "width": "150px"}
133133
return img
134134

135-
@reactive.effect()
135+
@reactive.Effect()
136136
def _():
137137
btn = input.btn()
138138
if btn and btn > 0:
@@ -144,7 +144,7 @@ def _():
144144
)
145145
)
146146

147-
@reactive.effect()
147+
@reactive.Effect()
148148
def _():
149149
link = input.link()
150150
if link and link > 0:

examples/insert_ui/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222

2323
def server(input: Inputs, output: Outputs, session: Session):
24-
@reactive.calc()
24+
@reactive.Calc()
2525
def r():
2626
if input.n() is None:
2727
return
@@ -50,7 +50,7 @@ def _():
5050
"This slider is rendered via @render_ui()", "N", 0, 100, 20
5151
)
5252

53-
@reactive.effect()
53+
@reactive.Effect()
5454
def _():
5555
btn = input.btn()
5656
if btn % 2 == 1:

examples/moduleapp/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def counter_ui(
2020
def counter_server(input: ModuleInputs, output: ModuleOutputs, session: ModuleSession):
2121
count: reactive.Value[int] = reactive.Value(0)
2222

23-
@reactive.effect()
23+
@reactive.Effect()
2424
@event(input.button)
2525
def _():
2626
count.set(count() + 1)

examples/myapp/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424

2525
def server(input: Inputs, output: Outputs, session: Session):
26-
@reactive.calc()
26+
@reactive.Calc()
2727
def r():
2828
if input.n() is None:
2929
return
@@ -37,7 +37,7 @@ async def txt():
3737

3838
# This observer watches n, and changes shared_val, which is shared across
3939
# all running sessions.
40-
@reactive.effect()
40+
@reactive.Effect()
4141
def _():
4242
if input.n() is None:
4343
return

examples/req/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616

1717
def server(input: Inputs, output: Outputs, session: Session):
18-
@reactive.calc()
18+
@reactive.Calc()
1919
def safe_click():
2020
req(input.safe())
2121
return input.safe()
@@ -31,7 +31,7 @@ def unsafe():
3131
req(input.unsafe())
3232
raise Exception(f"Super secret number of clicks: {str(input.unsafe())}")
3333

34-
@reactive.effect()
34+
@reactive.Effect()
3535
def _():
3636
req(input.unsafe())
3737
print("unsafe clicks:", input.unsafe())

examples/simple/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
def server(input: Inputs, output: Outputs, session: Session):
13-
@reactive.calc()
13+
@reactive.Calc()
1414
def r():
1515
if input.n() is None:
1616
return

shiny/reactive/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"flush",
66
"on_flushed",
77
"Value",
8-
"calc",
9-
"effect",
8+
"Calc",
9+
"Effect",
1010
"isolate",
1111
"invalidate_later",
1212
)

shiny/reactive/_reactives.py

Lines changed: 27 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Reactive components"""
22

3-
__all__ = ("Value", "Calc", "CalcAsync", "calc", "Effect", "EffectAsync", "effect")
3+
__all__ = ("Value", "Calc", "Calc_", "CalcAsync_", "Effect", "Effect_")
44

55
import traceback
66
from typing import (
@@ -68,7 +68,7 @@ def _set(self, value: T) -> bool:
6868
CalcFunctionAsync = Callable[[], Awaitable[T]]
6969

7070

71-
class Calc(Generic[T]):
71+
class Calc_(Generic[T]):
7272
def __init__(
7373
self,
7474
fn: CalcFunction[T],
@@ -82,7 +82,7 @@ def __init__(
8282
# static type checker that it's synchronous. wrap_async() is smart -- if is
8383
# passed an async function, it will not change it.
8484
self._fn: CalcFunctionAsync[T] = _utils.wrap_async(fn)
85-
self._is_async: bool = False
85+
self._is_async: bool = _utils.is_async_callable(fn)
8686

8787
self._dependents: Dependents = Dependents()
8888
self._invalidated: bool = True
@@ -96,11 +96,11 @@ def __init__(
9696
# the type checker doesn't know that MISSING is the only instance of
9797
# MISSING_TYPE; this saves us from casting later on.
9898
if isinstance(session, MISSING_TYPE):
99-
import shiny.session
99+
from ..session import get_current_session
100100

101101
# If no session is provided, autodetect the current session (this
102102
# could be None if outside of a session).
103-
session = shiny.session.get_current_session()
103+
session = get_current_session()
104104
self._session = session
105105

106106
# Use lists to hold (optional) value and error, instead of Optional[T],
@@ -139,9 +139,9 @@ async def update_value(self) -> None:
139139
was_running = self._running
140140
self._running = True
141141

142-
import shiny.session
142+
from ..session import session_context
143143

144-
with shiny.session.session_context(self._session):
144+
with session_context(self._session):
145145
try:
146146
with self._ctx():
147147
await self._run_func()
@@ -162,7 +162,7 @@ async def _run_func(self) -> None:
162162
self._error.append(err)
163163

164164

165-
class CalcAsync(Calc[T]):
165+
class CalcAsync_(Calc_[T]):
166166
def __init__(
167167
self,
168168
fn: CalcFunctionAsync[T],
@@ -173,7 +173,6 @@ def __init__(
173173
raise TypeError(self.__class__.__name__ + " requires an async function")
174174

175175
super().__init__(cast(CalcFunction[T], fn), session=session)
176-
self._is_async = True
177176

178177
async def __call__(self) -> T:
179178
return await self.get_value()
@@ -198,15 +197,15 @@ async def __call__(self) -> T:
198197
# twice: once here, and once when we return a Calc object (which has a synchronous
199198
# __call__ method) or CalcAsync object (which has an async __call__ method), and it
200199
# works out.
201-
def calc(
200+
def Calc(
202201
*, session: Union[MISSING_TYPE, "Session", None] = MISSING
203-
) -> Callable[[CalcFunction[T]], Calc[T]]:
204-
def create_calc(fn: Union[CalcFunction[T], CalcFunctionAsync[T]]) -> Calc[T]:
202+
) -> Callable[[CalcFunction[T]], Calc_[T]]:
203+
def create_calc(fn: Union[CalcFunction[T], CalcFunctionAsync[T]]) -> Calc_[T]:
205204
if _utils.is_async_callable(fn):
206-
return CalcAsync(fn, session=session)
205+
return CalcAsync_(fn, session=session)
207206
else:
208207
fn = cast(CalcFunction[T], fn)
209-
return Calc(fn, session=session)
208+
return Calc_(fn, session=session)
210209

211210
return create_calc
212211

@@ -219,10 +218,10 @@ def create_calc(fn: Union[CalcFunction[T], CalcFunctionAsync[T]]) -> Calc[T]:
219218
EffectFunctionAsync = Callable[[], Awaitable[None]]
220219

221220

222-
class Effect:
221+
class Effect_:
223222
def __init__(
224223
self,
225-
fn: EffectFunction,
224+
fn: Union[EffectFunction, EffectFunctionAsync],
226225
*,
227226
suspended: bool = False,
228227
priority: int = 0,
@@ -235,7 +234,8 @@ def __init__(
235234
# static type checker that it's synchronous. wrap_async() is smart -- if is
236235
# passed an async function, it will not change it.
237236
self._fn: EffectFunctionAsync = _utils.wrap_async(fn)
238-
self._is_async: bool = False
237+
# This indicates whether the user's effect function (before wrapping) is async.
238+
self._is_async: bool = _utils.is_async_callable(fn)
239239

240240
self._priority: int = priority
241241
self._suspended = suspended
@@ -251,11 +251,11 @@ def __init__(
251251
# the type checker doesn't know that MISSING is the only instance of
252252
# MISSING_TYPE; this saves us from casting later on.
253253
if isinstance(session, MISSING_TYPE):
254-
import shiny.session
254+
from ..session import get_current_session
255255

256256
# If no session is provided, autodetect the current session (this
257257
# could be None if outside of a session).
258-
session = shiny.session.get_current_session()
258+
session = get_current_session()
259259
self._session = session
260260

261261
if self._session is not None:
@@ -302,9 +302,10 @@ async def on_flush_cb() -> None:
302302
async def run(self) -> None:
303303
ctx = self._create_context()
304304
self._exec_count += 1
305-
import shiny.session
306305

307-
with shiny.session.session_context(self._session):
306+
from ..session import session_context
307+
308+
with session_context(self._session):
308309
try:
309310
with ctx():
310311
await self._fn()
@@ -360,51 +361,14 @@ def _on_session_ended_cb(self) -> None:
360361
self.destroy()
361362

362363

363-
class EffectAsync(Effect):
364-
def __init__(
365-
self,
366-
fn: EffectFunctionAsync,
367-
*,
368-
suspended: bool = False,
369-
priority: int = 0,
370-
session: Union[MISSING_TYPE, "Session", None] = MISSING,
371-
) -> None:
372-
if not _utils.is_async_callable(fn):
373-
raise TypeError(self.__class__.__name__ + " requires an async function")
374-
375-
super().__init__(
376-
cast(EffectFunction, fn),
377-
suspended=suspended,
378-
session=session,
379-
priority=priority,
380-
)
381-
self._is_async = True
382-
383-
384-
def effect(
364+
def Effect(
385365
*,
386366
suspended: bool = False,
387367
priority: int = 0,
388368
session: Union[MISSING_TYPE, "Session", None] = MISSING,
389-
) -> Callable[[Union[EffectFunction, EffectFunctionAsync]], Effect]:
390-
"""[summary]
391-
392-
Args:
393-
priority : [description]. Defaults to 0.
394-
session : [description]. Defaults to MISSING.
395-
396-
Returns:
397-
[description]
398-
"""
399-
400-
def create_effect(fn: Union[EffectFunction, EffectFunctionAsync]) -> Effect:
401-
if _utils.is_async_callable(fn):
402-
fn = cast(EffectFunctionAsync, fn)
403-
return EffectAsync(
404-
fn, suspended=suspended, priority=priority, session=session
405-
)
406-
else:
407-
fn = cast(EffectFunction, fn)
408-
return Effect(fn, suspended=suspended, priority=priority, session=session)
369+
) -> Callable[[Union[EffectFunction, EffectFunctionAsync]], Effect_]:
370+
def create_effect(fn: Union[EffectFunction, EffectFunctionAsync]) -> Effect_:
371+
fn = cast(EffectFunction, fn)
372+
return Effect_(fn, suspended=suspended, priority=priority, session=session)
409373

410374
return create_effect

0 commit comments

Comments
 (0)