fix rx.cond with ComputedVars and use union type (#3336)

This commit is contained in:
benedikt-bartscher 2024-05-19 21:14:46 +02:00 committed by GitHub
parent b614e38047
commit 656914edef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 6 deletions

View File

@ -1,7 +1,8 @@
"""Create a list of components from an iterable."""
from __future__ import annotations
from typing import Any, Dict, Optional, overload
from typing import Any, Dict, Optional, Union, overload
from reflex.components.base.fragment import Fragment
from reflex.components.component import BaseComponent, Component, MemoizationLeaf
@ -10,7 +11,7 @@ from reflex.constants import Dirs
from reflex.constants.colors import Color
from reflex.style import LIGHT_COLOR_MODE, color_mode
from reflex.utils import format, imports
from reflex.vars import BaseVar, Var, VarData
from reflex.vars import Var, VarData
_IS_TRUE_IMPORT = {
f"/{Dirs.STATE_PATH}": [imports.ImportVar(tag="isTrue")],
@ -171,6 +172,11 @@ def cond(condition: Any, c1: Any, c2: Any = None):
c2 = create_var(c2)
var_datas.extend([c1._var_data, c2._var_data])
c1_type = c1._var_type if isinstance(c1, Var) else type(c1)
c2_type = c2._var_type if isinstance(c2, Var) else type(c2)
var_type = c1_type if c1_type == c2_type else Union[c1_type, c2_type]
# Create the conditional var.
return cond_var._replace(
_var_name=format.format_cond(
@ -179,7 +185,7 @@ def cond(condition: Any, c1: Any, c2: Any = None):
false_value=c2,
is_prop=True,
),
_var_type=c1._var_type if isinstance(c1, BaseVar) else type(c1),
_var_type=var_type,
_var_is_local=False,
_var_full_name_needs_state_prefix=False,
merge_var_data=VarData.merge(*var_datas),

View File

@ -1,13 +1,14 @@
import json
from typing import Any
from typing import Any, Union
import pytest
from reflex.components.base.fragment import Fragment
from reflex.components.core.cond import Cond, cond
from reflex.components.radix.themes.typography.text import Text
from reflex.state import BaseState
from reflex.vars import Var
from reflex.state import BaseState, State
from reflex.utils.format import format_state_name
from reflex.vars import BaseVar, Var, computed_var
@pytest.fixture
@ -118,3 +119,29 @@ def test_cond_no_else():
# Props do not support the use of cond without else
with pytest.raises(ValueError):
cond(True, "hello") # type: ignore
def test_cond_computed_var():
"""Test if cond works with computed vars."""
class CondStateComputed(State):
@computed_var
def computed_int(self) -> int:
return 0
@computed_var
def computed_str(self) -> str:
return "a string"
comp = cond(True, CondStateComputed.computed_int, CondStateComputed.computed_str)
# TODO: shouln't this be a ComputedVar?
assert isinstance(comp, BaseVar)
state_name = format_state_name(CondStateComputed.get_full_name())
assert (
str(comp)
== f"{{isTrue(true) ? {state_name}.computed_int : {state_name}.computed_str}}"
)
assert comp._var_type == Union[int, str]