浏览代码

fail on using rxcond on event handlers or event spec (#5209)

* fail on using rxcond on event handlers or event spec

* Add unit tests for EventVar and EventChainVar bool() methods

Co-Authored-By: khaleel@reflex.dev <khaleel.aladhami@gmail.com>

* Update test to verify event handlers fail when used in rx.cond()

Co-Authored-By: khaleel@reflex.dev <khaleel.aladhami@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Khaleel Al-Adhami 1 周之前
父节点
当前提交
60df90770d
共有 2 个文件被更改,包括 51 次插入0 次删除
  1. 21 0
      reflex/event.py
  2. 30 0
      tests/units/test_event.py

+ 21 - 0
reflex/event.py

@@ -14,6 +14,7 @@ from typing import (
     Annotated,
     Annotated,
     Any,
     Any,
     Generic,
     Generic,
+    NoReturn,
     Protocol,
     Protocol,
     TypedDict,
     TypedDict,
     TypeVar,
     TypeVar,
@@ -1683,6 +1684,16 @@ prevent_default = noop().prevent_default
 class EventVar(ObjectVar, python_types=(EventSpec, EventHandler)):
 class EventVar(ObjectVar, python_types=(EventSpec, EventHandler)):
     """Base class for event vars."""
     """Base class for event vars."""
 
 
+    def bool(self) -> NoReturn:
+        """Get the boolean value of the var.
+
+        Raises:
+            TypeError: EventVar cannot be converted to a boolean.
+        """
+        raise TypeError(
+            f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
+        )
+
 
 
 @dataclasses.dataclass(
 @dataclasses.dataclass(
     eq=False,
     eq=False,
@@ -1759,6 +1770,16 @@ class LiteralEventVar(VarOperationCall, LiteralVar, EventVar):
 class EventChainVar(BuilderFunctionVar, python_types=EventChain):
 class EventChainVar(BuilderFunctionVar, python_types=EventChain):
     """Base class for event chain vars."""
     """Base class for event chain vars."""
 
 
+    def bool(self) -> NoReturn:
+        """Get the boolean value of the var.
+
+        Raises:
+            TypeError: EventChainVar cannot be converted to a boolean.
+        """
+        raise TypeError(
+            f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
+        )
+
 
 
 @dataclasses.dataclass(
 @dataclasses.dataclass(
     eq=False,
     eq=False,

+ 30 - 0
tests/units/test_event.py

@@ -485,6 +485,36 @@ def test_event_bound_method() -> None:
     _ = rx.input(on_change=w.get_handler)
     _ = rx.input(on_change=w.get_handler)
 
 
 
 
+def test_event_var_in_rx_cond():
+    """Test that EventVar and EventChainVar cannot be used in rx.cond()."""
+    from reflex.components.core.cond import cond as rx_cond
+
+    class S(BaseState):
+        @event
+        def s(self):
+            pass
+
+    handler_var = Var.create(S.s)
+    with pytest.raises(TypeError) as err:
+        rx_cond(handler_var, rx.text("True"), rx.text("False"))
+    assert "Cannot convert" in str(err.value)
+    assert "to bool" in str(err.value)
+
+    def _args_spec() -> tuple:
+        return ()
+
+    chain_var = Var.create(
+        EventChain(
+            events=[S.s()],
+            args_spec=_args_spec,
+        )
+    )
+    with pytest.raises(TypeError) as err:
+        rx_cond(chain_var, rx.text("True"), rx.text("False"))
+    assert "Cannot convert" in str(err.value)
+    assert "to bool" in str(err.value)
+
+
 def test_decentralized_event_with_args():
 def test_decentralized_event_with_args():
     """Test the decentralized event."""
     """Test the decentralized event."""