Skip to content

Commit e81bab7

Browse files
authored
don't treat name with - differently (#5291)
* don't treat name with - differently * ok i got things very wrong * improve performance * simplify even more code * fix the test
1 parent cf8f5db commit e81bab7

4 files changed

Lines changed: 56 additions & 91 deletions

File tree

reflex/components/component.py

Lines changed: 26 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
)
5959
from reflex.vars.function import ArgsFunctionOperation, FunctionStringVar, FunctionVar
6060
from reflex.vars.number import ternary_operation
61-
from reflex.vars.object import LiteralObjectVar, ObjectVar
61+
from reflex.vars.object import ObjectVar
6262
from reflex.vars.sequence import LiteralArrayVar, LiteralStringVar, StringVar
6363

6464

@@ -500,36 +500,16 @@ def _post_init(self, *args, **kwargs):
500500
else:
501501
continue
502502

503-
def determine_key(value: Any):
504-
# Try to create a var from the value
505-
key = value if isinstance(value, Var) else LiteralVar.create(value)
506-
507-
# Check that the var type is not None.
508-
if key is None:
509-
raise TypeError
510-
511-
return key
512-
513503
# Check whether the key is a component prop.
514504
if is_var:
515505
try:
516-
kwargs[key] = determine_key(value)
506+
kwargs[key] = LiteralVar.create(value)
517507

508+
# Get the passed type and the var type.
509+
passed_type = kwargs[key]._var_type
518510
expected_type = types.get_args(
519511
types.get_field_type(type(self), key)
520512
)[0]
521-
522-
# validate literal fields.
523-
types.validate_literal(
524-
key, value, expected_type, type(self).__name__
525-
)
526-
# Get the passed type and the var type.
527-
passed_type = kwargs[key]._var_type
528-
expected_type = (
529-
type(expected_type.__args__[0])
530-
if types.is_literal(expected_type)
531-
else expected_type
532-
)
533513
except TypeError:
534514
# If it is not a valid var, check the base types.
535515
passed_type = type(value)
@@ -561,15 +541,19 @@ def determine_key(value: Any):
561541
kwargs.pop(key, None)
562542

563543
# Place data_ and aria_ attributes into custom_attrs
564-
special_attributes = tuple(
544+
special_attributes = [
565545
key
566546
for key in kwargs
567547
if key not in fields and SpecialAttributes.is_special(key)
568-
)
548+
]
569549
if special_attributes:
570550
custom_attrs = kwargs.setdefault("custom_attrs", {})
571-
for key in special_attributes:
572-
custom_attrs[format.to_kebab_case(key)] = kwargs.pop(key)
551+
custom_attrs.update(
552+
{
553+
format.to_kebab_case(key): kwargs.pop(key)
554+
for key in special_attributes
555+
}
556+
)
573557

574558
# Add style props to the component.
575559
style = kwargs.get("style", {})
@@ -805,6 +789,18 @@ def _get_components_in_props(self) -> Sequence[BaseComponent]:
805789
for component in _components_from(value)
806790
]
807791

792+
@classmethod
793+
def _validate_children(cls, children: tuple | list):
794+
from reflex.utils.exceptions import ChildrenTypeError
795+
796+
for child in children:
797+
if isinstance(child, (tuple, list)):
798+
cls._validate_children(child)
799+
800+
# Make sure the child is a valid type.
801+
if isinstance(child, dict) or not isinstance(child, ComponentChildTypes):
802+
raise ChildrenTypeError(component=cls.__name__, child=child)
803+
808804
@classmethod
809805
def create(cls: type[T], *children, **props) -> T:
810806
"""Create the component.
@@ -819,24 +815,12 @@ def create(cls: type[T], *children, **props) -> T:
819815
# Import here to avoid circular imports.
820816
from reflex.components.base.bare import Bare
821817
from reflex.components.base.fragment import Fragment
822-
from reflex.utils.exceptions import ChildrenTypeError
823818

824819
# Filter out None props
825820
props = {key: value for key, value in props.items() if value is not None}
826821

827-
def validate_children(children: tuple | list):
828-
for child in children:
829-
if isinstance(child, (tuple, list)):
830-
validate_children(child)
831-
832-
# Make sure the child is a valid type.
833-
if isinstance(child, dict) or not isinstance(
834-
child, ComponentChildTypes
835-
):
836-
raise ChildrenTypeError(component=cls.__name__, child=child)
837-
838822
# Validate all the children.
839-
validate_children(children)
823+
cls._validate_children(children)
840824

841825
children_normalized = [
842826
(
@@ -2577,25 +2561,7 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) ->
25772561
else LiteralNoneVar.create(),
25782562
)
25792563

2580-
props = {}
2581-
2582-
special_props = []
2583-
2584-
for prop_str in tag["props"]:
2585-
if ":" not in prop_str:
2586-
special_props.append(Var(prop_str).to(ObjectVar))
2587-
continue
2588-
prop = prop_str.index(":")
2589-
key = prop_str[:prop]
2590-
value = prop_str[prop + 1 :]
2591-
props[key] = value
2592-
2593-
props = LiteralObjectVar.create(
2594-
{LiteralStringVar.create(k): Var(v) for k, v in props.items()}
2595-
)
2596-
2597-
for prop in special_props:
2598-
props = props.merge(prop)
2564+
props = Var("({" + ",".join(tag["props"]) + "})")
25992565

26002566
contents = tag["contents"] if tag["contents"] else None
26012567

reflex/constants/compiler.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,18 +171,19 @@ class MemoizationMode:
171171
recursive: bool = True
172172

173173

174+
DATA_UNDERSCORE = "data_"
175+
DATA_DASH = "data-"
176+
ARIA_UNDERSCORE = "aria_"
177+
ARIA_DASH = "aria-"
178+
179+
174180
class SpecialAttributes(enum.Enum):
175181
"""Special attributes for components.
176182
177183
These are placed in custom_attrs and rendered as-is rather than converting
178184
to a style prop.
179185
"""
180186

181-
DATA_UNDERSCORE = "data_"
182-
DATA_DASH = "data-"
183-
ARIA_UNDERSCORE = "aria_"
184-
ARIA_DASH = "aria-"
185-
186187
@classmethod
187188
def is_special(cls, attr: str) -> bool:
188189
"""Check if the attribute is special.
@@ -193,4 +194,9 @@ def is_special(cls, attr: str) -> bool:
193194
Returns:
194195
True if the attribute is special.
195196
"""
196-
return any(attr.startswith(value.value) for value in cls)
197+
return (
198+
attr.startswith(DATA_UNDERSCORE)
199+
or attr.startswith(DATA_DASH)
200+
or attr.startswith(ARIA_UNDERSCORE)
201+
or attr.startswith(ARIA_DASH)
202+
)

reflex/utils/format.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -436,19 +436,12 @@ def format_props(*single_props, **key_value_props) -> list[str]:
436436
The formatted props list.
437437
"""
438438
# Format all the props.
439-
from reflex.vars.base import LiteralVar, Var
439+
from reflex.vars import LiteralStringVar, LiteralVar, Var
440440

441441
return [
442-
":".join(
443-
[
444-
str(name if "-" not in name else LiteralVar.create(name)),
445-
str(
446-
format_prop(
447-
prop if isinstance(prop, Var) else LiteralVar.create(prop)
448-
)
449-
),
450-
]
451-
)
442+
(str(LiteralStringVar.create(name)) if "-" in name else name)
443+
+ ":"
444+
+ str(format_prop(prop if isinstance(prop, Var) else LiteralVar.create(prop)))
452445
for name, prop in sorted(key_value_props.items())
453446
if prop is not None
454447
] + [(f"...{LiteralVar.create(prop)!s}") for prop in single_props]

tests/units/components/test_component.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,10 +1221,10 @@ def test_stateful_banner():
12211221
assert isinstance(stateful_component, StatefulComponent)
12221222

12231223

1224-
TEST_VAR = LiteralVar.create("test")._replace(
1224+
TEST_VAR = LiteralVar.create("p")._replace(
12251225
merge_var_data=VarData(
12261226
hooks={"useTest": None},
1227-
imports={"test": [ImportVar(tag="test")]},
1227+
imports={"test": [ImportVar(tag="p")]},
12281228
state="Test",
12291229
)
12301230
)
@@ -1233,31 +1233,31 @@ def test_stateful_banner():
12331233
EVENT_CHAIN_VAR = TEST_VAR.to(EventChain)
12341234
ARG_VAR = Var(_js_expr="arg")
12351235

1236-
TEST_VAR_DICT_OF_DICT = LiteralVar.create({"a": {"b": "test"}})._replace(
1236+
TEST_VAR_DICT_OF_DICT = LiteralVar.create({"a": {"b": "p"}})._replace(
1237+
merge_var_data=TEST_VAR._var_data
1238+
)
1239+
FORMATTED_TEST_VAR_DICT_OF_DICT = LiteralVar.create({"a": {"b": "foopbar"}})._replace(
12371240
merge_var_data=TEST_VAR._var_data
12381241
)
1239-
FORMATTED_TEST_VAR_DICT_OF_DICT = LiteralVar.create(
1240-
{"a": {"b": "footestbar"}}
1241-
)._replace(merge_var_data=TEST_VAR._var_data)
12421242

1243-
TEST_VAR_LIST_OF_LIST = LiteralVar.create([["test"]])._replace(
1243+
TEST_VAR_LIST_OF_LIST = LiteralVar.create([["p"]])._replace(
12441244
merge_var_data=TEST_VAR._var_data
12451245
)
1246-
FORMATTED_TEST_VAR_LIST_OF_LIST = LiteralVar.create([["footestbar"]])._replace(
1246+
FORMATTED_TEST_VAR_LIST_OF_LIST = LiteralVar.create([["foopbar"]])._replace(
12471247
merge_var_data=TEST_VAR._var_data
12481248
)
12491249

1250-
TEST_VAR_LIST_OF_LIST_OF_LIST = LiteralVar.create([[["test"]]])._replace(
1250+
TEST_VAR_LIST_OF_LIST_OF_LIST = LiteralVar.create([[["p"]]])._replace(
1251+
merge_var_data=TEST_VAR._var_data
1252+
)
1253+
FORMATTED_TEST_VAR_LIST_OF_LIST_OF_LIST = LiteralVar.create([[["foopbar"]]])._replace(
12511254
merge_var_data=TEST_VAR._var_data
12521255
)
1253-
FORMATTED_TEST_VAR_LIST_OF_LIST_OF_LIST = LiteralVar.create(
1254-
[[["footestbar"]]]
1255-
)._replace(merge_var_data=TEST_VAR._var_data)
12561256

1257-
TEST_VAR_LIST_OF_DICT = LiteralVar.create([{"a": "test"}])._replace(
1257+
TEST_VAR_LIST_OF_DICT = LiteralVar.create([{"a": "p"}])._replace(
12581258
merge_var_data=TEST_VAR._var_data
12591259
)
1260-
FORMATTED_TEST_VAR_LIST_OF_DICT = LiteralVar.create([{"a": "footestbar"}])._replace(
1260+
FORMATTED_TEST_VAR_LIST_OF_DICT = LiteralVar.create([{"a": "foopbar"}])._replace(
12611261
merge_var_data=TEST_VAR._var_data
12621262
)
12631263

0 commit comments

Comments
 (0)