Skip to content

Commit 8127f1a

Browse files
authored
Rename suspend_display->hold, display_body->expressify, render.display-> render.express (#1037)
1 parent de2b063 commit 8127f1a

File tree

27 files changed

+315
-216
lines changed

27 files changed

+315
-216
lines changed

examples/express/expressify_app.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from shiny.express import expressify, ui
2+
3+
4+
# @expressify converts a function to work with Express syntax
5+
@expressify
6+
def expressified1(s: str):
7+
f"Expressified function 1: {s}" # noqa: B021
8+
ui.br()
9+
10+
11+
expressified1("Hello")
12+
13+
expressified1("world")
14+
15+
16+
ui.br()
17+
18+
19+
# @expressify() also works with parens
20+
@expressify()
21+
def expressified2(s: str):
22+
f"Expressified function 2: {s}" # noqa: B021
23+
ui.br()
24+
25+
26+
expressified2("Hello")
27+
28+
expressified2("world")

examples/express/hold_app.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import shiny.ui
2+
from shiny.express import input, render, ui
3+
4+
# `ui.hold() as x` can be used to save `x` for later output
5+
with ui.hold() as hello_card:
6+
with ui.card():
7+
with ui.span():
8+
"This is a"
9+
ui.span(" card", style="color: red;")
10+
11+
hello_card
12+
13+
hello_card
14+
15+
ui.hr()
16+
17+
18+
# `ui.hold()` can be used to just suppress output
19+
with ui.hold():
20+
21+
@render.text()
22+
def txt():
23+
return f"Slider value: {input.n()}"
24+
25+
26+
ui.input_slider("n", "N", 1, 100, 50)
27+
28+
shiny.ui.output_text("txt", inline=True)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from shiny.express import input, render, ui
2+
3+
ui.input_slider("n", "N", 1, 100, 50)
4+
5+
6+
# @render.express is like @render.ui, but with Express syntax
7+
@render.express
8+
def render_express1():
9+
"Slider value:"
10+
input.n()
11+
12+
13+
# @render.express() also works with parens
14+
@render.express()
15+
def render_express2():
16+
"Slider value:"
17+
input.n()

shiny/api-examples/render_display/app.py

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import datetime
2+
3+
from shiny.express import input, render, ui
4+
5+
with ui.card(id="card"):
6+
ui.input_slider("val", "slider", 0, 100, 50)
7+
"Text outside of render express call"
8+
ui.tags.br()
9+
f"Rendered time: {str(datetime.datetime.now())}"
10+
11+
@render.express
12+
def render_express():
13+
"Text inside of render express call"
14+
ui.tags.br()
15+
"Dynamic slider value: "
16+
input.val()
17+
ui.tags.br()
18+
f"Rendered time: {str(datetime.datetime.now())}"

shiny/express/__init__.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
from . import ui
99
from ._is_express import is_express_app
1010
from ._output import ( # noqa: F401
11-
suspend_display,
1211
output_args, # pyright: ignore[reportUnusedImport]
12+
suspend_display, # pyright: ignore[reportUnusedImport] - Deprecated
1313
)
1414
from ._run import wrap_express_app
15-
from .display_decorator import display_body
15+
from .expressify_decorator import expressify
1616

1717

1818
__all__ = (
@@ -21,10 +21,9 @@
2121
"output",
2222
"session",
2323
"is_express_app",
24-
"suspend_display",
2524
"wrap_express_app",
2625
"ui",
27-
"display_body",
26+
"expressify",
2827
)
2928

3029
# Add types to help type checkers

shiny/express/_output.py

Lines changed: 14 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
from __future__ import annotations
22

3-
import contextlib
4-
import sys
53
from contextlib import AbstractContextManager
6-
from typing import Callable, Generator, TypeVar, cast, overload
4+
from typing import Callable, TypeVar
75

8-
from .. import ui
9-
from ..render.renderer import Renderer, RendererT
6+
from .._deprecated import warn_deprecated
7+
from .._typing_extensions import ParamSpec
8+
from ..render.renderer import RendererT
9+
from .ui import hold
1010

1111
__all__ = ("suspend_display",)
1212

13+
P = ParamSpec("P")
14+
R = TypeVar("R")
1315
CallableT = TypeVar("CallableT", bound=Callable[..., object])
1416

1517

@@ -45,82 +47,11 @@ def wrapper(renderer: RendererT) -> RendererT:
4547
return wrapper
4648

4749

48-
@overload
49-
def suspend_display(fn: RendererT) -> RendererT:
50-
...
51-
52-
53-
@overload
54-
def suspend_display(fn: CallableT) -> CallableT:
55-
...
56-
57-
58-
@overload
59-
def suspend_display() -> AbstractContextManager[None]:
60-
...
61-
62-
6350
def suspend_display(
64-
fn: RendererT | CallableT | None = None,
65-
) -> RendererT | CallableT | AbstractContextManager[None]:
66-
"""Suppresses the display of UI elements in various ways.
67-
68-
If used as a context manager (`with suspend_display():`), it suppresses the display
69-
of all UI elements within the context block. (This is useful when you want to
70-
temporarily suppress the display of a large number of UI elements, or when you want
71-
to suppress the display of UI elements that are not directly under your control.)
72-
73-
If used as a decorator (without parentheses) on a Shiny rendering function, it
74-
prevents that function from automatically outputting itself at the point of its
75-
declaration. (This is useful when you want to define the rendering logic for an
76-
output, but want to explicitly call a UI output function to indicate where and how
77-
it should be displayed.)
78-
79-
If used as a decorator (without parentheses) on any other function, it turns
80-
Python's `sys.displayhook` into a no-op for the duration of the function call.
81-
82-
Parameters
83-
----------
84-
fn
85-
The function to decorate. If `None`, returns a context manager that suppresses
86-
the display of UI elements within the context block.
87-
88-
Returns
89-
-------
90-
:
91-
If `fn` is `None`, returns a context manager that suppresses the display of UI
92-
elements within the context block. Otherwise, returns a decorated version of
93-
`fn`.
94-
"""
95-
96-
if fn is None:
97-
return suspend_display_ctxmgr()
98-
99-
# Special case for Renderer; when we decorate those, we just mean "don't
100-
# display yourself"
101-
if isinstance(fn, Renderer):
102-
# By setting the class value, the `self` arg will be auto added.
103-
fn.auto_output_ui = null_ui
104-
return cast(RendererT, fn)
105-
106-
return suspend_display_ctxmgr()(fn)
107-
108-
109-
@contextlib.contextmanager
110-
def suspend_display_ctxmgr() -> Generator[None, None, None]:
111-
oldhook = sys.displayhook
112-
sys.displayhook = null_displayhook
113-
try:
114-
yield
115-
finally:
116-
sys.displayhook = oldhook
117-
118-
119-
def null_ui(
120-
**kwargs: object,
121-
) -> ui.TagList:
122-
return ui.TagList()
123-
124-
125-
def null_displayhook(x: object) -> None:
126-
pass
51+
fn: Callable[P, R] | RendererT | None = None
52+
) -> Callable[P, R] | RendererT | AbstractContextManager[None]:
53+
warn_deprecated(
54+
"`suspend_display` is deprecated. Please use `ui.hold` instead. "
55+
"It has a new name, but the exact same functionality."
56+
)
57+
return hold(fn) # type: ignore

shiny/express/_run.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
from .._app import App
1111
from ..session import Inputs, Outputs, Session
1212
from ._recall_context import RecallContextManager
13-
from .display_decorator._func_displayhook import _display_decorator_function_def
14-
from .display_decorator._node_transformers import (
13+
from .expressify_decorator._func_displayhook import _expressify_decorator_function_def
14+
from .expressify_decorator._node_transformers import (
1515
DisplayFuncsTransformer,
16-
display_decorator_func_name,
16+
expressify_decorator_func_name,
1717
)
1818

1919
__all__ = ("wrap_express_app",)
@@ -83,7 +83,7 @@ def set_result(x: object):
8383

8484
var_context: dict[str, object] = {
8585
"__file__": file_path,
86-
display_decorator_func_name: _display_decorator_function_def,
86+
expressify_decorator_func_name: _expressify_decorator_function_def,
8787
"input": InputNotImportedShim(),
8888
}
8989

shiny/express/display_decorator/__init__.py

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from ._expressify import expressify
2+
3+
__all__ = ("expressify",)

0 commit comments

Comments
 (0)