Skip to content

Commit 40309e1

Browse files
fix: properly initialize rx.Field annotated backend vars in mixin states (#5909)
* fix: properly initialize rx.Field annotated backend vars in mixin states * fix: check mixin_cls instead of cls * add some basic tests * i missed this one
1 parent b6a62eb commit 40309e1

File tree

3 files changed

+24
-10
lines changed

3 files changed

+24
-10
lines changed

reflex/state.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -523,15 +523,17 @@ def __init_subclass__(cls, mixin: bool = False, **kwargs):
523523

524524
new_backend_vars = {
525525
name: value if not isinstance(value, Field) else value.default_value()
526-
for name, value in list(cls.__dict__.items())
527-
if types.is_backend_base_variable(name, cls)
526+
for mixin_cls in [*cls._mixins(), cls]
527+
for name, value in list(mixin_cls.__dict__.items())
528+
if types.is_backend_base_variable(name, mixin_cls)
528529
}
529530
# Add annotated backend vars that may not have a default value.
530531
new_backend_vars.update({
531532
name: cls._get_var_default(name, annotation_value)
532-
for name, annotation_value in cls._get_type_hints().items()
533+
for mixin_cls in [*cls._mixins(), cls]
534+
for name, annotation_value in mixin_cls._get_type_hints().items()
533535
if name not in new_backend_vars
534-
and types.is_backend_base_variable(name, cls)
536+
and types.is_backend_base_variable(name, mixin_cls)
535537
})
536538

537539
cls.backend_vars = {
@@ -579,9 +581,6 @@ def __init_subclass__(cls, mixin: bool = False, **kwargs):
579581
cls.computed_vars[name] = newcv
580582
cls.vars[name] = newcv
581583
continue
582-
if types.is_backend_base_variable(name, mixin_cls):
583-
cls.backend_vars[name] = copy.deepcopy(value)
584-
continue
585584
if events.get(name) is not None:
586585
continue
587586
if not cls._item_is_event_handler(name, value):

tests/units/test_state.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,14 @@ class Object(Base):
110110
prop2: str = "hello"
111111

112112

113-
class TestState(BaseState):
113+
class TestMixin(BaseState, mixin=True):
114+
"""A test mixin."""
115+
116+
mixin: rx.Field[str] = rx.field("mixin_value")
117+
_mixin_backend: rx.Field[int] = rx.field(default_factory=lambda: 10)
118+
119+
120+
class TestState(TestMixin, BaseState): # pyright: ignore[reportUnsafeMultipleInheritance]
114121
"""A test state."""
115122

116123
# Set this class as not test one
@@ -342,6 +349,7 @@ def test_class_vars(test_state):
342349
"fig",
343350
"dt",
344351
"asynctest",
352+
"mixin",
345353
}
346354

347355

@@ -367,7 +375,7 @@ def test_event_handlers(test_state):
367375
assert all(key in cls.event_handlers for key in expected_keys)
368376

369377

370-
def test_default_value(test_state):
378+
def test_default_value(test_state: TestState):
371379
"""Test that the default value of a var is correct.
372380
373381
Args:
@@ -378,6 +386,10 @@ def test_default_value(test_state):
378386
assert test_state.key == ""
379387
assert test_state.sum == 3.15
380388
assert test_state.upper == ""
389+
assert test_state._backend == 0
390+
assert test_state.mixin == "mixin_value"
391+
assert test_state._mixin_backend == 10
392+
assert test_state.array == [1, 2, 3.15]
381393

382394

383395
def test_computed_vars(test_state):
@@ -735,7 +747,7 @@ def test_set_dirty_substate(
735747
assert grandchild_state.dirty_vars == set()
736748

737749

738-
def test_reset(test_state, child_state):
750+
def test_reset(test_state: TestState, child_state: ChildState):
739751
"""Test resetting the state.
740752
741753
Args:
@@ -771,6 +783,8 @@ def test_reset(test_state, child_state):
771783
"mapping",
772784
"dt",
773785
"_backend",
786+
"mixin",
787+
"_mixin_backend",
774788
"asynctest",
775789
}
776790

tests/units/utils/test_format.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ def test_format_query_params(input, output):
602602
"key" + FIELD_MARKER: "",
603603
"map_key" + FIELD_MARKER: "a",
604604
"mapping" + FIELD_MARKER: {"a": [1, 2, 3], "b": [4, 5, 6]},
605+
"mixin" + FIELD_MARKER: "mixin_value",
605606
"num1" + FIELD_MARKER: 0,
606607
"num2" + FIELD_MARKER: 3.15,
607608
"obj" + FIELD_MARKER: {"prop1": 42, "prop2": "hello"},

0 commit comments

Comments
 (0)