Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions reflex/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def _compile_page(component: BaseComponent) -> str:
# Compile the code to render the component.
return templates.page_template(
imports=imports,
dynamic_imports=component._get_all_dynamic_imports(),
dynamic_imports=sorted(component._get_all_dynamic_imports()),
custom_codes=component._get_all_custom_code(),
hooks=component._get_all_hooks(),
render=component.render(),
Expand Down Expand Up @@ -379,7 +379,7 @@ def _compile_components(
templates.custom_component_template(
imports=utils.compile_imports(imports),
components=component_renders,
dynamic_imports=dynamic_imports,
dynamic_imports=sorted(dynamic_imports),
custom_codes=custom_codes,
),
imports,
Expand Down Expand Up @@ -435,9 +435,7 @@ def get_shared_components_recursive(component: BaseComponent):
rendered_components.update(dict.fromkeys(dynamic_imports))

# Include custom code in the shared component.
rendered_components.update(
dict.fromkeys(component._get_all_custom_code(export=True)),
)
rendered_components.update(component._get_all_custom_code(export=True))

# Include all imports in the shared component.
all_import_dicts.append(component._get_all_imports())
Expand Down
2 changes: 1 addition & 1 deletion reflex/compiler/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def document_root_template(*, imports: list[_ImportDict], document: dict[str, An
def app_root_template(
*,
imports: list[_ImportDict],
custom_codes: set[str],
custom_codes: Iterable[str],
hooks: dict[str, VarData | None],
window_libraries: list[tuple[str, str]],
render: dict[str, Any],
Expand Down
4 changes: 2 additions & 2 deletions reflex/components/base/bare.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def _get_all_dynamic_imports(self) -> set[str]:
dynamic_imports |= component._get_all_dynamic_imports()
return dynamic_imports

def _get_all_custom_code(self) -> set[str]:
def _get_all_custom_code(self) -> dict[str, None]:
"""Get custom code for the component.

Returns:
Expand Down Expand Up @@ -166,7 +166,7 @@ def _get_all_app_wrap_components(
)
return app_wrap_components

def _get_all_refs(self) -> set[str]:
def _get_all_refs(self) -> dict[str, None]:
"""Get the refs for the children of the component.

Returns:
Expand Down
46 changes: 23 additions & 23 deletions reflex/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import inspect
import typing
from abc import ABC, ABCMeta, abstractmethod
from collections.abc import Callable, Iterator, Mapping, Sequence
from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
from dataclasses import _MISSING_TYPE, MISSING
from functools import wraps
from hashlib import md5
Expand Down Expand Up @@ -374,15 +374,15 @@ def _get_all_dynamic_imports(self) -> set[str]:
"""

@abstractmethod
def _get_all_custom_code(self) -> set[str]:
def _get_all_custom_code(self) -> dict[str, None]:
"""Get custom code for the component.

Returns:
The custom code.
"""

@abstractmethod
def _get_all_refs(self) -> set[str]:
def _get_all_refs(self) -> dict[str, None]:
"""Get the refs for the children of the component.

Returns:
Expand Down Expand Up @@ -1003,13 +1003,13 @@ def _render(self, props: dict[str, Any] | None = None) -> Tag:

@classmethod
@functools.cache
def get_props(cls) -> set[str]:
def get_props(cls) -> Iterable[str]:
"""Get the unique fields for the component.

Returns:
The unique fields.
"""
return set(cls.get_js_fields())
return cls.get_js_fields()

@classmethod
@functools.cache
Expand Down Expand Up @@ -1509,27 +1509,27 @@ def _get_custom_code(self) -> str | None:
"""
return None

def _get_all_custom_code(self) -> set[str]:
def _get_all_custom_code(self) -> dict[str, None]:
"""Get custom code for the component and its children.

Returns:
The custom code.
"""
# Store the code in a set to avoid duplicates.
code = set()
code: dict[str, None] = {}

# Add the custom code for this component.
custom_code = self._get_custom_code()
if custom_code is not None:
code.add(custom_code)
code[custom_code] = None

for component in self._get_components_in_props():
code |= component._get_all_custom_code()

# Add the custom code from add_custom_code method.
for clz in self._iter_parent_classes_with_method("add_custom_code"):
for item in clz.add_custom_code(self):
code.add(item)
code[item] = None

# Add the custom code for the children.
for child in self.children:
Expand Down Expand Up @@ -1814,7 +1814,7 @@ def _get_all_hooks_internal(self) -> dict[str, VarData | None]:

# Add the hook code for the children.
for child in self.children:
code = {**code, **child._get_all_hooks_internal()}
code.update(child._get_all_hooks_internal())

return code

Expand All @@ -1838,7 +1838,7 @@ def _get_all_hooks(self) -> dict[str, VarData | None]:

# Add the hook code for the children.
for child in self.children:
code = {**code, **child._get_all_hooks()}
code.update(child._get_all_hooks())

return code

Expand All @@ -1853,16 +1853,16 @@ def get_ref(self) -> str | None:
return None
return format.format_ref(self.id)

def _get_all_refs(self) -> set[str]:
def _get_all_refs(self) -> dict[str, None]:
"""Get the refs for the children of the component.

Returns:
The refs for the children.
"""
refs = set()
refs = {}
ref = self.get_ref()
if ref is not None:
refs.add(ref)
refs[ref] = None
for child in self.children:
refs |= child._get_all_refs()
for component in self._get_components_in_props():
Expand Down Expand Up @@ -1994,7 +1994,7 @@ def get_args_spec(key: str) -> types.ArgsSpec | Sequence[types.ArgsSpec]:
)

to_camel_cased_props = {
format.to_camel_case(key + MEMO_MARKER)
format.to_camel_case(key + MEMO_MARKER): None
for key in props
if key not in event_types
}
Expand Down Expand Up @@ -2048,13 +2048,13 @@ def __hash__(self) -> int:
return hash(self.tag)

@classmethod
def get_props(cls) -> set[str]:
def get_props(cls) -> Iterable[str]:
"""Get the props for the component.

Returns:
The set of component props.
"""
return set()
return ()

@staticmethod
def _get_event_spec_from_args_spec(name: str, event: EventChain) -> Callable:
Expand Down Expand Up @@ -2656,7 +2656,7 @@ def _get_all_dynamic_imports(self) -> set[str]:
return set()
return self.component._get_all_dynamic_imports()

def _get_all_custom_code(self, export: bool = False) -> set[str]:
def _get_all_custom_code(self, export: bool = False) -> dict[str, None]:
"""Get custom code for the component.

Args:
Expand All @@ -2666,19 +2666,19 @@ def _get_all_custom_code(self, export: bool = False) -> set[str]:
The custom code.
"""
if self.rendered_as_shared:
return set()
return self.component._get_all_custom_code().union(
{self._render_stateful_code(export=export)}
return {}
return self.component._get_all_custom_code() | (
{self._render_stateful_code(export=export): None}
)

def _get_all_refs(self) -> set[str]:
def _get_all_refs(self) -> dict[str, None]:
"""Get the refs for the children of the component.

Returns:
The refs for the children.
"""
if self.rendered_as_shared:
return set()
return {}
return self.component._get_all_refs()

def render(self) -> dict:
Expand Down
2 changes: 1 addition & 1 deletion reflex/components/core/debounce.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def create(cls, *children: Component, **props: Any) -> Component:
component.children = child.children
component._rename_props = child._rename_props # pyright: ignore[reportAttributeAccessIssue]
outer_get_all_custom_code = component._get_all_custom_code
component._get_all_custom_code = lambda: outer_get_all_custom_code().union(
component._get_all_custom_code = lambda: outer_get_all_custom_code() | (
child._get_all_custom_code()
)
return component
Expand Down
26 changes: 7 additions & 19 deletions reflex/components/core/foreach.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import functools
import inspect
from collections.abc import Callable, Iterable
from hashlib import md5
from typing import Any

from reflex.components.base.fragment import Fragment
Expand Down Expand Up @@ -141,25 +142,12 @@ def _render(self) -> IterTag:
else:
render_fn = self.render_fn
# Otherwise, use a deterministic index, based on the render function bytecode.
code_hash = (
hash(
getattr(
render_fn,
"__code__",
(
repr(self.render_fn)
if not isinstance(render_fn, functools.partial)
else render_fn.func.__code__
),
)
)
.to_bytes(
length=8,
byteorder="big",
signed=True,
)
.hex()
)
if (render_fn_code := getattr(render_fn, "__code__", None)) is not None:
code_hash = md5(render_fn_code.co_code).hexdigest()
elif isinstance(render_fn, functools.partial):
code_hash = md5(render_fn.func.__code__.co_code).hexdigest()
else:
code_hash = md5(repr(render_fn).encode()).hexdigest()
props["index_var_name"] = f"index_{code_hash}"

return IterTag(
Expand Down
2 changes: 1 addition & 1 deletion reflex/components/core/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ def create(cls, *children, **props) -> Component:
props["class_name"] = ["rx-Upload", *given_class_name]

# get only upload component props
supported_props = cls.get_props().union({"on_drop"})
supported_props = set(cls.get_props()) | {"on_drop"}
upload_props = {
key: value for key, value in props.items() if key in supported_props
}
Expand Down
4 changes: 1 addition & 3 deletions reflex/components/dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ def make_component(component: Component) -> str:
rendered_components.update(dict.fromkeys(dynamic_imports))

# Include custom code in the shared component.
rendered_components.update(
dict.fromkeys(component._get_all_custom_code()),
)
rendered_components.update(component._get_all_custom_code())

rendered_components[
templates.stateful_component_template(
Expand Down
6 changes: 3 additions & 3 deletions reflex/components/el/elements/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -770,17 +770,17 @@ def _exclude_props(self) -> list[str]:
"enter_key_submit",
]

def _get_all_custom_code(self) -> set[str]:
def _get_all_custom_code(self) -> dict[str, None]:
"""Include the custom code for auto_height and enter_key_submit functionality.

Returns:
The custom code for the component.
"""
custom_code = super()._get_all_custom_code()
if self.auto_height is not None:
custom_code.add(AUTO_HEIGHT_JS)
custom_code[AUTO_HEIGHT_JS] = None
if self.enter_key_submit is not None:
custom_code.add(ENTER_KEY_SUBMIT_JS)
custom_code[ENTER_KEY_SUBMIT_JS] = None
return custom_code


Expand Down
11 changes: 9 additions & 2 deletions reflex/vars/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import functools
import inspect
import json
import random
import re
import string
import uuid
Expand Down Expand Up @@ -50,6 +49,7 @@
from reflex.constants.compiler import Hooks
from reflex.constants.state import FIELD_MARKER
from reflex.utils import console, exceptions, imports, serializers, types
from reflex.utils.decorator import once
from reflex.utils.exceptions import (
ComputedVarSignatureError,
UntypedComputedVarError,
Expand Down Expand Up @@ -3033,13 +3033,20 @@ def get_uuid_string_var() -> Var:
USED_VARIABLES = set()


@once
def _rng():
import random

return random.Random(42)


def get_unique_variable_name() -> str:
"""Get a unique variable name.

Returns:
The unique variable name.
"""
name = "".join([random.choice(string.ascii_lowercase) for _ in range(8)])
name = "".join([_rng().choice(string.ascii_lowercase) for _ in range(8)])
if name not in USED_VARIABLES:
USED_VARIABLES.add(name)
return name
Expand Down
Loading
Loading