Skip to content

Commit 50e8877

Browse files
committed
Add _validate_component_children bypass for experimental memo wrappers
Memo wrappers are transparent in the authored component tree — they should not trigger _valid_parents checks against themselves. Override _validate_component_children on ExperimentalMemoComponent to skip the check, preventing false validation failures when a restricted child (e.g. _valid_parents = ["ValidParent"]) is wrapped in a memo before being placed inside its valid parent.
1 parent ee4dcb4 commit 50e8877

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

reflex/experimental/memo.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,19 @@ class ExperimentalMemoComponent(Component):
7676

7777
library = f"$/{constants.Dirs.COMPONENTS_PATH}"
7878

79+
def _validate_component_children(self, children: list[Component]) -> None:
80+
"""Skip direct parent/child validation for memo wrapper instances.
81+
82+
Experimental memos wrap an underlying compiled component definition.
83+
The runtime wrapper should not interpose on `_valid_parents` checks for
84+
the authored subtree because the wrapper itself is not the semantic
85+
parent in the user-authored component tree.
86+
87+
Args:
88+
children: The children of the component (ignored).
89+
"""
90+
del children
91+
7992
def _post_init(self, **kwargs):
8093
"""Initialize the experimental memo component.
8194

tests/units/experimental/test_memo.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,29 @@ def wrapper() -> rx.Component:
415415
assert definition.component.style == Style()
416416

417417

418+
def test_component_returning_memo_is_transparent_for_child_validation():
419+
"""Experimental memo wrappers should not break `_valid_parents` checks."""
420+
421+
class ValidParent(Component):
422+
tag = "ValidParent"
423+
library = "valid-parent"
424+
425+
class RestrictedChild(Component):
426+
tag = "RestrictedChild"
427+
library = "restricted-child"
428+
_valid_parents = ["ValidParent"]
429+
430+
@rx._x.memo
431+
def transparent(children: rx.Var[rx.Component]) -> rx.Component:
432+
return children # type: ignore[return-value]
433+
434+
wrapped_child = transparent(RestrictedChild.create())
435+
parent = ValidParent.create(wrapped_child)
436+
437+
assert isinstance(wrapped_child, ExperimentalMemoComponent)
438+
assert parent.children == [wrapped_child]
439+
440+
418441
def test_compile_memo_components_includes_experimental_custom_code():
419442
"""Experimental component memos should include custom code in compiled output."""
420443

0 commit comments

Comments
 (0)