Skip to content

Commit 5d0ddff

Browse files
authored
optimize various var functions (#5865)
* optimize various var functions * more optimizations
1 parent 5fd8ea9 commit 5d0ddff

File tree

8 files changed

+321
-68
lines changed

8 files changed

+321
-68
lines changed

reflex/components/markdown/markdown.py

Lines changed: 101 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,84 @@
3838
NO_PROPS_TAGS = ("ul", "ol", "li")
3939

4040

41+
def _h1(value: object):
42+
from reflex.components.radix.themes.typography.heading import Heading
43+
44+
return Heading.create(value, as_="h1", size="6", margin_y="0.5em")
45+
46+
47+
def _h2(value: object):
48+
from reflex.components.radix.themes.typography.heading import Heading
49+
50+
return Heading.create(value, as_="h2", size="5", margin_y="0.5em")
51+
52+
53+
def _h3(value: object):
54+
from reflex.components.radix.themes.typography.heading import Heading
55+
56+
return Heading.create(value, as_="h3", size="4", margin_y="0.5em")
57+
58+
59+
def _h4(value: object):
60+
from reflex.components.radix.themes.typography.heading import Heading
61+
62+
return Heading.create(value, as_="h4", size="3", margin_y="0.5em")
63+
64+
65+
def _h5(value: object):
66+
from reflex.components.radix.themes.typography.heading import Heading
67+
68+
return Heading.create(value, as_="h5", size="2", margin_y="0.5em")
69+
70+
71+
def _h6(value: object):
72+
from reflex.components.radix.themes.typography.heading import Heading
73+
74+
return Heading.create(value, as_="h6", size="1", margin_y="0.5em")
75+
76+
77+
def _p(value: object):
78+
from reflex.components.radix.themes.typography.text import Text
79+
80+
return Text.create(value, margin_y="1em")
81+
82+
83+
def _ul(value: object):
84+
from reflex.components.radix.themes.layout.list import UnorderedList
85+
86+
return UnorderedList.create(value, margin_y="1em")
87+
88+
89+
def _ol(value: object):
90+
from reflex.components.radix.themes.layout.list import OrderedList
91+
92+
return OrderedList.create(value, margin_y="1em")
93+
94+
95+
def _li(value: object):
96+
from reflex.components.radix.themes.layout.list import ListItem
97+
98+
return ListItem.create(value, margin_y="0.5em")
99+
100+
101+
def _a(value: object):
102+
from reflex.components.radix.themes.typography.link import Link
103+
104+
return Link.create(value)
105+
106+
107+
def _code(value: object):
108+
from reflex.components.radix.themes.typography.code import Code
109+
110+
return Code.create(value)
111+
112+
113+
def _codeblock(value: object, **props):
114+
from reflex.components.datadisplay.code import CodeBlock
115+
116+
return CodeBlock.create(value, margin_y="1em", wrap_long_lines=True, **props)
117+
118+
41119
# Component Mapping
42120
@lru_cache
43121
def get_base_component_map() -> dict[str, Callable]:
@@ -46,33 +124,20 @@ def get_base_component_map() -> dict[str, Callable]:
46124
Returns:
47125
The base component map.
48126
"""
49-
from reflex.components.datadisplay.code import CodeBlock
50-
from reflex.components.radix.themes.layout.list import (
51-
ListItem,
52-
OrderedList,
53-
UnorderedList,
54-
)
55-
from reflex.components.radix.themes.typography.code import Code
56-
from reflex.components.radix.themes.typography.heading import Heading
57-
from reflex.components.radix.themes.typography.link import Link
58-
from reflex.components.radix.themes.typography.text import Text
59-
60127
return {
61-
"h1": lambda value: Heading.create(value, as_="h1", size="6", margin_y="0.5em"),
62-
"h2": lambda value: Heading.create(value, as_="h2", size="5", margin_y="0.5em"),
63-
"h3": lambda value: Heading.create(value, as_="h3", size="4", margin_y="0.5em"),
64-
"h4": lambda value: Heading.create(value, as_="h4", size="3", margin_y="0.5em"),
65-
"h5": lambda value: Heading.create(value, as_="h5", size="2", margin_y="0.5em"),
66-
"h6": lambda value: Heading.create(value, as_="h6", size="1", margin_y="0.5em"),
67-
"p": lambda value: Text.create(value, margin_y="1em"),
68-
"ul": lambda value: UnorderedList.create(value, margin_y="1em"),
69-
"ol": lambda value: OrderedList.create(value, margin_y="1em"),
70-
"li": lambda value: ListItem.create(value, margin_y="0.5em"),
71-
"a": lambda value: Link.create(value),
72-
"code": lambda value: Code.create(value),
73-
"codeblock": lambda value, **props: CodeBlock.create(
74-
value, margin_y="1em", wrap_long_lines=True, **props
75-
),
128+
"h1": _h1,
129+
"h2": _h2,
130+
"h3": _h3,
131+
"h4": _h4,
132+
"h5": _h5,
133+
"h6": _h6,
134+
"p": _p,
135+
"ul": _ul,
136+
"ol": _ol,
137+
"li": _li,
138+
"a": _a,
139+
"code": _code,
140+
"codeblock": _codeblock,
76141
}
77142

78143

@@ -413,7 +478,16 @@ def _get_map_fn_custom_code_from_children(
413478
@staticmethod
414479
def _component_map_hash(component_map: dict) -> str:
415480
inp = str(
416-
{tag: component(_MOCK_ARG) for tag, component in component_map.items()}
481+
{
482+
tag: (
483+
f"{component.__module__}.{component.__qualname__}"
484+
if (
485+
"<" not in component.__name__
486+
) # simple way to check against lambdas
487+
else component(_MOCK_ARG)
488+
)
489+
for tag, component in component_map.items()
490+
}
417491
).encode()
418492
return md5(inp).hexdigest()
419493

reflex/utils/types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ def is_literal(cls: GenericType) -> bool:
291291
return getattr(cls, "__origin__", None) is Literal
292292

293293

294+
@lru_cache
294295
def has_args(cls: type) -> bool:
295296
"""Check if the class has generic parameters.
296297

reflex/vars/base.py

Lines changed: 104 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,82 @@ def _create_literal_var(
15271527
def __post_init__(self):
15281528
"""Post-initialize the var."""
15291529

1530+
@classmethod
1531+
def _get_all_var_data_without_creating_var(
1532+
cls,
1533+
value: Any,
1534+
) -> VarData | None:
1535+
return cls.create(value)._get_all_var_data()
1536+
1537+
@classmethod
1538+
def _get_all_var_data_without_creating_var_dispatch(
1539+
cls,
1540+
value: Any,
1541+
) -> VarData | None:
1542+
"""Get all the var data without creating a var.
1543+
1544+
Args:
1545+
value: The value to get the var data from.
1546+
1547+
Returns:
1548+
The var data or None.
1549+
1550+
Raises:
1551+
TypeError: If the value is not a supported type for LiteralVar.
1552+
"""
1553+
from .object import LiteralObjectVar
1554+
from .sequence import LiteralStringVar
1555+
1556+
if isinstance(value, Var):
1557+
return value._get_all_var_data()
1558+
1559+
for literal_subclass, var_subclass in _var_literal_subclasses[::-1]:
1560+
if isinstance(value, var_subclass.python_types):
1561+
return literal_subclass._get_all_var_data_without_creating_var(value)
1562+
1563+
if (
1564+
(as_var_method := getattr(value, "_as_var", None)) is not None
1565+
and callable(as_var_method)
1566+
and isinstance((resulting_var := as_var_method()), Var)
1567+
):
1568+
return resulting_var._get_all_var_data()
1569+
1570+
from reflex.event import EventHandler
1571+
from reflex.utils.format import get_event_handler_parts
1572+
1573+
if isinstance(value, EventHandler):
1574+
return Var(
1575+
_js_expr=".".join(filter(None, get_event_handler_parts(value)))
1576+
)._get_all_var_data()
1577+
1578+
serialized_value = serializers.serialize(value)
1579+
if serialized_value is not None:
1580+
if isinstance(serialized_value, Mapping):
1581+
return LiteralObjectVar._get_all_var_data_without_creating_var(
1582+
serialized_value
1583+
)
1584+
if isinstance(serialized_value, str):
1585+
return LiteralStringVar._get_all_var_data_without_creating_var(
1586+
serialized_value
1587+
)
1588+
return LiteralVar._get_all_var_data_without_creating_var_dispatch(
1589+
serialized_value
1590+
)
1591+
1592+
if dataclasses.is_dataclass(value) and not isinstance(value, type):
1593+
return LiteralObjectVar._get_all_var_data_without_creating_var(
1594+
{
1595+
k: (None if callable(v) else v)
1596+
for k, v in dataclasses.asdict(value).items()
1597+
}
1598+
)
1599+
1600+
if isinstance(value, range):
1601+
return None
1602+
1603+
msg = f"Unsupported type {type(value)} for LiteralVar. Tried to create a LiteralVar from {value}."
1604+
raise TypeError(msg)
1605+
15301606
@property
15311607
def _var_value(self) -> Any:
15321608
msg = "LiteralVar subclasses must implement the _var_value property."
@@ -1688,30 +1764,30 @@ def figure_out_type(value: Any) -> types.GenericType:
16881764
Returns:
16891765
The type of the value.
16901766
"""
1691-
if isinstance(value, Var):
1692-
return value._var_type
1693-
type_ = type(value)
1694-
if has_args(type_):
1695-
return type_
1696-
if isinstance(value, list):
1697-
if not value:
1698-
return Sequence[NoReturn]
1699-
return Sequence[unionize(*(figure_out_type(v) for v in value))]
1700-
if isinstance(value, set):
1701-
return set[unionize(*(figure_out_type(v) for v in value))]
1702-
if isinstance(value, tuple):
1703-
if not value:
1704-
return tuple[NoReturn, ...]
1705-
if len(value) <= 5:
1706-
return tuple[tuple(figure_out_type(v) for v in value)]
1707-
return tuple[unionize(*(figure_out_type(v) for v in value)), ...]
1708-
if isinstance(value, Mapping):
1709-
if not value:
1710-
return Mapping[NoReturn, NoReturn]
1711-
return Mapping[
1712-
unionize(*(figure_out_type(k) for k in value)),
1713-
unionize(*(figure_out_type(v) for v in value.values())),
1714-
]
1767+
if isinstance(value, (list, set, tuple, Mapping, Var)):
1768+
if isinstance(value, Var):
1769+
return value._var_type
1770+
if has_args(value_type := type(value)):
1771+
return value_type
1772+
if isinstance(value, list):
1773+
if not value:
1774+
return Sequence[NoReturn]
1775+
return Sequence[unionize(*{figure_out_type(v) for v in value[:100]})]
1776+
if isinstance(value, set):
1777+
return set[unionize(*{figure_out_type(v) for v in value})]
1778+
if isinstance(value, tuple):
1779+
if not value:
1780+
return tuple[NoReturn, ...]
1781+
if len(value) <= 5:
1782+
return tuple[tuple(figure_out_type(v) for v in value)]
1783+
return tuple[unionize(*{figure_out_type(v) for v in value[:100]}), ...]
1784+
if isinstance(value, Mapping):
1785+
if not value:
1786+
return Mapping[NoReturn, NoReturn]
1787+
return Mapping[
1788+
unionize(*{figure_out_type(k) for k in list(value.keys())[:100]}),
1789+
unionize(*{figure_out_type(v) for v in list(value.values())[:100]}),
1790+
]
17151791
return type(value)
17161792

17171793

@@ -2883,6 +2959,10 @@ def json(self) -> str:
28832959
"""
28842960
return "null"
28852961

2962+
@classmethod
2963+
def _get_all_var_data_without_creating_var(cls, value: None) -> VarData | None:
2964+
return None
2965+
28862966
@classmethod
28872967
def create(
28882968
cls,

reflex/vars/color.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ class LiteralColorVar(CachedVarOperation, LiteralVar, ColorVar):
2929

3030
_var_value: Color = dataclasses.field(default_factory=lambda: Color(color="black"))
3131

32+
@classmethod
33+
def _get_all_var_data_without_creating_var(
34+
cls,
35+
value: Color,
36+
) -> VarData | None:
37+
return VarData.merge(
38+
LiteralStringVar._get_all_var_data_without_creating_var(value.color)
39+
if isinstance(value.color, str)
40+
else value.color._get_all_var_data(),
41+
value.alpha._get_all_var_data()
42+
if not isinstance(value.alpha, bool)
43+
else None,
44+
value.shade._get_all_var_data()
45+
if not isinstance(value.shade, int)
46+
else None,
47+
)
48+
3249
@classmethod
3350
def create(
3451
cls,
@@ -111,14 +128,17 @@ def _cached_get_all_var_data(self) -> VarData | None:
111128
The var data.
112129
"""
113130
return VarData.merge(
114-
*[
115-
LiteralVar.create(var)._get_all_var_data()
116-
for var in (
117-
self._var_value.color,
118-
self._var_value.alpha,
119-
self._var_value.shade,
120-
)
121-
],
131+
LiteralStringVar._get_all_var_data_without_creating_var(
132+
self._var_value.color
133+
)
134+
if isinstance(self._var_value.color, str)
135+
else self._var_value.color._get_all_var_data(),
136+
self._var_value.alpha._get_all_var_data()
137+
if not isinstance(self._var_value.alpha, bool)
138+
else None,
139+
self._var_value.shade._get_all_var_data()
140+
if not isinstance(self._var_value.shade, int)
141+
else None,
122142
self._var_data,
123143
)
124144

reflex/vars/datetime.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,14 @@ def date_compare_operation(
174174
class LiteralDatetimeVar(LiteralVar, DateTimeVar):
175175
"""Base class for immutable datetime and date vars."""
176176

177-
_var_value: datetime | date = dataclasses.field(default=datetime.now())
177+
_var_value: date = dataclasses.field(default=datetime.now())
178178

179179
@classmethod
180-
def create(cls, value: datetime | date, _var_data: VarData | None = None):
180+
def _get_all_var_data_without_creating_var(cls, value: date) -> VarData | None:
181+
return None
182+
183+
@classmethod
184+
def create(cls, value: date, _var_data: VarData | None = None):
181185
"""Create a new instance of the class.
182186
183187
Args:

0 commit comments

Comments
 (0)