Skip to content

Commit b0813de

Browse files
committed
feat(express): Automatically suppress non-renderable UI objects
1 parent 36aa320 commit b0813de

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

shiny/express/_recall_context.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,44 @@
33
import functools
44
import sys
55
from types import TracebackType
6-
from typing import Callable, Generic, Mapping, Optional, Type, TypeVar
6+
from typing import Any, Callable, Generic, Mapping, Optional, Type, TypeVar
77

8-
from htmltools import MetadataNode, Tag, TagList, wrap_displayhook_handler
8+
from htmltools import (
9+
HTML,
10+
MetadataNode,
11+
ReprHtml,
12+
Tag,
13+
Tagifiable,
14+
TagList,
15+
wrap_displayhook_handler,
16+
)
917

1018
from .._typing_extensions import ParamSpec
19+
from ..render.renderer import Renderer
1120

1221
P = ParamSpec("P")
1322
R = TypeVar("R")
1423
U = TypeVar("U")
1524

1625

26+
def only_append_renderable(handler: Callable[[object], None]) -> Callable[[Any], None]:
27+
def f(x: Any):
28+
if isinstance(x, str):
29+
return handler(x)
30+
elif isinstance(x, (str, HTML, Tag, TagList, Tagifiable, ReprHtml, Renderer)):
31+
return handler(x) # pyright: ignore
32+
33+
x_trunc = f"{x!r}"[:20]
34+
35+
print(
36+
# TODO: Make this a more informative warning
37+
f"Express has suppressed the object `{x_trunc}` because it is of type {type(x)}. "
38+
"Coerce to HTML, a string, or an htmltools tag to display this object."
39+
)
40+
41+
return f
42+
43+
1744
class RecallContextManager(Generic[R]):
1845
def __init__(
1946
self,
@@ -31,7 +58,9 @@ def __init__(
3158
self.kwargs: dict[str, object] = dict(kwargs)
3259
# Let htmltools.wrap_displayhook_handler decide what to do with objects before
3360
# we append them.
34-
self.wrapped_append = wrap_displayhook_handler(self.args.append)
61+
self.wrapped_append = only_append_renderable(
62+
wrap_displayhook_handler(self.args.append)
63+
)
3564

3665
def __enter__(self) -> None:
3766
self._prev_displayhook = sys.displayhook

0 commit comments

Comments
 (0)