Procházet zdrojové kódy

fix: prevent AttributeError when using bare mixins (#5011)

benedikt-bartscher před 1 měsícem
rodič
revize
c661669359
2 změnil soubory, kde provedl 40 přidání a 1 odebrání
  1. 1 1
      reflex/state.py
  2. 39 0
      tests/units/test_state.py

+ 1 - 1
reflex/state.py

@@ -907,7 +907,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
             raise ValueError(f"Only one parent state is allowed {parent_states}.")
         # The first non-mixin state in the mro is our parent.
         for base in cls.mro()[1:]:
-            if base._mixin or not issubclass(base, BaseState):
+            if not issubclass(base, BaseState) or base._mixin:
                 continue
             if base is BaseState:
                 break

+ 39 - 0
tests/units/test_state.py

@@ -3436,6 +3436,30 @@ class GrandchildUsesMixinState(ChildMixinState):
     pass
 
 
+class BareMixin:
+    """A bare mixin which does not inherit from rx.State."""
+
+    _bare_mixin: int = 0
+
+
+class BareStateMixin(BareMixin, rx.State, mixin=True):
+    """A state mixin that uses a bare mixin."""
+
+    pass
+
+
+class BareMixinState(BareStateMixin, State):
+    """A state that uses a bare mixin."""
+
+    pass
+
+
+class ChildBareMixinState(BareMixinState):
+    """A child state that uses a bare mixin."""
+
+    pass
+
+
 def test_mixin_state() -> None:
     """Test that a mixin state works correctly."""
     assert "num" in UsesMixinState.base_vars
@@ -3481,6 +3505,21 @@ def test_grandchild_mixin_state() -> None:
     assert GrandchildUsesMixinState.get_root_state() == State
 
 
+def test_bare_mixin_state() -> None:
+    """Test that a mixin can inherit from a concrete state class."""
+    assert "_bare_mixin" not in BareMixinState.inherited_vars
+    assert "_bare_mixin" not in BareMixinState.base_vars
+
+    assert BareMixinState.get_parent_state() == State
+    assert BareMixinState.get_root_state() == State
+
+    assert "_bare_mixin" not in ChildBareMixinState.inherited_vars
+    assert "_bare_mixin" not in ChildBareMixinState.base_vars
+
+    assert ChildBareMixinState.get_parent_state() == BareMixinState
+    assert ChildBareMixinState.get_root_state() == State
+
+
 def test_assignment_to_undeclared_vars():
     """Test that an attribute error is thrown when undeclared vars are set."""