get reflex-web to compile
This commit is contained in:
parent
81cd679802
commit
ea33c3987a
@ -324,7 +324,8 @@ _MAPPING: dict = {
|
|||||||
"style": ["Style", "toggle_color_mode"],
|
"style": ["Style", "toggle_color_mode"],
|
||||||
"utils.imports": ["ImportVar"],
|
"utils.imports": ["ImportVar"],
|
||||||
"utils.serializers": ["serializer"],
|
"utils.serializers": ["serializer"],
|
||||||
"vars": ["cached_var", "Var"],
|
"vars": ["Var"],
|
||||||
|
"ivars.base": ["cached_var"],
|
||||||
}
|
}
|
||||||
|
|
||||||
_SUBMODULES: set[str] = {
|
_SUBMODULES: set[str] = {
|
||||||
|
@ -175,6 +175,7 @@ from .event import stop_propagation as stop_propagation
|
|||||||
from .event import upload_files as upload_files
|
from .event import upload_files as upload_files
|
||||||
from .event import window_alert as window_alert
|
from .event import window_alert as window_alert
|
||||||
from .experimental import _x as _x
|
from .experimental import _x as _x
|
||||||
|
from .ivars.base import cached_var as cached_var
|
||||||
from .middleware import Middleware as Middleware
|
from .middleware import Middleware as Middleware
|
||||||
from .middleware import middleware as middleware
|
from .middleware import middleware as middleware
|
||||||
from .model import Model as Model
|
from .model import Model as Model
|
||||||
@ -191,7 +192,6 @@ from .style import toggle_color_mode as toggle_color_mode
|
|||||||
from .utils.imports import ImportVar as ImportVar
|
from .utils.imports import ImportVar as ImportVar
|
||||||
from .utils.serializers import serializer as serializer
|
from .utils.serializers import serializer as serializer
|
||||||
from .vars import Var as Var
|
from .vars import Var as Var
|
||||||
from .vars import cached_var as cached_var
|
|
||||||
|
|
||||||
del compat
|
del compat
|
||||||
RADIX_THEMES_MAPPING: dict
|
RADIX_THEMES_MAPPING: dict
|
||||||
|
@ -442,7 +442,11 @@ class App(MiddlewareMixin, LifespanMixin, Base):
|
|||||||
raise
|
raise
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
message = str(e)
|
message = str(e)
|
||||||
if "BaseVar" in message or "ComputedVar" in message:
|
if (
|
||||||
|
"BaseVar" in message
|
||||||
|
or "ComputedVar" in message
|
||||||
|
or "ImmutableComputedVar" in message
|
||||||
|
):
|
||||||
raise VarOperationTypeError(
|
raise VarOperationTypeError(
|
||||||
"You may be trying to use an invalid Python function on a state var. "
|
"You may be trying to use an invalid Python function on a state var. "
|
||||||
"When referencing a var inside your render code, only limited var operations are supported. "
|
"When referencing a var inside your render code, only limited var operations are supported. "
|
||||||
|
@ -28,7 +28,7 @@ class Bare(Component):
|
|||||||
"""
|
"""
|
||||||
if isinstance(contents, ImmutableVar):
|
if isinstance(contents, ImmutableVar):
|
||||||
return cls(contents=contents)
|
return cls(contents=contents)
|
||||||
if isinstance(contents, Var) and contents._var_data:
|
if isinstance(contents, Var) and contents._get_all_var_data():
|
||||||
contents = contents.to(str)
|
contents = contents.to(str)
|
||||||
else:
|
else:
|
||||||
contents = str(contents) if contents is not None else ""
|
contents = str(contents) if contents is not None else ""
|
||||||
|
@ -1121,7 +1121,8 @@ class Component(BaseComponent, ABC):
|
|||||||
for child in self.children:
|
for child in self.children:
|
||||||
if not isinstance(child, Component):
|
if not isinstance(child, Component):
|
||||||
continue
|
continue
|
||||||
vars.extend(child._get_vars(include_children=include_children))
|
child_vars = child._get_vars(include_children=include_children)
|
||||||
|
vars.extend(child_vars)
|
||||||
|
|
||||||
return vars
|
return vars
|
||||||
|
|
||||||
@ -1326,13 +1327,13 @@ class Component(BaseComponent, ABC):
|
|||||||
|
|
||||||
other_imports = []
|
other_imports = []
|
||||||
user_hooks = self._get_hooks()
|
user_hooks = self._get_hooks()
|
||||||
if (
|
user_hooks_data = (
|
||||||
user_hooks is not None
|
VarData.merge(user_hooks._get_all_var_data())
|
||||||
and isinstance(user_hooks, Var)
|
if user_hooks is not None and isinstance(user_hooks, Var)
|
||||||
and user_hooks._var_data is not None
|
else None
|
||||||
and user_hooks._var_data.imports
|
)
|
||||||
):
|
if user_hooks_data is not None:
|
||||||
other_imports.append(user_hooks._var_data.imports)
|
other_imports.append(user_hooks_data.imports)
|
||||||
other_imports.extend(
|
other_imports.extend(
|
||||||
hook_imports for hook_imports in self._get_added_hooks().values()
|
hook_imports for hook_imports in self._get_added_hooks().values()
|
||||||
)
|
)
|
||||||
@ -1830,9 +1831,11 @@ class CustomComponent(Component):
|
|||||||
Returns:
|
Returns:
|
||||||
Each var referenced by the component (props, styles, event handlers).
|
Each var referenced by the component (props, styles, event handlers).
|
||||||
"""
|
"""
|
||||||
return super()._get_vars(include_children=include_children) + [
|
return (
|
||||||
prop for prop in self.props.values() if isinstance(prop, Var)
|
super()._get_vars(include_children=include_children)
|
||||||
]
|
+ [prop for prop in self.props.values() if isinstance(prop, Var)]
|
||||||
|
+ self.get_component(self)._get_vars(include_children=include_children)
|
||||||
|
)
|
||||||
|
|
||||||
@lru_cache(maxsize=None) # noqa
|
@lru_cache(maxsize=None) # noqa
|
||||||
def get_component(self) -> Component:
|
def get_component(self) -> Component:
|
||||||
|
@ -153,7 +153,7 @@ class ConnectionToaster(Toaster):
|
|||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
),
|
),
|
||||||
LiteralArrayVar([connect_errors]),
|
LiteralArrayVar.create([connect_errors]),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class WebsocketTargetURL(Bare):
|
|||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
contents: Optional[Union[Var[str], str]] = None,
|
contents: Optional[Union[Var[Any], Any]] = None,
|
||||||
style: Optional[Style] = None,
|
style: Optional[Style] = None,
|
||||||
key: Optional[Any] = None,
|
key: Optional[Any] = None,
|
||||||
id: Optional[Any] = None,
|
id: Optional[Any] = None,
|
||||||
|
@ -104,7 +104,7 @@ class Cond(MemoizationLeaf):
|
|||||||
The import dict for the component.
|
The import dict for the component.
|
||||||
"""
|
"""
|
||||||
cond_imports: dict[str, str | ImportVar | list[str | ImportVar]] = getattr(
|
cond_imports: dict[str, str | ImportVar | list[str | ImportVar]] = getattr(
|
||||||
self.cond._var_data, "imports", {}
|
VarData.merge(self.cond._get_all_var_data()), "imports", {}
|
||||||
)
|
)
|
||||||
return {**cond_imports, **_IS_TRUE_IMPORT}
|
return {**cond_imports, **_IS_TRUE_IMPORT}
|
||||||
|
|
||||||
@ -135,6 +135,8 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | ImmutableVar:
|
|||||||
Raises:
|
Raises:
|
||||||
ValueError: If the arguments are invalid.
|
ValueError: If the arguments are invalid.
|
||||||
"""
|
"""
|
||||||
|
if isinstance(condition, Var) and not isinstance(condition, ImmutableVar):
|
||||||
|
condition._var_is_local = True
|
||||||
# Convert the condition to a Var.
|
# Convert the condition to a Var.
|
||||||
cond_var = LiteralVar.create(condition)
|
cond_var = LiteralVar.create(condition)
|
||||||
assert cond_var is not None, "The condition must be set."
|
assert cond_var is not None, "The condition must be set."
|
||||||
@ -161,8 +163,8 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | ImmutableVar:
|
|||||||
c2 = create_var(c2)
|
c2 = create_var(c2)
|
||||||
|
|
||||||
# Create the conditional var.
|
# Create the conditional var.
|
||||||
return TernaryOperator(
|
return TernaryOperator.create(
|
||||||
condition=cond_var,
|
condition=cond_var.to(bool),
|
||||||
if_true=c1,
|
if_true=c1,
|
||||||
if_false=c2,
|
if_false=c2,
|
||||||
_var_data=VarData(imports=_IS_TRUE_IMPORT),
|
_var_data=VarData(imports=_IS_TRUE_IMPORT),
|
||||||
|
@ -11,7 +11,7 @@ from reflex.style import Style
|
|||||||
from reflex.utils import format, types
|
from reflex.utils import format, types
|
||||||
from reflex.utils.exceptions import MatchTypeError
|
from reflex.utils.exceptions import MatchTypeError
|
||||||
from reflex.utils.imports import ImportDict
|
from reflex.utils.imports import ImportDict
|
||||||
from reflex.vars import ImmutableVarData, Var
|
from reflex.vars import ImmutableVarData, Var, VarData
|
||||||
|
|
||||||
|
|
||||||
class Match(MemoizationLeaf):
|
class Match(MemoizationLeaf):
|
||||||
@ -264,7 +264,7 @@ class Match(MemoizationLeaf):
|
|||||||
Returns:
|
Returns:
|
||||||
The import dict.
|
The import dict.
|
||||||
"""
|
"""
|
||||||
return getattr(self.cond._var_data, "imports", {})
|
return getattr(VarData.merge(self.cond._get_all_var_data()), "imports", {})
|
||||||
|
|
||||||
|
|
||||||
match = Match.create
|
match = Match.create
|
||||||
|
@ -22,7 +22,7 @@ from reflex.event import (
|
|||||||
from reflex.ivars.base import ImmutableCallableVar, ImmutableVar
|
from reflex.ivars.base import ImmutableCallableVar, ImmutableVar
|
||||||
from reflex.ivars.sequence import LiteralStringVar
|
from reflex.ivars.sequence import LiteralStringVar
|
||||||
from reflex.utils.imports import ImportVar
|
from reflex.utils.imports import ImportVar
|
||||||
from reflex.vars import Var, VarData
|
from reflex.vars import ImmutableVarData, Var, VarData
|
||||||
|
|
||||||
DEFAULT_UPLOAD_ID: str = "default"
|
DEFAULT_UPLOAD_ID: str = "default"
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> ImmutableVar:
|
|||||||
return ImmutableVar(
|
return ImmutableVar(
|
||||||
_var_name=var_name,
|
_var_name=var_name,
|
||||||
_var_type=EventChain,
|
_var_type=EventChain,
|
||||||
_var_data=VarData.merge(
|
_var_data=ImmutableVarData.merge(
|
||||||
upload_files_context_var_data, id_var._get_all_var_data()
|
upload_files_context_var_data, id_var._get_all_var_data()
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -81,7 +81,7 @@ def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> ImmutableVar:
|
|||||||
return ImmutableVar(
|
return ImmutableVar(
|
||||||
_var_name=f"(filesById[{str(id_var)}] ? filesById[{str(id_var)}].map((f) => (f.path || f.name)) : [])",
|
_var_name=f"(filesById[{str(id_var)}] ? filesById[{str(id_var)}].map((f) => (f.path || f.name)) : [])",
|
||||||
_var_type=List[str],
|
_var_type=List[str],
|
||||||
_var_data=VarData.merge(
|
_var_data=ImmutableVarData.merge(
|
||||||
upload_files_context_var_data, id_var._get_all_var_data()
|
upload_files_context_var_data, id_var._get_all_var_data()
|
||||||
),
|
),
|
||||||
).guess_type()
|
).guess_type()
|
||||||
|
@ -12,16 +12,17 @@ from reflex.event import (
|
|||||||
EventHandler,
|
EventHandler,
|
||||||
EventSpec,
|
EventSpec,
|
||||||
)
|
)
|
||||||
|
from reflex.ivars.base import ImmutableCallableVar, ImmutableVar
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.vars import BaseVar, CallableVar, Var, VarData
|
from reflex.vars import BaseVar, Var, VarData
|
||||||
|
|
||||||
DEFAULT_UPLOAD_ID: str
|
DEFAULT_UPLOAD_ID: str
|
||||||
upload_files_context_var_data: VarData
|
upload_files_context_var_data: VarData
|
||||||
|
|
||||||
@CallableVar
|
@ImmutableCallableVar
|
||||||
def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> BaseVar: ...
|
def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> ImmutableVar: ...
|
||||||
@CallableVar
|
@ImmutableCallableVar
|
||||||
def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> BaseVar: ...
|
def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> ImmutableVar: ...
|
||||||
@CallableEventSpec
|
@CallableEventSpec
|
||||||
def clear_selected_files(id_: str = DEFAULT_UPLOAD_ID) -> EventSpec: ...
|
def clear_selected_files(id_: str = DEFAULT_UPLOAD_ID) -> EventSpec: ...
|
||||||
def cancel_upload(upload_id: str) -> EventSpec: ...
|
def cancel_upload(upload_id: str) -> EventSpec: ...
|
||||||
|
@ -390,7 +390,7 @@ class CodeBlock(Component):
|
|||||||
The import dict.
|
The import dict.
|
||||||
"""
|
"""
|
||||||
imports_: ImportDict = {}
|
imports_: ImportDict = {}
|
||||||
themes = re.findall(r"`(.*?)`", self.theme._var_name)
|
themes = re.findall(r'"(.*?)"', self.theme._var_name)
|
||||||
if not themes:
|
if not themes:
|
||||||
themes = [self.theme._var_name]
|
themes = [self.theme._var_name]
|
||||||
|
|
||||||
@ -509,11 +509,8 @@ class CodeBlock(Component):
|
|||||||
style=ImmutableVar.create(
|
style=ImmutableVar.create(
|
||||||
format.to_camel_case(f"{predicate}{qmark}{value.replace('`', '')}"),
|
format.to_camel_case(f"{predicate}{qmark}{value.replace('`', '')}"),
|
||||||
)
|
)
|
||||||
).remove_props("theme", "code")
|
).remove_props("theme", "code").add_props(children=self.code)
|
||||||
if self.code is not None:
|
|
||||||
out.special_props.add(
|
|
||||||
Var.create_safe(f"children={str(self.code)}", _var_is_string=False)
|
|
||||||
)
|
|
||||||
return out
|
return out
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -14,7 +14,7 @@ from reflex.event import EventChain, EventHandler
|
|||||||
from reflex.ivars.base import ImmutableVar
|
from reflex.ivars.base import ImmutableVar
|
||||||
from reflex.utils.format import format_event_chain
|
from reflex.utils.format import format_event_chain
|
||||||
from reflex.utils.imports import ImportDict
|
from reflex.utils.imports import ImportDict
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var, VarData
|
||||||
|
|
||||||
from .base import BaseHTML
|
from .base import BaseHTML
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ class Form(BaseHTML):
|
|||||||
f"getRefValues({str(ref_var)})",
|
f"getRefValues({str(ref_var)})",
|
||||||
_var_is_local=False,
|
_var_is_local=False,
|
||||||
_var_is_string=False,
|
_var_is_string=False,
|
||||||
_var_data=ref_var._var_data,
|
_var_data=VarData.merge(ref_var._get_all_var_data()),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
ref_var = Var.create_safe(ref, _var_is_string=False).as_ref()
|
ref_var = Var.create_safe(ref, _var_is_string=False).as_ref()
|
||||||
@ -226,7 +226,7 @@ class Form(BaseHTML):
|
|||||||
f"getRefValue({str(ref_var)})",
|
f"getRefValue({str(ref_var)})",
|
||||||
_var_is_local=False,
|
_var_is_local=False,
|
||||||
_var_is_string=False,
|
_var_is_string=False,
|
||||||
_var_data=ref_var._var_data,
|
_var_data=VarData.merge(ref_var._get_all_var_data()),
|
||||||
)
|
)
|
||||||
return form_refs
|
return form_refs
|
||||||
|
|
||||||
@ -632,7 +632,7 @@ class Textarea(BaseHTML):
|
|||||||
f"(e) => enterKeySubmitOnKeyDown(e, {self.enter_key_submit._var_name_unwrapped})",
|
f"(e) => enterKeySubmitOnKeyDown(e, {self.enter_key_submit._var_name_unwrapped})",
|
||||||
_var_is_local=False,
|
_var_is_local=False,
|
||||||
_var_is_string=False,
|
_var_is_string=False,
|
||||||
_var_data=self.enter_key_submit._var_data,
|
_var_data=VarData.merge(self.enter_key_submit._get_all_var_data()),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if self.auto_height is not None:
|
if self.auto_height is not None:
|
||||||
@ -641,7 +641,7 @@ class Textarea(BaseHTML):
|
|||||||
f"(e) => autoHeightOnInput(e, {self.auto_height._var_name_unwrapped})",
|
f"(e) => autoHeightOnInput(e, {self.auto_height._var_name_unwrapped})",
|
||||||
_var_is_local=False,
|
_var_is_local=False,
|
||||||
_var_is_string=False,
|
_var_is_string=False,
|
||||||
_var_data=self.auto_height._var_data,
|
_var_data=VarData.merge(self.auto_height._get_all_var_data()),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return tag
|
return tag
|
||||||
|
@ -9,13 +9,14 @@ from jinja2 import Environment
|
|||||||
|
|
||||||
from reflex.components.el.element import Element
|
from reflex.components.el.element import Element
|
||||||
from reflex.event import EventHandler, EventSpec
|
from reflex.event import EventHandler, EventSpec
|
||||||
|
from reflex.ivars.base import ImmutableVar
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.utils.imports import ImportDict
|
from reflex.utils.imports import ImportDict
|
||||||
from reflex.vars import BaseVar, Var
|
from reflex.vars import BaseVar, Var
|
||||||
|
|
||||||
from .base import BaseHTML
|
from .base import BaseHTML
|
||||||
|
|
||||||
FORM_DATA = Var.create("form_data", _var_is_string=False)
|
FORM_DATA = ImmutableVar.create("form_data")
|
||||||
HANDLE_SUBMIT_JS_JINJA2 = Environment().from_string(
|
HANDLE_SUBMIT_JS_JINJA2 = Environment().from_string(
|
||||||
"\n const handleSubmit_{{ handle_submit_unique_name }} = useCallback((ev) => {\n const $form = ev.target\n ev.preventDefault()\n const {{ form_data }} = {...Object.fromEntries(new FormData($form).entries()), ...{{ field_ref_mapping }}}\n\n {{ on_submit_event_chain }}\n\n if ({{ reset_on_submit }}) {\n $form.reset()\n }\n })\n "
|
"\n const handleSubmit_{{ handle_submit_unique_name }} = useCallback((ev) => {\n const $form = ev.target\n ev.preventDefault()\n const {{ form_data }} = {...Object.fromEntries(new FormData($form).entries()), ...{{ field_ref_mapping }}}\n\n {{ on_submit_event_chain }}\n\n if ({{ reset_on_submit }}) {\n $form.reset()\n }\n })\n "
|
||||||
)
|
)
|
||||||
|
@ -29,24 +29,49 @@ class Link(BaseHTML): # noqa: E742
|
|||||||
|
|
||||||
tag = "link"
|
tag = "link"
|
||||||
|
|
||||||
|
# Specifies the CORS settings for the linked resource
|
||||||
cross_origin: Var[Union[str, int, bool]]
|
cross_origin: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
# Specifies the URL of the linked document/resource
|
||||||
href: Var[Union[str, int, bool]]
|
href: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
# Specifies the language of the text in the linked document
|
||||||
href_lang: Var[Union[str, int, bool]]
|
href_lang: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
# Allows a browser to check the fetched link for integrity
|
||||||
integrity: Var[Union[str, int, bool]]
|
integrity: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
# Specifies on what device the linked document will be displayed
|
||||||
media: Var[Union[str, int, bool]]
|
media: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
# Specifies the referrer policy of the linked document
|
||||||
referrer_policy: Var[Union[str, int, bool]]
|
referrer_policy: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
# Specifies the relationship between the current document and the linked one
|
||||||
rel: Var[Union[str, int, bool]]
|
rel: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
# Specifies the sizes of icons for visual media
|
||||||
sizes: Var[Union[str, int, bool]]
|
sizes: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
# Specifies the MIME type of the linked document
|
||||||
type: Var[Union[str, int, bool]]
|
type: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
|
||||||
class Meta(BaseHTML): # Inherits common attributes from BaseHTML
|
class Meta(BaseHTML): # Inherits common attributes from BaseHTML
|
||||||
"""Display the meta element."""
|
"""Display the meta element."""
|
||||||
|
|
||||||
tag = "meta"
|
tag = "meta" # The HTML tag for this element is <meta>
|
||||||
|
|
||||||
|
# Specifies the character encoding for the HTML document
|
||||||
char_set: Var[Union[str, int, bool]]
|
char_set: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
# Defines the content of the metadata
|
||||||
content: Var[Union[str, int, bool]]
|
content: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
# Provides an HTTP header for the information/value of the content attribute
|
||||||
http_equiv: Var[Union[str, int, bool]]
|
http_equiv: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
# Specifies a name for the metadata
|
||||||
name: Var[Union[str, int, bool]]
|
name: Var[Union[str, int, bool]]
|
||||||
|
|
||||||
|
|
||||||
|
@ -346,6 +346,15 @@ class Link(BaseHTML):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
*children: The children of the component.
|
*children: The children of the component.
|
||||||
|
cross_origin: Specifies the CORS settings for the linked resource
|
||||||
|
href: Specifies the URL of the linked document/resource
|
||||||
|
href_lang: Specifies the language of the text in the linked document
|
||||||
|
integrity: Allows a browser to check the fetched link for integrity
|
||||||
|
media: Specifies on what device the linked document will be displayed
|
||||||
|
referrer_policy: Specifies the referrer policy of the linked document
|
||||||
|
rel: Specifies the relationship between the current document and the linked one
|
||||||
|
sizes: Specifies the sizes of icons for visual media
|
||||||
|
type: Specifies the MIME type of the linked document
|
||||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||||
content_editable: Indicates whether the element's content is editable.
|
content_editable: Indicates whether the element's content is editable.
|
||||||
@ -466,6 +475,10 @@ class Meta(BaseHTML):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
*children: The children of the component.
|
*children: The children of the component.
|
||||||
|
char_set: Specifies the character encoding for the HTML document
|
||||||
|
content: Defines the content of the metadata
|
||||||
|
http_equiv: Provides an HTTP header for the information/value of the content attribute
|
||||||
|
name: Specifies a name for the metadata
|
||||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||||
content_editable: Indicates whether the element's content is editable.
|
content_editable: Indicates whether the element's content is editable.
|
||||||
|
@ -6,6 +6,7 @@ from typing import Any, Dict, List, Union
|
|||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.components.tags import Tag
|
from reflex.components.tags import Tag
|
||||||
|
from reflex.ivars.base import ImmutableComputedVar
|
||||||
from reflex.utils import types
|
from reflex.utils import types
|
||||||
from reflex.utils.imports import ImportDict
|
from reflex.utils.imports import ImportDict
|
||||||
from reflex.utils.serializers import serialize
|
from reflex.utils.serializers import serialize
|
||||||
@ -65,14 +66,17 @@ class DataTable(Gridjs):
|
|||||||
|
|
||||||
# The annotation should be provided if data is a computed var. We need this to know how to
|
# The annotation should be provided if data is a computed var. We need this to know how to
|
||||||
# render pandas dataframes.
|
# render pandas dataframes.
|
||||||
if isinstance(data, ComputedVar) and data._var_type == Any:
|
if (
|
||||||
|
isinstance(data, (ComputedVar, ImmutableComputedVar))
|
||||||
|
and data._var_type == Any
|
||||||
|
):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Annotation of the computed var assigned to the data field should be provided."
|
"Annotation of the computed var assigned to the data field should be provided."
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
columns is not None
|
columns is not None
|
||||||
and isinstance(columns, ComputedVar)
|
and isinstance(columns, (ComputedVar, ImmutableComputedVar))
|
||||||
and columns._var_type == Any
|
and columns._var_type == Any
|
||||||
):
|
):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
|
@ -17,30 +17,26 @@ from reflex.components.radix.themes.typography.heading import Heading
|
|||||||
from reflex.components.radix.themes.typography.link import Link
|
from reflex.components.radix.themes.typography.link import Link
|
||||||
from reflex.components.radix.themes.typography.text import Text
|
from reflex.components.radix.themes.typography.text import Text
|
||||||
from reflex.components.tags.tag import Tag
|
from reflex.components.tags.tag import Tag
|
||||||
from reflex.ivars.base import LiteralVar
|
from reflex.ivars.base import ImmutableVar, LiteralVar
|
||||||
from reflex.utils import types
|
from reflex.utils import types
|
||||||
from reflex.utils.imports import ImportDict, ImportVar
|
from reflex.utils.imports import ImportDict, ImportVar
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
# Special vars used in the component map.
|
# Special vars used in the component map.
|
||||||
_CHILDREN = Var.create_safe("children", _var_is_local=False, _var_is_string=False)
|
_CHILDREN = ImmutableVar.create_safe("children")
|
||||||
_PROPS = Var.create_safe("...props", _var_is_local=False, _var_is_string=False)
|
_PROPS = ImmutableVar.create_safe("...props")
|
||||||
_MOCK_ARG = Var.create_safe("", _var_is_string=False)
|
_MOCK_ARG = ImmutableVar.create_safe("")
|
||||||
|
|
||||||
# Special remark plugins.
|
# Special remark plugins.
|
||||||
_REMARK_MATH = Var.create_safe("remarkMath", _var_is_local=False, _var_is_string=False)
|
_REMARK_MATH = ImmutableVar.create_safe("remarkMath")
|
||||||
_REMARK_GFM = Var.create_safe("remarkGfm", _var_is_local=False, _var_is_string=False)
|
_REMARK_GFM = ImmutableVar.create_safe("remarkGfm")
|
||||||
_REMARK_UNWRAP_IMAGES = Var.create_safe(
|
_REMARK_UNWRAP_IMAGES = ImmutableVar.create_safe("remarkUnwrapImages")
|
||||||
"remarkUnwrapImages", _var_is_local=False, _var_is_string=False
|
_REMARK_PLUGINS = LiteralVar.create([_REMARK_MATH, _REMARK_GFM, _REMARK_UNWRAP_IMAGES])
|
||||||
)
|
|
||||||
_REMARK_PLUGINS = Var.create_safe([_REMARK_MATH, _REMARK_GFM, _REMARK_UNWRAP_IMAGES])
|
|
||||||
|
|
||||||
# Special rehype plugins.
|
# Special rehype plugins.
|
||||||
_REHYPE_KATEX = Var.create_safe(
|
_REHYPE_KATEX = ImmutableVar.create_safe("rehypeKatex")
|
||||||
"rehypeKatex", _var_is_local=False, _var_is_string=False
|
_REHYPE_RAW = ImmutableVar.create_safe("rehypeRaw")
|
||||||
)
|
_REHYPE_PLUGINS = LiteralVar.create([_REHYPE_KATEX, _REHYPE_RAW])
|
||||||
_REHYPE_RAW = Var.create_safe("rehypeRaw", _var_is_local=False, _var_is_string=False)
|
|
||||||
_REHYPE_PLUGINS = Var.create_safe([_REHYPE_KATEX, _REHYPE_RAW])
|
|
||||||
|
|
||||||
# These tags do NOT get props passed to them
|
# These tags do NOT get props passed to them
|
||||||
NO_PROPS_TAGS = ("ul", "ol", "li")
|
NO_PROPS_TAGS = ("ul", "ol", "li")
|
||||||
@ -209,10 +205,11 @@ class Markdown(Component):
|
|||||||
children_prop = props.pop("children", None)
|
children_prop = props.pop("children", None)
|
||||||
if children_prop is not None:
|
if children_prop is not None:
|
||||||
special_props.add(
|
special_props.add(
|
||||||
Var.create_safe(f"children={str(children_prop)}", _var_is_string=False)
|
Var.create_safe(
|
||||||
|
f"children={{{str(children_prop)}}}", _var_is_string=False
|
||||||
|
)
|
||||||
)
|
)
|
||||||
children = []
|
children = []
|
||||||
|
|
||||||
# Get the component.
|
# Get the component.
|
||||||
component = self.component_map[tag](*children, **props).set(
|
component = self.component_map[tag](*children, **props).set(
|
||||||
special_props=special_props
|
special_props=special_props
|
||||||
@ -238,7 +235,7 @@ class Markdown(Component):
|
|||||||
The formatted component map.
|
The formatted component map.
|
||||||
"""
|
"""
|
||||||
components = {
|
components = {
|
||||||
tag: f"{{({{node, {_CHILDREN._var_name}, {_PROPS._var_name}}}) => {self.format_component(tag)}}}"
|
tag: f"{{({{node, {_CHILDREN._var_name}, {_PROPS._var_name}}}) => ({self.format_component(tag)})}}"
|
||||||
for tag in self.component_map
|
for tag in self.component_map
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +258,7 @@ class Markdown(Component):
|
|||||||
return inline ? (
|
return inline ? (
|
||||||
{self.format_component("code")}
|
{self.format_component("code")}
|
||||||
) : (
|
) : (
|
||||||
{self.format_component("codeblock", language=Var.create_safe("language", _var_is_local=False, _var_is_string=False))}
|
{self.format_component("codeblock", language=ImmutableVar.create_safe("language"))}
|
||||||
);
|
);
|
||||||
}}}}""".replace("\n", " ")
|
}}}}""".replace("\n", " ")
|
||||||
|
|
||||||
@ -288,7 +285,7 @@ class Markdown(Component):
|
|||||||
function {self._get_component_map_name()} () {{
|
function {self._get_component_map_name()} () {{
|
||||||
{formatted_hooks}
|
{formatted_hooks}
|
||||||
return (
|
return (
|
||||||
{str(LiteralVar.create(self.format_component_map()))}
|
{str(ImmutableVar.create_safe(self.format_component_map()))}
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
@ -300,14 +297,10 @@ class Markdown(Component):
|
|||||||
.add_props(
|
.add_props(
|
||||||
remark_plugins=_REMARK_PLUGINS,
|
remark_plugins=_REMARK_PLUGINS,
|
||||||
rehype_plugins=_REHYPE_PLUGINS,
|
rehype_plugins=_REHYPE_PLUGINS,
|
||||||
|
components=ImmutableVar.create_safe(
|
||||||
|
f"{self._get_component_map_name()}()"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.remove_props("componentMap", "componentMapHash")
|
.remove_props("componentMap", "componentMapHash")
|
||||||
)
|
)
|
||||||
tag.special_props.add(
|
|
||||||
Var.create_safe(
|
|
||||||
f"components={{{self._get_component_map_name()}()}}",
|
|
||||||
_var_is_local=True,
|
|
||||||
_var_is_string=False,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
return tag
|
return tag
|
||||||
|
@ -8,24 +8,21 @@ from typing import Any, Callable, Dict, Optional, Union, overload
|
|||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import EventHandler, EventSpec
|
from reflex.event import EventHandler, EventSpec
|
||||||
|
from reflex.ivars.base import ImmutableVar, LiteralVar
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.utils.imports import ImportDict
|
from reflex.utils.imports import ImportDict
|
||||||
from reflex.vars import BaseVar, Var
|
from reflex.vars import BaseVar, Var
|
||||||
|
|
||||||
_CHILDREN = Var.create_safe("children", _var_is_local=False, _var_is_string=False)
|
_CHILDREN = ImmutableVar.create_safe("children")
|
||||||
_PROPS = Var.create_safe("...props", _var_is_local=False, _var_is_string=False)
|
_PROPS = ImmutableVar.create_safe("...props")
|
||||||
_MOCK_ARG = Var.create_safe("", _var_is_string=False)
|
_MOCK_ARG = ImmutableVar.create_safe("")
|
||||||
_REMARK_MATH = Var.create_safe("remarkMath", _var_is_local=False, _var_is_string=False)
|
_REMARK_MATH = ImmutableVar.create_safe("remarkMath")
|
||||||
_REMARK_GFM = Var.create_safe("remarkGfm", _var_is_local=False, _var_is_string=False)
|
_REMARK_GFM = ImmutableVar.create_safe("remarkGfm")
|
||||||
_REMARK_UNWRAP_IMAGES = Var.create_safe(
|
_REMARK_UNWRAP_IMAGES = ImmutableVar.create_safe("remarkUnwrapImages")
|
||||||
"remarkUnwrapImages", _var_is_local=False, _var_is_string=False
|
_REMARK_PLUGINS = LiteralVar.create([_REMARK_MATH, _REMARK_GFM, _REMARK_UNWRAP_IMAGES])
|
||||||
)
|
_REHYPE_KATEX = ImmutableVar.create_safe("rehypeKatex")
|
||||||
_REMARK_PLUGINS = Var.create_safe([_REMARK_MATH, _REMARK_GFM, _REMARK_UNWRAP_IMAGES])
|
_REHYPE_RAW = ImmutableVar.create_safe("rehypeRaw")
|
||||||
_REHYPE_KATEX = Var.create_safe(
|
_REHYPE_PLUGINS = LiteralVar.create([_REHYPE_KATEX, _REHYPE_RAW])
|
||||||
"rehypeKatex", _var_is_local=False, _var_is_string=False
|
|
||||||
)
|
|
||||||
_REHYPE_RAW = Var.create_safe("rehypeRaw", _var_is_local=False, _var_is_string=False)
|
|
||||||
_REHYPE_PLUGINS = Var.create_safe([_REHYPE_KATEX, _REHYPE_RAW])
|
|
||||||
NO_PROPS_TAGS = ("ul", "ol", "li")
|
NO_PROPS_TAGS = ("ul", "ol", "li")
|
||||||
|
|
||||||
@lru_cache
|
@lru_cache
|
||||||
|
@ -206,5 +206,5 @@ class ColorModeNamespace(ImmutableVar):
|
|||||||
color_mode = color_mode_var_and_namespace = ColorModeNamespace(
|
color_mode = color_mode_var_and_namespace = ColorModeNamespace(
|
||||||
_var_name=color_mode._var_name,
|
_var_name=color_mode._var_name,
|
||||||
_var_type=color_mode._var_type,
|
_var_type=color_mode._var_type,
|
||||||
_var_data=color_mode._var_data,
|
_var_data=color_mode.get_default_value(),
|
||||||
)
|
)
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
# ------------------- DO NOT EDIT ----------------------
|
# ------------------- DO NOT EDIT ----------------------
|
||||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||||
# ------------------------------------------------------
|
# ------------------------------------------------------
|
||||||
import dataclasses
|
|
||||||
from typing import Any, Callable, Dict, Literal, Optional, Union, get_args, overload
|
from typing import Any, Callable, Dict, Literal, Optional, Union, get_args, overload
|
||||||
|
|
||||||
from reflex.components.component import BaseComponent
|
from reflex.components.component import BaseComponent
|
||||||
@ -12,6 +11,7 @@ from reflex.components.core.cond import Cond
|
|||||||
from reflex.components.lucide.icon import Icon
|
from reflex.components.lucide.icon import Icon
|
||||||
from reflex.components.radix.themes.components.switch import Switch
|
from reflex.components.radix.themes.components.switch import Switch
|
||||||
from reflex.event import EventHandler, EventSpec
|
from reflex.event import EventHandler, EventSpec
|
||||||
|
from reflex.ivars.base import ImmutableVar
|
||||||
from reflex.style import (
|
from reflex.style import (
|
||||||
Style,
|
Style,
|
||||||
color_mode,
|
color_mode,
|
||||||
@ -533,11 +533,13 @@ class ColorModeSwitch(Switch):
|
|||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
class ColorModeNamespace(BaseVar):
|
class ColorModeNamespace(ImmutableVar):
|
||||||
icon = staticmethod(ColorModeIcon.create)
|
icon = staticmethod(ColorModeIcon.create)
|
||||||
button = staticmethod(ColorModeIconButton.create)
|
button = staticmethod(ColorModeIconButton.create)
|
||||||
switch = staticmethod(ColorModeSwitch.create)
|
switch = staticmethod(ColorModeSwitch.create)
|
||||||
|
|
||||||
color_mode = color_mode_var_and_namespace = ColorModeNamespace(
|
color_mode = color_mode_var_and_namespace = ColorModeNamespace(
|
||||||
**dataclasses.asdict(color_mode)
|
_var_name=color_mode._var_name,
|
||||||
|
_var_type=color_mode._var_type,
|
||||||
|
_var_data=color_mode.get_default_value(),
|
||||||
)
|
)
|
||||||
|
@ -7,6 +7,7 @@ from reflex.components.core.breakpoints import Responsive
|
|||||||
from reflex.components.radix.themes.layout.flex import Flex
|
from reflex.components.radix.themes.layout.flex import Flex
|
||||||
from reflex.components.radix.themes.typography.text import Text
|
from reflex.components.radix.themes.typography.text import Text
|
||||||
from reflex.event import EventHandler
|
from reflex.event import EventHandler
|
||||||
|
from reflex.ivars.base import LiteralVar
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
from ..base import (
|
from ..base import (
|
||||||
@ -115,9 +116,7 @@ class HighLevelCheckbox(RadixThemesComponent):
|
|||||||
on_change: EventHandler[lambda e0: [e0]]
|
on_change: EventHandler[lambda e0: [e0]]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(
|
def create(cls, text: Var[str] = LiteralVar.create(""), **props) -> Component:
|
||||||
cls, text: Var[str] = Var.create_safe("", _var_is_string=True), **props
|
|
||||||
) -> Component:
|
|
||||||
"""Create a checkbox with a label.
|
"""Create a checkbox with a label.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -11,7 +11,6 @@ from reflex.components.radix.themes.layout.flex import Flex
|
|||||||
from reflex.components.radix.themes.typography.text import Text
|
from reflex.components.radix.themes.typography.text import Text
|
||||||
from reflex.event import EventHandler
|
from reflex.event import EventHandler
|
||||||
from reflex.ivars.base import ImmutableVar, LiteralVar
|
from reflex.ivars.base import ImmutableVar, LiteralVar
|
||||||
from reflex.ivars.function import JSON_STRINGIFY
|
|
||||||
from reflex.ivars.sequence import StringVar
|
from reflex.ivars.sequence import StringVar
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
@ -30,14 +29,10 @@ class RadioGroupRoot(RadixThemesComponent):
|
|||||||
tag = "RadioGroup.Root"
|
tag = "RadioGroup.Root"
|
||||||
|
|
||||||
# The size of the radio group: "1" | "2" | "3"
|
# The size of the radio group: "1" | "2" | "3"
|
||||||
size: Var[Responsive[Literal["1", "2", "3"]]] = Var.create_safe(
|
size: Var[Responsive[Literal["1", "2", "3"]]] = LiteralVar.create("2")
|
||||||
"2", _var_is_string=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# The variant of the radio group
|
# The variant of the radio group
|
||||||
variant: Var[Literal["classic", "surface", "soft"]] = Var.create_safe(
|
variant: Var[Literal["classic", "surface", "soft"]] = LiteralVar.create("classic")
|
||||||
"classic", _var_is_string=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# The color of the radio group
|
# The color of the radio group
|
||||||
color_scheme: Var[LiteralAccentColor]
|
color_scheme: Var[LiteralAccentColor]
|
||||||
@ -89,20 +84,16 @@ class HighLevelRadioGroup(RadixThemesComponent):
|
|||||||
items: Var[List[str]]
|
items: Var[List[str]]
|
||||||
|
|
||||||
# The direction of the radio group.
|
# The direction of the radio group.
|
||||||
direction: Var[LiteralFlexDirection] = Var.create_safe(
|
direction: Var[LiteralFlexDirection] = LiteralVar.create("column")
|
||||||
"column", _var_is_string=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# The gap between the items of the radio group.
|
# The gap between the items of the radio group.
|
||||||
spacing: Var[LiteralSpacing] = Var.create_safe("2", _var_is_string=True)
|
spacing: Var[LiteralSpacing] = LiteralVar.create("2")
|
||||||
|
|
||||||
# The size of the radio group.
|
# The size of the radio group.
|
||||||
size: Var[Literal["1", "2", "3"]] = Var.create_safe("2", _var_is_string=True)
|
size: Var[Literal["1", "2", "3"]] = LiteralVar.create("2")
|
||||||
|
|
||||||
# The variant of the radio group
|
# The variant of the radio group
|
||||||
variant: Var[Literal["classic", "surface", "soft"]] = Var.create_safe(
|
variant: Var[Literal["classic", "surface", "soft"]] = LiteralVar.create("classic")
|
||||||
"classic", _var_is_string=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# The color of the radio group
|
# The color of the radio group
|
||||||
color_scheme: Var[LiteralAccentColor]
|
color_scheme: Var[LiteralAccentColor]
|
||||||
@ -159,13 +150,13 @@ class HighLevelRadioGroup(RadixThemesComponent):
|
|||||||
):
|
):
|
||||||
default_value = LiteralVar.create(default_value) # type: ignore
|
default_value = LiteralVar.create(default_value) # type: ignore
|
||||||
else:
|
else:
|
||||||
default_value = JSON_STRINGIFY.call(ImmutableVar.create(default_value))
|
default_value = ImmutableVar.create_safe(default_value).to_string()
|
||||||
|
|
||||||
def radio_group_item(value: Var) -> Component:
|
def radio_group_item(value: Var) -> Component:
|
||||||
item_value = rx.cond(
|
item_value = rx.cond(
|
||||||
value._type() == "string",
|
value._type() == "string",
|
||||||
value,
|
value,
|
||||||
JSON_STRINGIFY.call(value),
|
value.to_string(),
|
||||||
).to(StringVar)
|
).to(StringVar)
|
||||||
|
|
||||||
return Text.create(
|
return Text.create(
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
from typing import Literal
|
from typing import Literal
|
||||||
|
|
||||||
from reflex.components.core.breakpoints import Responsive
|
from reflex.components.core.breakpoints import Responsive
|
||||||
|
from reflex.ivars.base import LiteralVar
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
from ..base import (
|
from ..base import (
|
||||||
@ -19,9 +20,7 @@ class Separator(RadixThemesComponent):
|
|||||||
tag = "Separator"
|
tag = "Separator"
|
||||||
|
|
||||||
# The size of the select: "1" | "2" | "3" | "4"
|
# The size of the select: "1" | "2" | "3" | "4"
|
||||||
size: Var[Responsive[LiteralSeperatorSize]] = Var.create_safe(
|
size: Var[Responsive[LiteralSeperatorSize]] = LiteralVar.create("4")
|
||||||
"4", _var_is_string=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# The color of the select
|
# The color of the select
|
||||||
color_scheme: Var[LiteralAccentColor]
|
color_scheme: Var[LiteralAccentColor]
|
||||||
|
@ -6,6 +6,7 @@ from typing import Literal
|
|||||||
|
|
||||||
from reflex.components.core.breakpoints import Responsive
|
from reflex.components.core.breakpoints import Responsive
|
||||||
from reflex.components.el import elements
|
from reflex.components.el import elements
|
||||||
|
from reflex.ivars.base import LiteralVar
|
||||||
from reflex.style import STACK_CHILDREN_FULL_WIDTH
|
from reflex.style import STACK_CHILDREN_FULL_WIDTH
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
@ -23,9 +24,7 @@ class Container(elements.Div, RadixThemesComponent):
|
|||||||
tag = "Container"
|
tag = "Container"
|
||||||
|
|
||||||
# The size of the container: "1" - "4" (default "3")
|
# The size of the container: "1" - "4" (default "3")
|
||||||
size: Var[Responsive[LiteralContainerSize]] = Var.create_safe(
|
size: Var[Responsive[LiteralContainerSize]] = LiteralVar.create("3")
|
||||||
"3", _var_is_string=True
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(
|
def create(
|
||||||
|
@ -6,6 +6,7 @@ from typing import Literal
|
|||||||
|
|
||||||
from reflex.components.core.breakpoints import Responsive
|
from reflex.components.core.breakpoints import Responsive
|
||||||
from reflex.components.el import elements
|
from reflex.components.el import elements
|
||||||
|
from reflex.ivars.base import LiteralVar
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
from ..base import RadixThemesComponent
|
from ..base import RadixThemesComponent
|
||||||
@ -19,9 +20,7 @@ class Section(elements.Section, RadixThemesComponent):
|
|||||||
tag = "Section"
|
tag = "Section"
|
||||||
|
|
||||||
# The size of the section: "1" - "3" (default "2")
|
# The size of the section: "1" - "3" (default "2")
|
||||||
size: Var[Responsive[LiteralSectionSize]] = Var.create_safe(
|
size: Var[Responsive[LiteralSectionSize]] = LiteralVar.create("2")
|
||||||
"2", _var_is_string=True
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
section = Section.create
|
section = Section.create
|
||||||
|
@ -7,6 +7,7 @@ from typing import Any, Dict, List, Union
|
|||||||
from reflex.constants import EventTriggers
|
from reflex.constants import EventTriggers
|
||||||
from reflex.constants.colors import Color
|
from reflex.constants.colors import Color
|
||||||
from reflex.event import EventHandler
|
from reflex.event import EventHandler
|
||||||
|
from reflex.ivars.base import LiteralVar
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
from .recharts import (
|
from .recharts import (
|
||||||
@ -86,7 +87,7 @@ class Axis(Recharts):
|
|||||||
tick_count: Var[int]
|
tick_count: Var[int]
|
||||||
|
|
||||||
# If set false, no axis tick lines will be drawn.
|
# If set false, no axis tick lines will be drawn.
|
||||||
tick_line: Var[bool] = Var.create_safe(False)
|
tick_line: Var[bool] = LiteralVar.create(False)
|
||||||
|
|
||||||
# The length of tick line.
|
# The length of tick line.
|
||||||
tick_size: Var[int]
|
tick_size: Var[int]
|
||||||
@ -95,7 +96,7 @@ class Axis(Recharts):
|
|||||||
min_tick_gap: Var[int]
|
min_tick_gap: Var[int]
|
||||||
|
|
||||||
# The stroke color of axis
|
# The stroke color of axis
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("gray", 9))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("gray", 9))
|
||||||
|
|
||||||
# The text anchor of axis
|
# The text anchor of axis
|
||||||
text_anchor: Var[str] # 'start', 'middle', 'end'
|
text_anchor: Var[str] # 'start', 'middle', 'end'
|
||||||
@ -136,7 +137,7 @@ class XAxis(Axis):
|
|||||||
x_axis_id: Var[Union[str, int]]
|
x_axis_id: Var[Union[str, int]]
|
||||||
|
|
||||||
# Ensures that all datapoints within a chart contribute to its domain calculation, even when they are hidden
|
# Ensures that all datapoints within a chart contribute to its domain calculation, even when they are hidden
|
||||||
include_hidden: Var[bool] = Var.create_safe(False)
|
include_hidden: Var[bool] = LiteralVar.create(False)
|
||||||
|
|
||||||
|
|
||||||
class YAxis(Axis):
|
class YAxis(Axis):
|
||||||
@ -187,10 +188,10 @@ class Brush(Recharts):
|
|||||||
alias = "RechartsBrush"
|
alias = "RechartsBrush"
|
||||||
|
|
||||||
# Stroke color
|
# Stroke color
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("gray", 9))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("gray", 9))
|
||||||
|
|
||||||
# The fill color of brush.
|
# The fill color of brush.
|
||||||
fill: Var[Union[str, Color]] = Var.create_safe(Color("gray", 2))
|
fill: Var[Union[str, Color]] = LiteralVar.create(Color("gray", 2))
|
||||||
|
|
||||||
# The key of data displayed in the axis.
|
# The key of data displayed in the axis.
|
||||||
data_key: Var[Union[str, int]]
|
data_key: Var[Union[str, int]]
|
||||||
@ -290,22 +291,22 @@ class Area(Cartesian):
|
|||||||
alias = "RechartsArea"
|
alias = "RechartsArea"
|
||||||
|
|
||||||
# The color of the line stroke.
|
# The color of the line stroke.
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("accent", 9))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("accent", 9))
|
||||||
|
|
||||||
# The width of the line stroke.
|
# The width of the line stroke.
|
||||||
stroke_width: Var[int] = Var.create_safe(1)
|
stroke_width: Var[int] = LiteralVar.create(1)
|
||||||
|
|
||||||
# The color of the area fill.
|
# The color of the area fill.
|
||||||
fill: Var[Union[str, Color]] = Var.create_safe(Color("accent", 5))
|
fill: Var[Union[str, Color]] = LiteralVar.create(Color("accent", 5))
|
||||||
|
|
||||||
# The interpolation type of area. And customized interpolation function can be set to type. 'basis' | 'basisClosed' | 'basisOpen' | 'bumpX' | 'bumpY' | 'bump' | 'linear' | 'linearClosed' | 'natural' | 'monotoneX' | 'monotoneY' | 'monotone' | 'step' | 'stepBefore' | 'stepAfter' |
|
# The interpolation type of area. And customized interpolation function can be set to type. 'basis' | 'basisClosed' | 'basisOpen' | 'bumpX' | 'bumpY' | 'bump' | 'linear' | 'linearClosed' | 'natural' | 'monotoneX' | 'monotoneY' | 'monotone' | 'step' | 'stepBefore' | 'stepAfter' |
|
||||||
type_: Var[LiteralAreaType] = Var.create_safe("monotone", _var_is_string=True)
|
type_: Var[LiteralAreaType] = LiteralVar.create("monotone")
|
||||||
|
|
||||||
# If false set, dots will not be drawn. If true set, dots will be drawn which have the props calculated internally.
|
# If false set, dots will not be drawn. If true set, dots will be drawn which have the props calculated internally.
|
||||||
dot: Var[Union[bool, Dict[str, Any]]]
|
dot: Var[Union[bool, Dict[str, Any]]]
|
||||||
|
|
||||||
# The dot is shown when user enter an area chart and this chart has tooltip. If false set, no active dot will not be drawn. If true set, active dot will be drawn which have the props calculated internally.
|
# The dot is shown when user enter an area chart and this chart has tooltip. If false set, no active dot will not be drawn. If true set, active dot will be drawn which have the props calculated internally.
|
||||||
active_dot: Var[Union[bool, Dict[str, Any]]] = Var.create_safe(
|
active_dot: Var[Union[bool, Dict[str, Any]]] = LiteralVar.create(
|
||||||
{
|
{
|
||||||
"stroke": Color("accent", 2),
|
"stroke": Color("accent", 2),
|
||||||
"fill": Color("accent", 10),
|
"fill": Color("accent", 10),
|
||||||
@ -342,7 +343,7 @@ class Bar(Cartesian):
|
|||||||
stroke_width: Var[int]
|
stroke_width: Var[int]
|
||||||
|
|
||||||
# The width of the line stroke.
|
# The width of the line stroke.
|
||||||
fill: Var[Union[str, Color]] = Var.create_safe(Color("accent", 9))
|
fill: Var[Union[str, Color]] = LiteralVar.create(Color("accent", 9))
|
||||||
# If false set, background of bars will not be drawn. If true set, background of bars will be drawn which have the props calculated internally.
|
# If false set, background of bars will not be drawn. If true set, background of bars will be drawn which have the props calculated internally.
|
||||||
background: Var[bool]
|
background: Var[bool]
|
||||||
|
|
||||||
@ -403,13 +404,13 @@ class Line(Cartesian):
|
|||||||
type_: Var[LiteralAreaType]
|
type_: Var[LiteralAreaType]
|
||||||
|
|
||||||
# The color of the line stroke.
|
# The color of the line stroke.
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("accent", 9))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("accent", 9))
|
||||||
|
|
||||||
# The width of the line stroke.
|
# The width of the line stroke.
|
||||||
stroke_width: Var[int]
|
stroke_width: Var[int]
|
||||||
|
|
||||||
# The dot is shown when mouse enter a line chart and this chart has tooltip. If false set, no active dot will not be drawn. If true set, active dot will be drawn which have the props calculated internally.
|
# The dot is shown when mouse enter a line chart and this chart has tooltip. If false set, no active dot will not be drawn. If true set, active dot will be drawn which have the props calculated internally.
|
||||||
dot: Var[Union[bool, Dict[str, Any]]] = Var.create_safe(
|
dot: Var[Union[bool, Dict[str, Any]]] = LiteralVar.create(
|
||||||
{
|
{
|
||||||
"stroke": Color("accent", 10),
|
"stroke": Color("accent", 10),
|
||||||
"fill": Color("accent", 4),
|
"fill": Color("accent", 4),
|
||||||
@ -417,7 +418,7 @@ class Line(Cartesian):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# The dot is shown when user enter an area chart and this chart has tooltip. If false set, no active dot will not be drawn. If true set, active dot will be drawn which have the props calculated internally.
|
# The dot is shown when user enter an area chart and this chart has tooltip. If false set, no active dot will not be drawn. If true set, active dot will be drawn which have the props calculated internally.
|
||||||
active_dot: Var[Union[bool, Dict[str, Any]]] = Var.create_safe(
|
active_dot: Var[Union[bool, Dict[str, Any]]] = LiteralVar.create(
|
||||||
{
|
{
|
||||||
"stroke": Color("accent", 2),
|
"stroke": Color("accent", 2),
|
||||||
"fill": Color("accent", 10),
|
"fill": Color("accent", 10),
|
||||||
@ -475,7 +476,7 @@ class Scatter(Recharts):
|
|||||||
line_type: Var[LiteralLineType]
|
line_type: Var[LiteralLineType]
|
||||||
|
|
||||||
# The fill
|
# The fill
|
||||||
fill: Var[Union[str, Color]] = Var.create_safe(Color("accent", 9))
|
fill: Var[Union[str, Color]] = LiteralVar.create(Color("accent", 9))
|
||||||
|
|
||||||
# the name
|
# the name
|
||||||
name: Var[Union[str, int]]
|
name: Var[Union[str, int]]
|
||||||
@ -552,7 +553,7 @@ class Funnel(Recharts):
|
|||||||
animation_easing: Var[LiteralAnimationEasing]
|
animation_easing: Var[LiteralAnimationEasing]
|
||||||
|
|
||||||
# stroke color
|
# stroke color
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("gray", 3))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("gray", 3))
|
||||||
|
|
||||||
# Valid children components
|
# Valid children components
|
||||||
_valid_children: List[str] = ["LabelList", "Cell"]
|
_valid_children: List[str] = ["LabelList", "Cell"]
|
||||||
@ -605,7 +606,7 @@ class ErrorBar(Recharts):
|
|||||||
width: Var[int]
|
width: Var[int]
|
||||||
|
|
||||||
# The stroke color of error bar.
|
# The stroke color of error bar.
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("gray", 8))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("gray", 8))
|
||||||
|
|
||||||
# The stroke width of error bar.
|
# The stroke width of error bar.
|
||||||
stroke_width: Var[int]
|
stroke_width: Var[int]
|
||||||
@ -795,7 +796,7 @@ class CartesianGrid(Grid):
|
|||||||
stroke_dasharray: Var[str]
|
stroke_dasharray: Var[str]
|
||||||
|
|
||||||
# the stroke color of grid
|
# the stroke color of grid
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("gray", 7))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("gray", 7))
|
||||||
|
|
||||||
|
|
||||||
class CartesianAxis(Grid):
|
class CartesianAxis(Grid):
|
||||||
|
@ -9,6 +9,7 @@ from reflex.components.recharts.general import ResponsiveContainer
|
|||||||
from reflex.constants import EventTriggers
|
from reflex.constants import EventTriggers
|
||||||
from reflex.constants.colors import Color
|
from reflex.constants.colors import Color
|
||||||
from reflex.event import EventHandler
|
from reflex.event import EventHandler
|
||||||
|
from reflex.ivars.base import LiteralVar
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
from .recharts import (
|
from .recharts import (
|
||||||
@ -156,10 +157,10 @@ class BarChart(CategoricalChartBase):
|
|||||||
alias = "RechartsBarChart"
|
alias = "RechartsBarChart"
|
||||||
|
|
||||||
# The gap between two bar categories, which can be a percent value or a fixed value. Percentage | Number
|
# The gap between two bar categories, which can be a percent value or a fixed value. Percentage | Number
|
||||||
bar_category_gap: Var[Union[str, int]] = Var.create_safe("10%", _var_is_string=True) # type: ignore
|
bar_category_gap: Var[Union[str, int]] = LiteralVar.create("10%")
|
||||||
|
|
||||||
# The gap between two bars in the same category, which can be a percent value or a fixed value. Percentage | Number
|
# The gap between two bars in the same category, which can be a percent value or a fixed value. Percentage | Number
|
||||||
bar_gap: Var[Union[str, int]] = Var.create_safe(4) # type: ignore
|
bar_gap: Var[Union[str, int]] = LiteralVar.create(4) # type: ignore
|
||||||
|
|
||||||
# The width of all the bars in the chart. Number
|
# The width of all the bars in the chart. Number
|
||||||
bar_size: Var[int]
|
bar_size: Var[int]
|
||||||
|
@ -7,6 +7,7 @@ from typing import Any, Dict, List, Union
|
|||||||
from reflex.components.component import MemoizationLeaf
|
from reflex.components.component import MemoizationLeaf
|
||||||
from reflex.constants.colors import Color
|
from reflex.constants.colors import Color
|
||||||
from reflex.event import EventHandler
|
from reflex.event import EventHandler
|
||||||
|
from reflex.ivars.base import LiteralVar
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
from .recharts import (
|
from .recharts import (
|
||||||
@ -139,7 +140,7 @@ class GraphingTooltip(Recharts):
|
|||||||
filter_null: Var[bool]
|
filter_null: Var[bool]
|
||||||
|
|
||||||
# If set false, no cursor will be drawn when tooltip is active.
|
# If set false, no cursor will be drawn when tooltip is active.
|
||||||
cursor: Var[Union[Dict[str, Any], bool]] = Var.create_safe(
|
cursor: Var[Union[Dict[str, Any], bool]] = LiteralVar.create(
|
||||||
{
|
{
|
||||||
"strokeWidth": 1,
|
"strokeWidth": 1,
|
||||||
"fill": Color("gray", 3),
|
"fill": Color("gray", 3),
|
||||||
@ -150,7 +151,7 @@ class GraphingTooltip(Recharts):
|
|||||||
view_box: Var[Dict[str, Any]]
|
view_box: Var[Dict[str, Any]]
|
||||||
|
|
||||||
# The style of default tooltip content item which is a li element. DEFAULT: {}
|
# The style of default tooltip content item which is a li element. DEFAULT: {}
|
||||||
item_style: Var[Dict[str, Any]] = Var.create_safe(
|
item_style: Var[Dict[str, Any]] = LiteralVar.create(
|
||||||
{
|
{
|
||||||
"color": Color("gray", 12),
|
"color": Color("gray", 12),
|
||||||
}
|
}
|
||||||
@ -159,7 +160,7 @@ class GraphingTooltip(Recharts):
|
|||||||
# The style of tooltip wrapper which is a dom element. DEFAULT: {}
|
# The style of tooltip wrapper which is a dom element. DEFAULT: {}
|
||||||
wrapper_style: Var[Dict[str, Any]]
|
wrapper_style: Var[Dict[str, Any]]
|
||||||
# The style of tooltip content which is a dom element. DEFAULT: {}
|
# The style of tooltip content which is a dom element. DEFAULT: {}
|
||||||
content_style: Var[Dict[str, Any]] = Var.create_safe(
|
content_style: Var[Dict[str, Any]] = LiteralVar.create(
|
||||||
{
|
{
|
||||||
"background": Color("gray", 1),
|
"background": Color("gray", 1),
|
||||||
"borderColor": Color("gray", 4),
|
"borderColor": Color("gray", 4),
|
||||||
@ -168,10 +169,10 @@ class GraphingTooltip(Recharts):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# The style of default tooltip label which is a p element. DEFAULT: {}
|
# The style of default tooltip label which is a p element. DEFAULT: {}
|
||||||
label_style: Var[Dict[str, Any]] = Var.create_safe({"color": Color("gray", 11)})
|
label_style: Var[Dict[str, Any]] = LiteralVar.create({"color": Color("gray", 11)})
|
||||||
|
|
||||||
# This option allows the tooltip to extend beyond the viewBox of the chart itself. DEFAULT: { x: false, y: false }
|
# This option allows the tooltip to extend beyond the viewBox of the chart itself. DEFAULT: { x: false, y: false }
|
||||||
allow_escape_view_box: Var[Dict[str, bool]] = Var.create_safe(
|
allow_escape_view_box: Var[Dict[str, bool]] = LiteralVar.create(
|
||||||
{"x": False, "y": False}
|
{"x": False, "y": False}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -231,10 +232,10 @@ class LabelList(Recharts):
|
|||||||
offset: Var[int]
|
offset: Var[int]
|
||||||
|
|
||||||
# The fill color of each label
|
# The fill color of each label
|
||||||
fill: Var[Union[str, Color]] = Var.create_safe(Color("gray", 10))
|
fill: Var[Union[str, Color]] = LiteralVar.create(Color("gray", 10))
|
||||||
|
|
||||||
# The stroke color of each label
|
# The stroke color of each label
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe("none", _var_is_string=True)
|
stroke: Var[Union[str, Color]] = LiteralVar.create("none")
|
||||||
|
|
||||||
|
|
||||||
responsive_container = ResponsiveContainer.create
|
responsive_container = ResponsiveContainer.create
|
||||||
|
@ -7,6 +7,7 @@ from typing import Any, Dict, List, Union
|
|||||||
from reflex.constants import EventTriggers
|
from reflex.constants import EventTriggers
|
||||||
from reflex.constants.colors import Color
|
from reflex.constants.colors import Color
|
||||||
from reflex.event import EventHandler
|
from reflex.event import EventHandler
|
||||||
|
from reflex.ivars.base import LiteralVar
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
from .recharts import (
|
from .recharts import (
|
||||||
@ -72,10 +73,10 @@ class Pie(Recharts):
|
|||||||
_valid_children: List[str] = ["Cell", "LabelList"]
|
_valid_children: List[str] = ["Cell", "LabelList"]
|
||||||
|
|
||||||
# Stoke color
|
# Stoke color
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("accent", 9))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("accent", 9))
|
||||||
|
|
||||||
# Fill color
|
# Fill color
|
||||||
fill: Var[Union[str, Color]] = Var.create_safe(Color("accent", 3))
|
fill: Var[Union[str, Color]] = LiteralVar.create(Color("accent", 3))
|
||||||
|
|
||||||
def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
|
def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
|
||||||
"""Get the event triggers that pass the component's value to the handler.
|
"""Get the event triggers that pass the component's value to the handler.
|
||||||
@ -110,13 +111,13 @@ class Radar(Recharts):
|
|||||||
dot: Var[bool]
|
dot: Var[bool]
|
||||||
|
|
||||||
# Stoke color
|
# Stoke color
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("accent", 9))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("accent", 9))
|
||||||
|
|
||||||
# Fill color
|
# Fill color
|
||||||
fill: Var[str] = Var.create_safe(Color("accent", 3))
|
fill: Var[str] = LiteralVar.create(Color("accent", 3))
|
||||||
|
|
||||||
# opacity
|
# opacity
|
||||||
fill_opacity: Var[float] = Var.create_safe(0.6)
|
fill_opacity: Var[float] = LiteralVar.create(0.6)
|
||||||
|
|
||||||
# The type of icon in legend. If set to 'none', no legend item will be rendered.
|
# The type of icon in legend. If set to 'none', no legend item will be rendered.
|
||||||
legend_type: Var[str]
|
legend_type: Var[str]
|
||||||
@ -218,7 +219,7 @@ class PolarAngleAxis(Recharts):
|
|||||||
axis_line_type: Var[str]
|
axis_line_type: Var[str]
|
||||||
|
|
||||||
# If false set, tick lines will not be drawn. If true set, tick lines will be drawn which have the props calculated internally. If object set, tick lines will be drawn which have the props mergered by the internal calculated props and the option.
|
# If false set, tick lines will not be drawn. If true set, tick lines will be drawn which have the props calculated internally. If object set, tick lines will be drawn which have the props mergered by the internal calculated props and the option.
|
||||||
tick_line: Var[Union[bool, Dict[str, Any]]] = Var.create_safe(False)
|
tick_line: Var[Union[bool, Dict[str, Any]]] = LiteralVar.create(False)
|
||||||
|
|
||||||
# The width or height of tick.
|
# The width or height of tick.
|
||||||
tick: Var[Union[int, str]]
|
tick: Var[Union[int, str]]
|
||||||
@ -230,7 +231,7 @@ class PolarAngleAxis(Recharts):
|
|||||||
orient: Var[str]
|
orient: Var[str]
|
||||||
|
|
||||||
# The stroke color of axis
|
# The stroke color of axis
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("gray", 10))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("gray", 10))
|
||||||
|
|
||||||
# Allow the axis has duplicated categorys or not when the type of axis is "category".
|
# Allow the axis has duplicated categorys or not when the type of axis is "category".
|
||||||
allow_duplicated_category: Var[bool]
|
allow_duplicated_category: Var[bool]
|
||||||
@ -292,7 +293,7 @@ class PolarGrid(Recharts):
|
|||||||
grid_type: Var[LiteralGridType]
|
grid_type: Var[LiteralGridType]
|
||||||
|
|
||||||
# The stroke color of grid
|
# The stroke color of grid
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("gray", 10))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("gray", 10))
|
||||||
|
|
||||||
# Valid children components
|
# Valid children components
|
||||||
_valid_children: List[str] = ["RadarChart", "RadiarBarChart"]
|
_valid_children: List[str] = ["RadarChart", "RadiarBarChart"]
|
||||||
@ -342,10 +343,10 @@ class PolarRadiusAxis(Recharts):
|
|||||||
_valid_children: List[str] = ["Label"]
|
_valid_children: List[str] = ["Label"]
|
||||||
|
|
||||||
# The domain of the polar radius axis, specifying the minimum and maximum values.
|
# The domain of the polar radius axis, specifying the minimum and maximum values.
|
||||||
domain: Var[List[int]] = Var.create_safe([0, 250])
|
domain: Var[List[int]] = LiteralVar.create([0, 250])
|
||||||
|
|
||||||
# The stroke color of axis
|
# The stroke color of axis
|
||||||
stroke: Var[Union[str, Color]] = Var.create_safe(Color("gray", 10))
|
stroke: Var[Union[str, Color]] = LiteralVar.create(Color("gray", 10))
|
||||||
|
|
||||||
def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
|
def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
|
||||||
"""Get the event triggers that pass the component's value to the handler.
|
"""Get the event triggers that pass the component's value to the handler.
|
||||||
|
@ -12,6 +12,7 @@ from reflex.event import (
|
|||||||
EventSpec,
|
EventSpec,
|
||||||
call_script,
|
call_script,
|
||||||
)
|
)
|
||||||
|
from reflex.ivars.base import LiteralVar
|
||||||
from reflex.style import Style, resolved_color_mode
|
from reflex.style import Style, resolved_color_mode
|
||||||
from reflex.utils import format
|
from reflex.utils import format
|
||||||
from reflex.utils.imports import ImportVar
|
from reflex.utils.imports import ImportVar
|
||||||
@ -171,21 +172,19 @@ class Toaster(Component):
|
|||||||
theme: Var[str] = resolved_color_mode
|
theme: Var[str] = resolved_color_mode
|
||||||
|
|
||||||
# whether to show rich colors
|
# whether to show rich colors
|
||||||
rich_colors: Var[bool] = Var.create_safe(True)
|
rich_colors: Var[bool] = LiteralVar.create(True)
|
||||||
|
|
||||||
# whether to expand the toast
|
# whether to expand the toast
|
||||||
expand: Var[bool] = Var.create_safe(True)
|
expand: Var[bool] = LiteralVar.create(True)
|
||||||
|
|
||||||
# the number of toasts that are currently visible
|
# the number of toasts that are currently visible
|
||||||
visible_toasts: Var[int]
|
visible_toasts: Var[int]
|
||||||
|
|
||||||
# the position of the toast
|
# the position of the toast
|
||||||
position: Var[LiteralPosition] = Var.create_safe(
|
position: Var[LiteralPosition] = LiteralVar.create("bottom-right")
|
||||||
"bottom-right", _var_is_string=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# whether to show the close button
|
# whether to show the close button
|
||||||
close_button: Var[bool] = Var.create_safe(False)
|
close_button: Var[bool] = LiteralVar.create(False)
|
||||||
|
|
||||||
# offset of the toast
|
# offset of the toast
|
||||||
offset: Var[str]
|
offset: Var[str]
|
||||||
@ -330,7 +329,7 @@ class Toaster(Component):
|
|||||||
|
|
||||||
if isinstance(id, Var):
|
if isinstance(id, Var):
|
||||||
dismiss = f"{toast_ref}.dismiss({id._var_name_unwrapped})"
|
dismiss = f"{toast_ref}.dismiss({id._var_name_unwrapped})"
|
||||||
dismiss_var_data = id._var_data
|
dismiss_var_data = id._get_all_var_data()
|
||||||
elif isinstance(id, str):
|
elif isinstance(id, str):
|
||||||
dismiss = f"{toast_ref}.dismiss('{id}')"
|
dismiss = f"{toast_ref}.dismiss('{id}')"
|
||||||
else:
|
else:
|
||||||
@ -339,7 +338,7 @@ class Toaster(Component):
|
|||||||
dismiss,
|
dismiss,
|
||||||
_var_is_string=False,
|
_var_is_string=False,
|
||||||
_var_is_local=True,
|
_var_is_local=True,
|
||||||
_var_data=dismiss_var_data,
|
_var_data=VarData.merge(dismiss_var_data),
|
||||||
)
|
)
|
||||||
return call_script(dismiss_action)
|
return call_script(dismiss_action)
|
||||||
|
|
||||||
|
@ -714,15 +714,11 @@ def download(
|
|||||||
url = "data:text/plain," + urllib.parse.quote(data)
|
url = "data:text/plain," + urllib.parse.quote(data)
|
||||||
elif isinstance(data, Var):
|
elif isinstance(data, Var):
|
||||||
# Need to check on the frontend if the Var already looks like a data: URI.
|
# Need to check on the frontend if the Var already looks like a data: URI.
|
||||||
is_data_url = data._replace(
|
|
||||||
_var_name=(
|
is_data_url = (data._type() == "string") & (
|
||||||
f"typeof {data._var_full_name} == 'string' && "
|
data.to(str).startswith("data:")
|
||||||
f"{data._var_full_name}.startsWith('data:')"
|
|
||||||
),
|
|
||||||
_var_type=bool,
|
|
||||||
_var_is_string=False,
|
|
||||||
_var_full_name_needs_state_prefix=False,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# If it's a data: URI, use it as is, otherwise convert the Var to JSON in a data: URI.
|
# If it's a data: URI, use it as is, otherwise convert the Var to JSON in a data: URI.
|
||||||
url = cond( # type: ignore
|
url = cond( # type: ignore
|
||||||
is_data_url,
|
is_data_url,
|
||||||
|
@ -2,10 +2,15 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import contextlib
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import datetime
|
||||||
|
import dis
|
||||||
import functools
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
|
import json
|
||||||
import sys
|
import sys
|
||||||
|
from types import CodeType, FunctionType
|
||||||
from typing import (
|
from typing import (
|
||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
Any,
|
Any,
|
||||||
@ -20,17 +25,22 @@ from typing import (
|
|||||||
Type,
|
Type,
|
||||||
TypeVar,
|
TypeVar,
|
||||||
Union,
|
Union,
|
||||||
|
cast,
|
||||||
get_args,
|
get_args,
|
||||||
overload,
|
overload,
|
||||||
|
override,
|
||||||
)
|
)
|
||||||
|
|
||||||
from typing_extensions import ParamSpec, get_origin
|
from typing_extensions import ParamSpec, get_origin, get_type_hints
|
||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.base import Base
|
from reflex.base import Base
|
||||||
|
from reflex.constants.colors import Color
|
||||||
from reflex.utils import console, imports, serializers, types
|
from reflex.utils import console, imports, serializers, types
|
||||||
from reflex.utils.exceptions import VarTypeError
|
from reflex.utils.exceptions import VarDependencyError, VarTypeError, VarValueError
|
||||||
|
from reflex.utils.format import format_state_name
|
||||||
from reflex.vars import (
|
from reflex.vars import (
|
||||||
|
ComputedVar,
|
||||||
ImmutableVarData,
|
ImmutableVarData,
|
||||||
Var,
|
Var,
|
||||||
VarData,
|
VarData,
|
||||||
@ -320,11 +330,15 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
|
|
||||||
@overload
|
@overload
|
||||||
def to(
|
def to(
|
||||||
self, output: Type[OUTPUT], var_type: types.GenericType | None = None
|
self,
|
||||||
|
output: Type[OUTPUT] | types.GenericType,
|
||||||
|
var_type: types.GenericType | None = None,
|
||||||
) -> OUTPUT: ...
|
) -> OUTPUT: ...
|
||||||
|
|
||||||
def to(
|
def to(
|
||||||
self, output: Type[OUTPUT], var_type: types.GenericType | None = None
|
self,
|
||||||
|
output: Type[OUTPUT] | types.GenericType,
|
||||||
|
var_type: types.GenericType | None = None,
|
||||||
) -> Var:
|
) -> Var:
|
||||||
"""Convert the var to a different type.
|
"""Convert the var to a different type.
|
||||||
|
|
||||||
@ -338,12 +352,15 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
The converted var.
|
The converted var.
|
||||||
"""
|
"""
|
||||||
|
from .function import FunctionVar, ToFunctionOperation
|
||||||
from .number import (
|
from .number import (
|
||||||
BooleanVar,
|
BooleanVar,
|
||||||
NumberVar,
|
NumberVar,
|
||||||
ToBooleanVarOperation,
|
ToBooleanVarOperation,
|
||||||
ToNumberVarOperation,
|
ToNumberVarOperation,
|
||||||
)
|
)
|
||||||
|
from .object import ObjectVar, ToObjectOperation
|
||||||
|
from .sequence import ArrayVar, StringVar, ToArrayOperation, ToStringOperation
|
||||||
|
|
||||||
fixed_type = (
|
fixed_type = (
|
||||||
var_type
|
var_type
|
||||||
@ -351,16 +368,28 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
else get_origin(var_type)
|
else get_origin(var_type)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fixed_output_type = output if inspect.isclass(output) else get_origin(output)
|
||||||
|
|
||||||
|
if fixed_output_type is dict:
|
||||||
|
return self.to(ObjectVar, output)
|
||||||
|
if fixed_output_type in (list, tuple, set):
|
||||||
|
return self.to(ArrayVar, output)
|
||||||
|
if fixed_output_type in (int, float):
|
||||||
|
return self.to(NumberVar, output)
|
||||||
|
if fixed_output_type is str:
|
||||||
|
return self.to(StringVar, output)
|
||||||
|
if fixed_output_type is bool:
|
||||||
|
return self.to(BooleanVar, output)
|
||||||
|
|
||||||
if issubclass(output, NumberVar):
|
if issubclass(output, NumberVar):
|
||||||
if fixed_type is not None and not issubclass(fixed_type, (int, float)):
|
if fixed_type is not None and not issubclass(fixed_type, (int, float)):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
f"Unsupported type {var_type} for NumberVar. Must be int or float."
|
f"Unsupported type {var_type} for NumberVar. Must be int or float."
|
||||||
)
|
)
|
||||||
return ToNumberVarOperation(self, var_type or float)
|
return ToNumberVarOperation.create(self, var_type or float)
|
||||||
if issubclass(output, BooleanVar):
|
|
||||||
return ToBooleanVarOperation(self)
|
|
||||||
|
|
||||||
from .sequence import ArrayVar, StringVar, ToArrayOperation, ToStringOperation
|
if issubclass(output, BooleanVar):
|
||||||
|
return ToBooleanVarOperation.create(self)
|
||||||
|
|
||||||
if issubclass(output, ArrayVar):
|
if issubclass(output, ArrayVar):
|
||||||
if fixed_type is not None and not issubclass(
|
if fixed_type is not None and not issubclass(
|
||||||
@ -369,28 +398,30 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
raise TypeError(
|
raise TypeError(
|
||||||
f"Unsupported type {var_type} for ArrayVar. Must be list, tuple, or set."
|
f"Unsupported type {var_type} for ArrayVar. Must be list, tuple, or set."
|
||||||
)
|
)
|
||||||
return ToArrayOperation(self, var_type or list)
|
return ToArrayOperation.create(self, var_type or list)
|
||||||
|
|
||||||
if issubclass(output, StringVar):
|
if issubclass(output, StringVar):
|
||||||
return ToStringOperation(self)
|
return ToStringOperation.create(self)
|
||||||
|
|
||||||
from .object import ObjectVar, ToObjectOperation
|
if issubclass(output, (ObjectVar, Base)):
|
||||||
|
return ToObjectOperation.create(self, var_type or dict)
|
||||||
if issubclass(output, ObjectVar):
|
|
||||||
return ToObjectOperation(self, var_type or dict)
|
|
||||||
|
|
||||||
from .function import FunctionVar, ToFunctionOperation
|
|
||||||
|
|
||||||
if issubclass(output, FunctionVar):
|
if issubclass(output, FunctionVar):
|
||||||
# if fixed_type is not None and not issubclass(fixed_type, Callable):
|
# if fixed_type is not None and not issubclass(fixed_type, Callable):
|
||||||
# raise TypeError(
|
# raise TypeError(
|
||||||
# f"Unsupported type {var_type} for FunctionVar. Must be Callable."
|
# f"Unsupported type {var_type} for FunctionVar. Must be Callable."
|
||||||
# )
|
# )
|
||||||
return ToFunctionOperation(self, var_type or Callable)
|
return ToFunctionOperation.create(self, var_type or Callable)
|
||||||
|
|
||||||
return output(
|
if not issubclass(output, Var) and var_type is None:
|
||||||
_var_name=self._var_name,
|
return dataclasses.replace(
|
||||||
_var_type=self._var_type if var_type is None else var_type,
|
self,
|
||||||
_var_data=self._var_data,
|
_var_type=output,
|
||||||
|
)
|
||||||
|
|
||||||
|
return dataclasses.replace(
|
||||||
|
self,
|
||||||
|
_var_type=var_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
def guess_type(self) -> ImmutableVar:
|
def guess_type(self) -> ImmutableVar:
|
||||||
@ -413,6 +444,9 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
if fixed_type is Union:
|
if fixed_type is Union:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
if not inspect.isclass(fixed_type):
|
||||||
|
raise TypeError(f"Unsupported type {var_type} for guess_type.")
|
||||||
|
|
||||||
if issubclass(fixed_type, (int, float)):
|
if issubclass(fixed_type, (int, float)):
|
||||||
return self.to(NumberVar, var_type)
|
return self.to(NumberVar, var_type)
|
||||||
if issubclass(fixed_type, dict):
|
if issubclass(fixed_type, dict):
|
||||||
@ -477,12 +511,12 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
The name of the setter function.
|
The name of the setter function.
|
||||||
"""
|
"""
|
||||||
setter = constants.SETTER_PREFIX + self._var_name
|
var_name_parts = self._var_name.split(".")
|
||||||
|
setter = constants.SETTER_PREFIX + var_name_parts[-1]
|
||||||
if self._var_data is None:
|
if self._var_data is None:
|
||||||
return setter
|
return setter
|
||||||
if not include_state or self._var_data.state == "":
|
if not include_state or self._var_data.state == "":
|
||||||
return setter
|
return setter
|
||||||
print("get_setter_name", self._var_data.state, setter)
|
|
||||||
return ".".join((self._var_data.state, setter))
|
return ".".join((self._var_data.state, setter))
|
||||||
|
|
||||||
def get_setter(self) -> Callable[[BaseState, Any], None]:
|
def get_setter(self) -> Callable[[BaseState, Any], None]:
|
||||||
@ -491,6 +525,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
A function that that creates a setter for the var.
|
A function that that creates a setter for the var.
|
||||||
"""
|
"""
|
||||||
|
actual_name = self._var_name.split(".")[-1]
|
||||||
|
|
||||||
def setter(state: BaseState, value: Any):
|
def setter(state: BaseState, value: Any):
|
||||||
"""Get the setter for the var.
|
"""Get the setter for the var.
|
||||||
@ -502,13 +537,13 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
if self._var_type in [int, float]:
|
if self._var_type in [int, float]:
|
||||||
try:
|
try:
|
||||||
value = self._var_type(value)
|
value = self._var_type(value)
|
||||||
setattr(state, self._var_name, value)
|
setattr(state, actual_name, value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
console.debug(
|
console.debug(
|
||||||
f"{type(state).__name__}.{self._var_name}: Failed conversion of {value} to '{self._var_type.__name__}'. Value not set.",
|
f"{type(state).__name__}.{self._var_name}: Failed conversion of {value} to '{self._var_type.__name__}'. Value not set.",
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
setattr(state, self._var_name, value)
|
setattr(state, actual_name, value)
|
||||||
|
|
||||||
setter.__qualname__ = self.get_setter_name()
|
setter.__qualname__ = self.get_setter_name()
|
||||||
|
|
||||||
@ -525,7 +560,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
"""
|
"""
|
||||||
from .number import EqualOperation
|
from .number import EqualOperation
|
||||||
|
|
||||||
return EqualOperation(self, other)
|
return EqualOperation.create(self, other)
|
||||||
|
|
||||||
def __ne__(self, other: Var | Any) -> BooleanVar:
|
def __ne__(self, other: Var | Any) -> BooleanVar:
|
||||||
"""Check if the current object is not equal to the given object.
|
"""Check if the current object is not equal to the given object.
|
||||||
@ -538,7 +573,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
"""
|
"""
|
||||||
from .number import EqualOperation
|
from .number import EqualOperation
|
||||||
|
|
||||||
return ~EqualOperation(self, other)
|
return ~EqualOperation.create(self, other)
|
||||||
|
|
||||||
def __gt__(self, other: Var | Any) -> BooleanVar:
|
def __gt__(self, other: Var | Any) -> BooleanVar:
|
||||||
"""Compare the current instance with another variable and return a BooleanVar representing the result of the greater than operation.
|
"""Compare the current instance with another variable and return a BooleanVar representing the result of the greater than operation.
|
||||||
@ -551,7 +586,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
"""
|
"""
|
||||||
from .number import GreaterThanOperation
|
from .number import GreaterThanOperation
|
||||||
|
|
||||||
return GreaterThanOperation(self, other)
|
return GreaterThanOperation.create(self, other)
|
||||||
|
|
||||||
def __ge__(self, other: Var | Any) -> BooleanVar:
|
def __ge__(self, other: Var | Any) -> BooleanVar:
|
||||||
"""Check if the value of this variable is greater than or equal to the value of another variable or object.
|
"""Check if the value of this variable is greater than or equal to the value of another variable or object.
|
||||||
@ -564,7 +599,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
"""
|
"""
|
||||||
from .number import GreaterThanOrEqualOperation
|
from .number import GreaterThanOrEqualOperation
|
||||||
|
|
||||||
return GreaterThanOrEqualOperation(self, other)
|
return GreaterThanOrEqualOperation.create(self, other)
|
||||||
|
|
||||||
def __lt__(self, other: Var | Any) -> BooleanVar:
|
def __lt__(self, other: Var | Any) -> BooleanVar:
|
||||||
"""Compare the current instance with another variable using the less than (<) operator.
|
"""Compare the current instance with another variable using the less than (<) operator.
|
||||||
@ -577,7 +612,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
"""
|
"""
|
||||||
from .number import LessThanOperation
|
from .number import LessThanOperation
|
||||||
|
|
||||||
return LessThanOperation(self, other)
|
return LessThanOperation.create(self, other)
|
||||||
|
|
||||||
def __le__(self, other: Var | Any) -> BooleanVar:
|
def __le__(self, other: Var | Any) -> BooleanVar:
|
||||||
"""Compare if the current instance is less than or equal to the given value.
|
"""Compare if the current instance is less than or equal to the given value.
|
||||||
@ -590,7 +625,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
"""
|
"""
|
||||||
from .number import LessThanOrEqualOperation
|
from .number import LessThanOrEqualOperation
|
||||||
|
|
||||||
return LessThanOrEqualOperation(self, other)
|
return LessThanOrEqualOperation.create(self, other)
|
||||||
|
|
||||||
def bool(self) -> BooleanVar:
|
def bool(self) -> BooleanVar:
|
||||||
"""Convert the var to a boolean.
|
"""Convert the var to a boolean.
|
||||||
@ -600,7 +635,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
"""
|
"""
|
||||||
from .number import ToBooleanVarOperation
|
from .number import ToBooleanVarOperation
|
||||||
|
|
||||||
return ToBooleanVarOperation(self)
|
return ToBooleanVarOperation.create(self)
|
||||||
|
|
||||||
def __and__(self, other: Var | Any) -> ImmutableVar:
|
def __and__(self, other: Var | Any) -> ImmutableVar:
|
||||||
"""Perform a logical AND operation on the current instance and another variable.
|
"""Perform a logical AND operation on the current instance and another variable.
|
||||||
@ -611,7 +646,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
A `BooleanVar` object representing the result of the logical AND operation.
|
A `BooleanVar` object representing the result of the logical AND operation.
|
||||||
"""
|
"""
|
||||||
return AndOperation(self, other)
|
return AndOperation.create(self, other)
|
||||||
|
|
||||||
def __rand__(self, other: Var | Any) -> ImmutableVar:
|
def __rand__(self, other: Var | Any) -> ImmutableVar:
|
||||||
"""Perform a logical AND operation on the current instance and another variable.
|
"""Perform a logical AND operation on the current instance and another variable.
|
||||||
@ -622,7 +657,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
A `BooleanVar` object representing the result of the logical AND operation.
|
A `BooleanVar` object representing the result of the logical AND operation.
|
||||||
"""
|
"""
|
||||||
return AndOperation(other, self)
|
return AndOperation.create(other, self)
|
||||||
|
|
||||||
def __or__(self, other: Var | Any) -> ImmutableVar:
|
def __or__(self, other: Var | Any) -> ImmutableVar:
|
||||||
"""Perform a logical OR operation on the current instance and another variable.
|
"""Perform a logical OR operation on the current instance and another variable.
|
||||||
@ -633,7 +668,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
A `BooleanVar` object representing the result of the logical OR operation.
|
A `BooleanVar` object representing the result of the logical OR operation.
|
||||||
"""
|
"""
|
||||||
return OrOperation(self, other)
|
return OrOperation.create(self, other)
|
||||||
|
|
||||||
def __ror__(self, other: Var | Any) -> ImmutableVar:
|
def __ror__(self, other: Var | Any) -> ImmutableVar:
|
||||||
"""Perform a logical OR operation on the current instance and another variable.
|
"""Perform a logical OR operation on the current instance and another variable.
|
||||||
@ -644,7 +679,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
A `BooleanVar` object representing the result of the logical OR operation.
|
A `BooleanVar` object representing the result of the logical OR operation.
|
||||||
"""
|
"""
|
||||||
return OrOperation(other, self)
|
return OrOperation.create(other, self)
|
||||||
|
|
||||||
def __invert__(self) -> BooleanVar:
|
def __invert__(self) -> BooleanVar:
|
||||||
"""Perform a logical NOT operation on the current instance.
|
"""Perform a logical NOT operation on the current instance.
|
||||||
@ -654,7 +689,7 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
"""
|
"""
|
||||||
from .number import BooleanNotOperation
|
from .number import BooleanNotOperation
|
||||||
|
|
||||||
return BooleanNotOperation(self.bool())
|
return BooleanNotOperation.create(self.bool())
|
||||||
|
|
||||||
def to_string(self) -> ImmutableVar:
|
def to_string(self) -> ImmutableVar:
|
||||||
"""Convert the var to a string.
|
"""Convert the var to a string.
|
||||||
@ -663,8 +698,9 @@ class ImmutableVar(Var, Generic[VAR_TYPE]):
|
|||||||
The string var.
|
The string var.
|
||||||
"""
|
"""
|
||||||
from .function import JSON_STRINGIFY
|
from .function import JSON_STRINGIFY
|
||||||
|
from .sequence import StringVar
|
||||||
|
|
||||||
return JSON_STRINGIFY.call(self)
|
return JSON_STRINGIFY.call(self).to(StringVar)
|
||||||
|
|
||||||
def as_ref(self) -> ImmutableVar:
|
def as_ref(self) -> ImmutableVar:
|
||||||
"""Get a reference to the var.
|
"""Get a reference to the var.
|
||||||
@ -732,35 +768,97 @@ class LiteralVar(ImmutableVar):
|
|||||||
if value is None:
|
if value is None:
|
||||||
return ImmutableVar.create_safe("null", _var_data=_var_data)
|
return ImmutableVar.create_safe("null", _var_data=_var_data)
|
||||||
|
|
||||||
|
from reflex.event import EventChain, EventSpec
|
||||||
|
from reflex.utils.format import get_event_handler_parts
|
||||||
|
|
||||||
|
from .function import ArgsFunctionOperation, FunctionStringVar
|
||||||
from .object import LiteralObjectVar
|
from .object import LiteralObjectVar
|
||||||
|
|
||||||
|
if isinstance(value, EventSpec):
|
||||||
|
event_name = LiteralVar.create(
|
||||||
|
".".join(get_event_handler_parts(value.handler))
|
||||||
|
)
|
||||||
|
event_args = LiteralVar.create({name: value for name, value in value.args})
|
||||||
|
event_client_name = LiteralVar.create(value.client_handler_name)
|
||||||
|
return FunctionStringVar("Event").call(
|
||||||
|
event_name, event_args, event_client_name
|
||||||
|
)
|
||||||
|
|
||||||
|
if isinstance(value, EventChain):
|
||||||
|
sig = inspect.signature(value.args_spec) # type: ignore
|
||||||
|
if sig.parameters:
|
||||||
|
arg_def = tuple((f"_{p}" for p in sig.parameters))
|
||||||
|
arg_def_expr = LiteralVar.create(
|
||||||
|
[ImmutableVar.create_safe(arg) for arg in arg_def]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# add a default argument for addEvents if none were specified in value.args_spec
|
||||||
|
# used to trigger the preventDefault() on the event.
|
||||||
|
arg_def = ("...args",)
|
||||||
|
arg_def_expr = ImmutableVar.create_safe("args")
|
||||||
|
|
||||||
|
return ArgsFunctionOperation.create(
|
||||||
|
arg_def,
|
||||||
|
FunctionStringVar.create("addEvents").call(
|
||||||
|
LiteralVar.create(
|
||||||
|
[LiteralVar.create(event) for event in value.events]
|
||||||
|
),
|
||||||
|
arg_def_expr,
|
||||||
|
LiteralVar.create(value.event_actions),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
from plotly.graph_objects import Figure, layout
|
||||||
|
from plotly.io import to_json
|
||||||
|
|
||||||
|
if isinstance(value, Figure):
|
||||||
|
return LiteralObjectVar.create(
|
||||||
|
json.loads(to_json(value)), _var_type=Figure, _var_data=_var_data
|
||||||
|
)
|
||||||
|
|
||||||
|
if isinstance(value, layout.Template):
|
||||||
|
return LiteralObjectVar.create(
|
||||||
|
{
|
||||||
|
"data": json.loads(to_json(value.data)),
|
||||||
|
"layout": json.loads(to_json(value.layout)),
|
||||||
|
},
|
||||||
|
_var_type=layout.Template,
|
||||||
|
_var_data=_var_data,
|
||||||
|
)
|
||||||
|
|
||||||
if isinstance(value, Base):
|
if isinstance(value, Base):
|
||||||
return LiteralObjectVar(
|
return LiteralObjectVar.create(
|
||||||
value.dict(), _var_type=type(value), _var_data=_var_data
|
value.dict(), _var_type=type(value), _var_data=_var_data
|
||||||
)
|
)
|
||||||
|
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
return LiteralObjectVar(value, _var_data=_var_data)
|
return LiteralObjectVar.create(value, _var_data=_var_data)
|
||||||
|
|
||||||
from .number import LiteralBooleanVar, LiteralNumberVar
|
|
||||||
from .sequence import LiteralArrayVar, LiteralStringVar
|
from .sequence import LiteralArrayVar, LiteralStringVar
|
||||||
|
|
||||||
if isinstance(value, str):
|
if isinstance(value, str):
|
||||||
return LiteralStringVar.create(value, _var_data=_var_data)
|
return LiteralStringVar.create(value, _var_data=_var_data)
|
||||||
|
|
||||||
|
if isinstance(value, Color):
|
||||||
|
return LiteralStringVar.create(f"{value}", _var_data=_var_data)
|
||||||
|
|
||||||
|
from .number import LiteralBooleanVar, LiteralNumberVar
|
||||||
|
|
||||||
type_mapping = {
|
type_mapping = {
|
||||||
int: LiteralNumberVar,
|
int: LiteralNumberVar.create,
|
||||||
float: LiteralNumberVar,
|
float: LiteralNumberVar.create,
|
||||||
bool: LiteralBooleanVar,
|
bool: LiteralBooleanVar.create,
|
||||||
list: LiteralArrayVar,
|
list: LiteralArrayVar.create,
|
||||||
tuple: LiteralArrayVar,
|
tuple: LiteralArrayVar.create,
|
||||||
set: LiteralArrayVar,
|
set: LiteralArrayVar.create,
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor = type_mapping.get(type(value))
|
constructor = type_mapping.get(type(value))
|
||||||
|
|
||||||
if constructor is None:
|
if constructor is None:
|
||||||
raise TypeError(f"Unsupported type {type(value)} for LiteralVar.")
|
raise TypeError(
|
||||||
|
f"Unsupported type {type(value)} for LiteralVar. Tried to create a LiteralVar from {value}."
|
||||||
|
)
|
||||||
|
|
||||||
return constructor(value, _var_data=_var_data)
|
return constructor(value, _var_data=_var_data)
|
||||||
|
|
||||||
@ -881,27 +979,8 @@ class AndOperation(ImmutableVar):
|
|||||||
# The second var.
|
# The second var.
|
||||||
_var2: Var = dataclasses.field(default_factory=lambda: LiteralVar.create(None))
|
_var2: Var = dataclasses.field(default_factory=lambda: LiteralVar.create(None))
|
||||||
|
|
||||||
def __init__(
|
def __post_init__(self):
|
||||||
self, var1: Var | Any, var2: Var | Any, _var_data: VarData | None = None
|
"""Post-initialize the AndOperation."""
|
||||||
):
|
|
||||||
"""Initialize the AndOperation.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
var1: The first var.
|
|
||||||
var2: The second var.
|
|
||||||
_var_data: Additional hooks and imports associated with the Var.
|
|
||||||
"""
|
|
||||||
super(AndOperation, self).__init__(
|
|
||||||
_var_name="",
|
|
||||||
_var_type=Union[var1._var_type, var2._var_type],
|
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
|
||||||
)
|
|
||||||
object.__setattr__(
|
|
||||||
self, "_var1", var1 if isinstance(var1, Var) else LiteralVar.create(var1)
|
|
||||||
)
|
|
||||||
object.__setattr__(
|
|
||||||
self, "_var2", var2 if isinstance(var2, Var) else LiteralVar.create(var2)
|
|
||||||
)
|
|
||||||
object.__delattr__(self, "_var_name")
|
object.__delattr__(self, "_var_name")
|
||||||
|
|
||||||
@functools.cached_property
|
@functools.cached_property
|
||||||
@ -955,6 +1034,29 @@ class AndOperation(ImmutableVar):
|
|||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self._var1, self._var2))
|
return hash((self.__class__.__name__, self._var1, self._var2))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls, var1: Var | Any, var2: Var | Any, _var_data: VarData | None = None
|
||||||
|
) -> AndOperation:
|
||||||
|
"""Create an AndOperation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var1: The first var.
|
||||||
|
var2: The second var.
|
||||||
|
_var_data: Additional hooks and imports associated with the Var.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The AndOperation.
|
||||||
|
"""
|
||||||
|
var1, var2 = map(LiteralVar.create, (var1, var2))
|
||||||
|
return AndOperation(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=unionize(var1._var_type, var2._var_type),
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_var1=var1,
|
||||||
|
_var2=var2,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(
|
@dataclasses.dataclass(
|
||||||
eq=False,
|
eq=False,
|
||||||
@ -970,27 +1072,8 @@ class OrOperation(ImmutableVar):
|
|||||||
# The second var.
|
# The second var.
|
||||||
_var2: Var = dataclasses.field(default_factory=lambda: LiteralVar.create(None))
|
_var2: Var = dataclasses.field(default_factory=lambda: LiteralVar.create(None))
|
||||||
|
|
||||||
def __init__(
|
def __post_init__(self):
|
||||||
self, var1: Var | Any, var2: Var | Any, _var_data: VarData | None = None
|
"""Post-initialize the OrOperation."""
|
||||||
):
|
|
||||||
"""Initialize the OrOperation.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
var1: The first var.
|
|
||||||
var2: The second var.
|
|
||||||
_var_data: Additional hooks and imports associated with the Var.
|
|
||||||
"""
|
|
||||||
super(OrOperation, self).__init__(
|
|
||||||
_var_name="",
|
|
||||||
_var_type=Union[var1._var_type, var2._var_type],
|
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
|
||||||
)
|
|
||||||
object.__setattr__(
|
|
||||||
self, "_var1", var1 if isinstance(var1, Var) else LiteralVar.create(var1)
|
|
||||||
)
|
|
||||||
object.__setattr__(
|
|
||||||
self, "_var2", var2 if isinstance(var2, Var) else LiteralVar.create(var2)
|
|
||||||
)
|
|
||||||
object.__delattr__(self, "_var_name")
|
object.__delattr__(self, "_var_name")
|
||||||
|
|
||||||
@functools.cached_property
|
@functools.cached_property
|
||||||
@ -1044,6 +1127,29 @@ class OrOperation(ImmutableVar):
|
|||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self._var1, self._var2))
|
return hash((self.__class__.__name__, self._var1, self._var2))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls, var1: Var | Any, var2: Var | Any, _var_data: VarData | None = None
|
||||||
|
) -> OrOperation:
|
||||||
|
"""Create an OrOperation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
var1: The first var.
|
||||||
|
var2: The second var.
|
||||||
|
_var_data: Additional hooks and imports associated with the Var.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The OrOperation.
|
||||||
|
"""
|
||||||
|
var1, var2 = map(LiteralVar.create, (var1, var2))
|
||||||
|
return OrOperation(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=unionize(var1._var_type, var2._var_type),
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_var1=var1,
|
||||||
|
_var2=var2,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(
|
@dataclasses.dataclass(
|
||||||
eq=False,
|
eq=False,
|
||||||
@ -1057,14 +1163,14 @@ class ImmutableCallableVar(ImmutableVar):
|
|||||||
API with functions that return a family of Var.
|
API with functions that return a family of Var.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
fn: Callable[..., ImmutableVar] = dataclasses.field(
|
fn: Callable[..., Var] = dataclasses.field(
|
||||||
default_factory=lambda: lambda: LiteralVar.create(None)
|
default_factory=lambda: lambda: ImmutableVar(_var_name="undefined")
|
||||||
)
|
)
|
||||||
original_var: ImmutableVar = dataclasses.field(
|
original_var: Var = dataclasses.field(
|
||||||
default_factory=lambda: LiteralVar.create(None)
|
default_factory=lambda: ImmutableVar(_var_name="undefined")
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, fn: Callable[..., ImmutableVar]):
|
def __init__(self, fn: Callable[..., Var]):
|
||||||
"""Initialize a CallableVar.
|
"""Initialize a CallableVar.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1074,12 +1180,12 @@ class ImmutableCallableVar(ImmutableVar):
|
|||||||
super(ImmutableCallableVar, self).__init__(
|
super(ImmutableCallableVar, self).__init__(
|
||||||
_var_name=original_var._var_name,
|
_var_name=original_var._var_name,
|
||||||
_var_type=original_var._var_type,
|
_var_type=original_var._var_type,
|
||||||
_var_data=original_var._var_data,
|
_var_data=ImmutableVarData.merge(original_var._var_data),
|
||||||
)
|
)
|
||||||
object.__setattr__(self, "fn", fn)
|
object.__setattr__(self, "fn", fn)
|
||||||
object.__setattr__(self, "original_var", original_var)
|
object.__setattr__(self, "original_var", original_var)
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs) -> ImmutableVar:
|
def __call__(self, *args, **kwargs) -> Var:
|
||||||
"""Call the decorated function.
|
"""Call the decorated function.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1098,3 +1204,433 @@ class ImmutableCallableVar(ImmutableVar):
|
|||||||
The hash of the object.
|
The hash of the object.
|
||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self.original_var))
|
return hash((self.__class__.__name__, self.original_var))
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass(
|
||||||
|
eq=False,
|
||||||
|
frozen=True,
|
||||||
|
**{"slots": True} if sys.version_info >= (3, 10) else {},
|
||||||
|
)
|
||||||
|
class ImmutableComputedVar(ImmutableVar):
|
||||||
|
"""A field with computed getters."""
|
||||||
|
|
||||||
|
# Whether to track dependencies and cache computed values
|
||||||
|
_cache: bool = dataclasses.field(default=False)
|
||||||
|
|
||||||
|
# Whether the computed var is a backend var
|
||||||
|
_backend: bool = dataclasses.field(default=False)
|
||||||
|
|
||||||
|
# The initial value of the computed var
|
||||||
|
_initial_value: Any | types.Unset = dataclasses.field(default=types.Unset())
|
||||||
|
|
||||||
|
# Explicit var dependencies to track
|
||||||
|
_static_deps: set[str] = dataclasses.field(default_factory=set)
|
||||||
|
|
||||||
|
# Whether var dependencies should be auto-determined
|
||||||
|
_auto_deps: bool = dataclasses.field(default=True)
|
||||||
|
|
||||||
|
# Interval at which the computed var should be updated
|
||||||
|
_update_interval: Optional[datetime.timedelta] = dataclasses.field(default=None)
|
||||||
|
|
||||||
|
_fget: Callable[[BaseState], Any] = dataclasses.field(
|
||||||
|
default_factory=lambda: lambda _: None
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
fget: Callable[[BaseState], Any],
|
||||||
|
initial_value: Any | types.Unset = types.Unset(),
|
||||||
|
cache: bool = False,
|
||||||
|
deps: Optional[List[Union[str, Var]]] = None,
|
||||||
|
auto_deps: bool = True,
|
||||||
|
interval: Optional[Union[int, datetime.timedelta]] = None,
|
||||||
|
backend: bool | None = None,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
|
"""Initialize a ComputedVar.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
fget: The getter function.
|
||||||
|
initial_value: The initial value of the computed var.
|
||||||
|
cache: Whether to cache the computed value.
|
||||||
|
deps: Explicit var dependencies to track.
|
||||||
|
auto_deps: Whether var dependencies should be auto-determined.
|
||||||
|
interval: Interval at which the computed var should be updated.
|
||||||
|
backend: Whether the computed var is a backend var.
|
||||||
|
**kwargs: additional attributes to set on the instance
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
TypeError: If the computed var dependencies are not Var instances or var names.
|
||||||
|
"""
|
||||||
|
hints = get_type_hints(fget)
|
||||||
|
hint = hints.get("return", Any)
|
||||||
|
|
||||||
|
kwargs["_var_name"] = kwargs.pop("_var_name", fget.__name__)
|
||||||
|
kwargs["_var_type"] = kwargs.pop("_var_type", hint)
|
||||||
|
|
||||||
|
super(ImmutableComputedVar, self).__init__(
|
||||||
|
_var_name=kwargs.pop("_var_name"),
|
||||||
|
_var_type=kwargs.pop("_var_type"),
|
||||||
|
_var_data=ImmutableVarData.merge(kwargs.pop("_var_data", None)),
|
||||||
|
)
|
||||||
|
|
||||||
|
if backend is None:
|
||||||
|
backend = fget.__name__.startswith("_")
|
||||||
|
|
||||||
|
object.__setattr__(self, "_backend", backend)
|
||||||
|
object.__setattr__(self, "_initial_value", initial_value)
|
||||||
|
object.__setattr__(self, "_cache", cache)
|
||||||
|
|
||||||
|
if isinstance(interval, int):
|
||||||
|
interval = datetime.timedelta(seconds=interval)
|
||||||
|
|
||||||
|
object.__setattr__(self, "_update_interval", interval)
|
||||||
|
|
||||||
|
if deps is None:
|
||||||
|
deps = []
|
||||||
|
else:
|
||||||
|
for dep in deps:
|
||||||
|
if isinstance(dep, Var):
|
||||||
|
continue
|
||||||
|
if isinstance(dep, str) and dep != "":
|
||||||
|
continue
|
||||||
|
raise TypeError(
|
||||||
|
"ComputedVar dependencies must be Var instances or var names (non-empty strings)."
|
||||||
|
)
|
||||||
|
object.__setattr__(
|
||||||
|
self,
|
||||||
|
"_static_deps",
|
||||||
|
{dep._var_name if isinstance(dep, Var) else dep for dep in deps},
|
||||||
|
)
|
||||||
|
object.__setattr__(self, "_auto_deps", auto_deps)
|
||||||
|
|
||||||
|
object.__setattr__(self, "_fget", fget)
|
||||||
|
|
||||||
|
@override
|
||||||
|
def _replace(self, merge_var_data=None, **kwargs: Any) -> ImmutableComputedVar:
|
||||||
|
"""Replace the attributes of the ComputedVar.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
merge_var_data: VarData to merge into the existing VarData.
|
||||||
|
**kwargs: Var fields to update.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The new ComputedVar instance.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
TypeError: If kwargs contains keys that are not allowed.
|
||||||
|
"""
|
||||||
|
field_values = dict(
|
||||||
|
fget=kwargs.pop("fget", self._fget),
|
||||||
|
initial_value=kwargs.pop("initial_value", self._initial_value),
|
||||||
|
cache=kwargs.pop("cache", self._cache),
|
||||||
|
deps=kwargs.pop("deps", self._static_deps),
|
||||||
|
auto_deps=kwargs.pop("auto_deps", self._auto_deps),
|
||||||
|
interval=kwargs.pop("interval", self._update_interval),
|
||||||
|
backend=kwargs.pop("backend", self._backend),
|
||||||
|
_var_name=kwargs.pop("_var_name", self._var_name),
|
||||||
|
_var_type=kwargs.pop("_var_type", self._var_type),
|
||||||
|
_var_is_local=kwargs.pop("_var_is_local", self._var_is_local),
|
||||||
|
_var_is_string=kwargs.pop("_var_is_string", self._var_is_string),
|
||||||
|
_var_full_name_needs_state_prefix=kwargs.pop(
|
||||||
|
"_var_full_name_needs_state_prefix",
|
||||||
|
self._var_full_name_needs_state_prefix,
|
||||||
|
),
|
||||||
|
_var_data=kwargs.pop(
|
||||||
|
"_var_data", VarData.merge(self._var_data, merge_var_data)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if kwargs:
|
||||||
|
unexpected_kwargs = ", ".join(kwargs.keys())
|
||||||
|
raise TypeError(f"Unexpected keyword arguments: {unexpected_kwargs}")
|
||||||
|
|
||||||
|
return ImmutableComputedVar(**field_values)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _cache_attr(self) -> str:
|
||||||
|
"""Get the attribute used to cache the value on the instance.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
An attribute name.
|
||||||
|
"""
|
||||||
|
return f"__cached_{self._var_name}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _last_updated_attr(self) -> str:
|
||||||
|
"""Get the attribute used to store the last updated timestamp.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
An attribute name.
|
||||||
|
"""
|
||||||
|
return f"__last_updated_{self._var_name}"
|
||||||
|
|
||||||
|
def needs_update(self, instance: BaseState) -> bool:
|
||||||
|
"""Check if the computed var needs to be updated.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
instance: The state instance that the computed var is attached to.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if the computed var needs to be updated, False otherwise.
|
||||||
|
"""
|
||||||
|
if self._update_interval is None:
|
||||||
|
return False
|
||||||
|
last_updated = getattr(instance, self._last_updated_attr, None)
|
||||||
|
if last_updated is None:
|
||||||
|
return True
|
||||||
|
return datetime.datetime.now() - last_updated > self._update_interval
|
||||||
|
|
||||||
|
def __get__(self, instance: BaseState | None, owner):
|
||||||
|
"""Get the ComputedVar value.
|
||||||
|
|
||||||
|
If the value is already cached on the instance, return the cached value.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
instance: the instance of the class accessing this computed var.
|
||||||
|
owner: the class that this descriptor is attached to.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The value of the var for the given instance.
|
||||||
|
"""
|
||||||
|
if instance is None:
|
||||||
|
return self._replace(
|
||||||
|
_var_name=format_state_name(owner.get_full_name())
|
||||||
|
+ "."
|
||||||
|
+ self._var_name,
|
||||||
|
merge_var_data=ImmutableVarData.from_state(owner),
|
||||||
|
).guess_type()
|
||||||
|
|
||||||
|
if not self._cache:
|
||||||
|
return self.fget(instance)
|
||||||
|
|
||||||
|
# handle caching
|
||||||
|
if not hasattr(instance, self._cache_attr) or self.needs_update(instance):
|
||||||
|
# Set cache attr on state instance.
|
||||||
|
setattr(instance, self._cache_attr, self.fget(instance))
|
||||||
|
# Ensure the computed var gets serialized to redis.
|
||||||
|
instance._was_touched = True
|
||||||
|
# Set the last updated timestamp on the state instance.
|
||||||
|
setattr(instance, self._last_updated_attr, datetime.datetime.now())
|
||||||
|
return getattr(instance, self._cache_attr)
|
||||||
|
|
||||||
|
def _deps(
|
||||||
|
self,
|
||||||
|
objclass: Type,
|
||||||
|
obj: FunctionType | CodeType | None = None,
|
||||||
|
self_name: Optional[str] = None,
|
||||||
|
) -> set[str]:
|
||||||
|
"""Determine var dependencies of this ComputedVar.
|
||||||
|
|
||||||
|
Save references to attributes accessed on "self". Recursively called
|
||||||
|
when the function makes a method call on "self" or define comprehensions
|
||||||
|
or nested functions that may reference "self".
|
||||||
|
|
||||||
|
Args:
|
||||||
|
objclass: the class obj this ComputedVar is attached to.
|
||||||
|
obj: the object to disassemble (defaults to the fget function).
|
||||||
|
self_name: if specified, look for this name in LOAD_FAST and LOAD_DEREF instructions.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A set of variable names accessed by the given obj.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
VarValueError: if the function references the get_state, parent_state, or substates attributes
|
||||||
|
(cannot track deps in a related state, only implicitly via parent state).
|
||||||
|
"""
|
||||||
|
if not self._auto_deps:
|
||||||
|
return self._static_deps
|
||||||
|
d = self._static_deps.copy()
|
||||||
|
if obj is None:
|
||||||
|
fget = self._fget
|
||||||
|
if fget is not None:
|
||||||
|
obj = cast(FunctionType, fget)
|
||||||
|
else:
|
||||||
|
return set()
|
||||||
|
with contextlib.suppress(AttributeError):
|
||||||
|
# unbox functools.partial
|
||||||
|
obj = cast(FunctionType, obj.func) # type: ignore
|
||||||
|
with contextlib.suppress(AttributeError):
|
||||||
|
# unbox EventHandler
|
||||||
|
obj = cast(FunctionType, obj.fn) # type: ignore
|
||||||
|
|
||||||
|
if self_name is None and isinstance(obj, FunctionType):
|
||||||
|
try:
|
||||||
|
# the first argument to the function is the name of "self" arg
|
||||||
|
self_name = obj.__code__.co_varnames[0]
|
||||||
|
except (AttributeError, IndexError):
|
||||||
|
self_name = None
|
||||||
|
if self_name is None:
|
||||||
|
# cannot reference attributes on self if method takes no args
|
||||||
|
return set()
|
||||||
|
|
||||||
|
invalid_names = ["get_state", "parent_state", "substates", "get_substate"]
|
||||||
|
self_is_top_of_stack = False
|
||||||
|
for instruction in dis.get_instructions(obj):
|
||||||
|
if (
|
||||||
|
instruction.opname in ("LOAD_FAST", "LOAD_DEREF")
|
||||||
|
and instruction.argval == self_name
|
||||||
|
):
|
||||||
|
# bytecode loaded the class instance to the top of stack, next load instruction
|
||||||
|
# is referencing an attribute on self
|
||||||
|
self_is_top_of_stack = True
|
||||||
|
continue
|
||||||
|
if self_is_top_of_stack and instruction.opname in (
|
||||||
|
"LOAD_ATTR",
|
||||||
|
"LOAD_METHOD",
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
ref_obj = getattr(objclass, instruction.argval)
|
||||||
|
except Exception:
|
||||||
|
ref_obj = None
|
||||||
|
if instruction.argval in invalid_names:
|
||||||
|
raise VarValueError(
|
||||||
|
f"Cached var {self._var_full_name} cannot access arbitrary state via `{instruction.argval}`."
|
||||||
|
)
|
||||||
|
if callable(ref_obj):
|
||||||
|
# recurse into callable attributes
|
||||||
|
d.update(
|
||||||
|
self._deps(
|
||||||
|
objclass=objclass,
|
||||||
|
obj=ref_obj,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# recurse into property fget functions
|
||||||
|
elif isinstance(ref_obj, property) and not isinstance(
|
||||||
|
ref_obj, ImmutableComputedVar
|
||||||
|
):
|
||||||
|
d.update(
|
||||||
|
self._deps(
|
||||||
|
objclass=objclass,
|
||||||
|
obj=ref_obj.fget, # type: ignore
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif (
|
||||||
|
instruction.argval in objclass.backend_vars
|
||||||
|
or instruction.argval in objclass.vars
|
||||||
|
):
|
||||||
|
# var access
|
||||||
|
d.add(instruction.argval)
|
||||||
|
elif instruction.opname == "LOAD_CONST" and isinstance(
|
||||||
|
instruction.argval, CodeType
|
||||||
|
):
|
||||||
|
# recurse into nested functions / comprehensions, which can reference
|
||||||
|
# instance attributes from the outer scope
|
||||||
|
d.update(
|
||||||
|
self._deps(
|
||||||
|
objclass=objclass,
|
||||||
|
obj=instruction.argval,
|
||||||
|
self_name=self_name,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self_is_top_of_stack = False
|
||||||
|
return d
|
||||||
|
|
||||||
|
def mark_dirty(self, instance) -> None:
|
||||||
|
"""Mark this ComputedVar as dirty.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
instance: the state instance that needs to recompute the value.
|
||||||
|
"""
|
||||||
|
with contextlib.suppress(AttributeError):
|
||||||
|
delattr(instance, self._cache_attr)
|
||||||
|
|
||||||
|
def _determine_var_type(self) -> Type:
|
||||||
|
"""Get the type of the var.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The type of the var.
|
||||||
|
"""
|
||||||
|
hints = get_type_hints(self._fget)
|
||||||
|
if "return" in hints:
|
||||||
|
return hints["return"]
|
||||||
|
return Any
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __class__(self) -> Type:
|
||||||
|
"""Get the class of the var.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The class of the var.
|
||||||
|
"""
|
||||||
|
return ComputedVar
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fget(self) -> Callable[[BaseState], Any]:
|
||||||
|
"""Get the getter function.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The getter function.
|
||||||
|
"""
|
||||||
|
return self._fget
|
||||||
|
|
||||||
|
|
||||||
|
def immutable_computed_var(
|
||||||
|
fget: Callable[[BaseState], Any] | None = None,
|
||||||
|
initial_value: Any | types.Unset = types.Unset(),
|
||||||
|
cache: bool = False,
|
||||||
|
deps: Optional[List[Union[str, Var]]] = None,
|
||||||
|
auto_deps: bool = True,
|
||||||
|
interval: Optional[Union[datetime.timedelta, int]] = None,
|
||||||
|
backend: bool | None = None,
|
||||||
|
_deprecated_cached_var: bool = False,
|
||||||
|
**kwargs,
|
||||||
|
) -> (
|
||||||
|
ImmutableComputedVar | Callable[[Callable[[BaseState], Any]], ImmutableComputedVar]
|
||||||
|
):
|
||||||
|
"""A ComputedVar decorator with or without kwargs.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
fget: The getter function.
|
||||||
|
initial_value: The initial value of the computed var.
|
||||||
|
cache: Whether to cache the computed value.
|
||||||
|
deps: Explicit var dependencies to track.
|
||||||
|
auto_deps: Whether var dependencies should be auto-determined.
|
||||||
|
interval: Interval at which the computed var should be updated.
|
||||||
|
backend: Whether the computed var is a backend var.
|
||||||
|
_deprecated_cached_var: Indicate usage of deprecated cached_var partial function.
|
||||||
|
**kwargs: additional attributes to set on the instance
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A ComputedVar instance.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If caching is disabled and an update interval is set.
|
||||||
|
VarDependencyError: If user supplies dependencies without caching.
|
||||||
|
"""
|
||||||
|
if _deprecated_cached_var:
|
||||||
|
console.deprecate(
|
||||||
|
feature_name="cached_var",
|
||||||
|
reason=("Use @rx.var(cache=True) instead of @rx.cached_var."),
|
||||||
|
deprecation_version="0.5.6",
|
||||||
|
removal_version="0.6.0",
|
||||||
|
)
|
||||||
|
|
||||||
|
if cache is False and interval is not None:
|
||||||
|
raise ValueError("Cannot set update interval without caching.")
|
||||||
|
|
||||||
|
if cache is False and (deps is not None or auto_deps is False):
|
||||||
|
raise VarDependencyError("Cannot track dependencies without caching.")
|
||||||
|
|
||||||
|
if fget is not None:
|
||||||
|
return ImmutableComputedVar(fget, cache=cache)
|
||||||
|
|
||||||
|
def wrapper(fget: Callable[[BaseState], Any]) -> ImmutableComputedVar:
|
||||||
|
return ImmutableComputedVar(
|
||||||
|
fget,
|
||||||
|
initial_value=initial_value,
|
||||||
|
cache=cache,
|
||||||
|
deps=deps,
|
||||||
|
auto_deps=auto_deps,
|
||||||
|
interval=interval,
|
||||||
|
backend=backend,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
# Partial function of computed_var with cache=True
|
||||||
|
cached_var = functools.partial(
|
||||||
|
immutable_computed_var, cache=True, _deprecated_cached_var=True
|
||||||
|
)
|
||||||
|
@ -7,6 +7,7 @@ import sys
|
|||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from typing import Any, Callable, Optional, Tuple, Type, Union
|
from typing import Any, Callable, Optional, Tuple, Type, Union
|
||||||
|
|
||||||
|
from reflex.utils.types import GenericType
|
||||||
from reflex.vars import ImmutableVarData, Var, VarData
|
from reflex.vars import ImmutableVarData, Var, VarData
|
||||||
|
|
||||||
from .base import ImmutableVar, LiteralVar
|
from .base import ImmutableVar, LiteralVar
|
||||||
@ -24,9 +25,9 @@ class FunctionVar(ImmutableVar[Callable]):
|
|||||||
Returns:
|
Returns:
|
||||||
The function call operation.
|
The function call operation.
|
||||||
"""
|
"""
|
||||||
return ArgsFunctionOperation(
|
return ArgsFunctionOperation.create(
|
||||||
("...args",),
|
("...args",),
|
||||||
VarOperationCall(self, *args, ImmutableVar.create_safe("...args")),
|
VarOperationCall.create(self, *args, ImmutableVar.create_safe("...args")),
|
||||||
)
|
)
|
||||||
|
|
||||||
def call(self, *args: Var | Any) -> VarOperationCall:
|
def call(self, *args: Var | Any) -> VarOperationCall:
|
||||||
@ -38,22 +39,31 @@ class FunctionVar(ImmutableVar[Callable]):
|
|||||||
Returns:
|
Returns:
|
||||||
The function call operation.
|
The function call operation.
|
||||||
"""
|
"""
|
||||||
return VarOperationCall(self, *args)
|
return VarOperationCall.create(self, *args)
|
||||||
|
|
||||||
|
|
||||||
class FunctionStringVar(FunctionVar):
|
class FunctionStringVar(FunctionVar):
|
||||||
"""Base class for immutable function vars from a string."""
|
"""Base class for immutable function vars from a string."""
|
||||||
|
|
||||||
def __init__(self, func: str, _var_data: VarData | None = None) -> None:
|
@classmethod
|
||||||
"""Initialize the function var.
|
def create(
|
||||||
|
cls,
|
||||||
|
func: str,
|
||||||
|
_var_type: Type[Callable] = Callable,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> FunctionStringVar:
|
||||||
|
"""Create a new function var from a string.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
func: The function to call.
|
func: The function to call.
|
||||||
_var_data: Additional hooks and imports associated with the Var.
|
_var_data: Additional hooks and imports associated with the Var.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The function var.
|
||||||
"""
|
"""
|
||||||
super(FunctionVar, self).__init__(
|
return cls(
|
||||||
_var_name=func,
|
_var_name=func,
|
||||||
_var_type=Callable,
|
_var_type=_var_type,
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -69,25 +79,6 @@ class VarOperationCall(ImmutableVar):
|
|||||||
_func: Optional[FunctionVar] = dataclasses.field(default=None)
|
_func: Optional[FunctionVar] = dataclasses.field(default=None)
|
||||||
_args: Tuple[Union[Var, Any], ...] = dataclasses.field(default_factory=tuple)
|
_args: Tuple[Union[Var, Any], ...] = dataclasses.field(default_factory=tuple)
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, func: FunctionVar, *args: Var | Any, _var_data: VarData | None = None
|
|
||||||
):
|
|
||||||
"""Initialize the function call var.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
func: The function to call.
|
|
||||||
*args: The arguments to call the function with.
|
|
||||||
_var_data: Additional hooks and imports associated with the Var.
|
|
||||||
"""
|
|
||||||
super(VarOperationCall, self).__init__(
|
|
||||||
_var_name="",
|
|
||||||
_var_type=Any,
|
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
|
||||||
)
|
|
||||||
object.__setattr__(self, "_func", func)
|
|
||||||
object.__setattr__(self, "_args", args)
|
|
||||||
object.__delattr__(self, "_var_name")
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
"""Get an attribute of the var.
|
"""Get an attribute of the var.
|
||||||
|
|
||||||
@ -133,7 +124,7 @@ class VarOperationCall(ImmutableVar):
|
|||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
"""Post-initialize the var."""
|
"""Post-initialize the var."""
|
||||||
pass
|
object.__delattr__(self, "_var_name")
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
"""Hash the var.
|
"""Hash the var.
|
||||||
@ -143,6 +134,32 @@ class VarOperationCall(ImmutableVar):
|
|||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self._func, self._args))
|
return hash((self.__class__.__name__, self._func, self._args))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
func: FunctionVar,
|
||||||
|
*args: Var | Any,
|
||||||
|
_var_type: GenericType = Any,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> VarOperationCall:
|
||||||
|
"""Create a new function call var.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
func: The function to call.
|
||||||
|
*args: The arguments to call the function with.
|
||||||
|
_var_data: Additional hooks and imports associated with the Var.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The function call var.
|
||||||
|
"""
|
||||||
|
return cls(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=_var_type,
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_func=func,
|
||||||
|
_args=args,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(
|
@dataclasses.dataclass(
|
||||||
eq=False,
|
eq=False,
|
||||||
@ -155,28 +172,6 @@ class ArgsFunctionOperation(FunctionVar):
|
|||||||
_args_names: Tuple[str, ...] = dataclasses.field(default_factory=tuple)
|
_args_names: Tuple[str, ...] = dataclasses.field(default_factory=tuple)
|
||||||
_return_expr: Union[Var, Any] = dataclasses.field(default=None)
|
_return_expr: Union[Var, Any] = dataclasses.field(default=None)
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
args_names: Tuple[str, ...],
|
|
||||||
return_expr: Var | Any,
|
|
||||||
_var_data: VarData | None = None,
|
|
||||||
) -> None:
|
|
||||||
"""Initialize the function with arguments var.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
args_names: The names of the arguments.
|
|
||||||
return_expr: The return expression of the function.
|
|
||||||
_var_data: Additional hooks and imports associated with the Var.
|
|
||||||
"""
|
|
||||||
super(ArgsFunctionOperation, self).__init__(
|
|
||||||
_var_name=f"",
|
|
||||||
_var_type=Callable,
|
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
|
||||||
)
|
|
||||||
object.__setattr__(self, "_args_names", args_names)
|
|
||||||
object.__setattr__(self, "_return_expr", return_expr)
|
|
||||||
object.__delattr__(self, "_var_name")
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
"""Get an attribute of the var.
|
"""Get an attribute of the var.
|
||||||
|
|
||||||
@ -221,6 +216,7 @@ class ArgsFunctionOperation(FunctionVar):
|
|||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
"""Post-initialize the var."""
|
"""Post-initialize the var."""
|
||||||
|
object.__delattr__(self, "_var_name")
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
"""Hash the var.
|
"""Hash the var.
|
||||||
@ -230,6 +226,32 @@ class ArgsFunctionOperation(FunctionVar):
|
|||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self._args_names, self._return_expr))
|
return hash((self.__class__.__name__, self._args_names, self._return_expr))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
args_names: Tuple[str, ...],
|
||||||
|
return_expr: Var | Any,
|
||||||
|
_var_type: GenericType = Callable,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> ArgsFunctionOperation:
|
||||||
|
"""Create a new function var.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
args_names: The names of the arguments.
|
||||||
|
return_expr: The return expression of the function.
|
||||||
|
_var_data: Additional hooks and imports associated with the Var.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The function var.
|
||||||
|
"""
|
||||||
|
return cls(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=_var_type,
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_args_names=args_names,
|
||||||
|
_return_expr=return_expr,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(
|
@dataclasses.dataclass(
|
||||||
eq=False,
|
eq=False,
|
||||||
@ -243,25 +265,8 @@ class ToFunctionOperation(FunctionVar):
|
|||||||
default_factory=lambda: LiteralVar.create(None)
|
default_factory=lambda: LiteralVar.create(None)
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(
|
def __post_init__(self):
|
||||||
self,
|
"""Post-initialize the var."""
|
||||||
original_var: Var,
|
|
||||||
_var_type: Type[Callable] = Callable,
|
|
||||||
_var_data: VarData | None = None,
|
|
||||||
) -> None:
|
|
||||||
"""Initialize the function with arguments var.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
original_var: The original var to convert to a function.
|
|
||||||
_var_type: The type of the function.
|
|
||||||
_var_data: Additional hooks and imports associated with the Var.
|
|
||||||
"""
|
|
||||||
super(ToFunctionOperation, self).__init__(
|
|
||||||
_var_name=f"",
|
|
||||||
_var_type=_var_type,
|
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
|
||||||
)
|
|
||||||
object.__setattr__(self, "_original_var", original_var)
|
|
||||||
object.__delattr__(self, "_var_name")
|
object.__delattr__(self, "_var_name")
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
@ -314,5 +319,29 @@ class ToFunctionOperation(FunctionVar):
|
|||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self._original_var))
|
return hash((self.__class__.__name__, self._original_var))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
original_var: Var,
|
||||||
|
_var_type: GenericType = Callable,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> ToFunctionOperation:
|
||||||
|
"""Create a new function var.
|
||||||
|
|
||||||
JSON_STRINGIFY = FunctionStringVar("JSON.stringify")
|
Args:
|
||||||
|
original_var: The original var to convert to a function.
|
||||||
|
_var_type: The type of the function.
|
||||||
|
_var_data: Additional hooks and imports associated with the Var.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The function var.
|
||||||
|
"""
|
||||||
|
return cls(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=_var_type,
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_original_var=original_var,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
JSON_STRINGIFY = FunctionStringVar.create("JSON.stringify")
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,7 @@ from .base import (
|
|||||||
from .number import BooleanVar, NumberVar
|
from .number import BooleanVar, NumberVar
|
||||||
from .sequence import ArrayVar, StringVar
|
from .sequence import ArrayVar, StringVar
|
||||||
|
|
||||||
OBJECT_TYPE = TypeVar("OBJECT_TYPE")
|
OBJECT_TYPE = TypeVar("OBJECT_TYPE", bound=Dict)
|
||||||
|
|
||||||
KEY_TYPE = TypeVar("KEY_TYPE")
|
KEY_TYPE = TypeVar("KEY_TYPE")
|
||||||
VALUE_TYPE = TypeVar("VALUE_TYPE")
|
VALUE_TYPE = TypeVar("VALUE_TYPE")
|
||||||
@ -79,7 +79,7 @@ class ObjectVar(ImmutableVar[OBJECT_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
The keys of the object.
|
The keys of the object.
|
||||||
"""
|
"""
|
||||||
return ObjectKeysOperation(self)
|
return ObjectKeysOperation.create(self)
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def values(
|
def values(
|
||||||
@ -95,7 +95,7 @@ class ObjectVar(ImmutableVar[OBJECT_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
The values of the object.
|
The values of the object.
|
||||||
"""
|
"""
|
||||||
return ObjectValuesOperation(self)
|
return ObjectValuesOperation.create(self)
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def entries(
|
def entries(
|
||||||
@ -111,7 +111,7 @@ class ObjectVar(ImmutableVar[OBJECT_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
The entries of the object.
|
The entries of the object.
|
||||||
"""
|
"""
|
||||||
return ObjectEntriesOperation(self)
|
return ObjectEntriesOperation.create(self)
|
||||||
|
|
||||||
def merge(self, other: ObjectVar) -> ObjectMergeOperation:
|
def merge(self, other: ObjectVar) -> ObjectMergeOperation:
|
||||||
"""Merge two objects.
|
"""Merge two objects.
|
||||||
@ -122,7 +122,7 @@ class ObjectVar(ImmutableVar[OBJECT_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
The merged object.
|
The merged object.
|
||||||
"""
|
"""
|
||||||
return ObjectMergeOperation(self, other)
|
return ObjectMergeOperation.create(self, other)
|
||||||
|
|
||||||
# NoReturn is used here to catch when key value is Any
|
# NoReturn is used here to catch when key value is Any
|
||||||
@overload
|
@overload
|
||||||
@ -180,7 +180,7 @@ class ObjectVar(ImmutableVar[OBJECT_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
The item from the object.
|
The item from the object.
|
||||||
"""
|
"""
|
||||||
return ObjectItemOperation(self, key).guess_type()
|
return ObjectItemOperation.create(self, key).guess_type()
|
||||||
|
|
||||||
# NoReturn is used here to catch when key value is Any
|
# NoReturn is used here to catch when key value is Any
|
||||||
@overload
|
@overload
|
||||||
@ -253,9 +253,9 @@ class ObjectVar(ImmutableVar[OBJECT_TYPE]):
|
|||||||
f"The State var `{self._var_name}` has no attribute '{name}' or may have been annotated "
|
f"The State var `{self._var_name}` has no attribute '{name}' or may have been annotated "
|
||||||
f"wrongly."
|
f"wrongly."
|
||||||
)
|
)
|
||||||
return ObjectItemOperation(self, name, attribute_type).guess_type()
|
return ObjectItemOperation.create(self, name, attribute_type).guess_type()
|
||||||
else:
|
else:
|
||||||
return ObjectItemOperation(self, name).guess_type()
|
return ObjectItemOperation.create(self, name).guess_type()
|
||||||
|
|
||||||
def contains(self, key: Var | Any) -> BooleanVar:
|
def contains(self, key: Var | Any) -> BooleanVar:
|
||||||
"""Check if the object contains a key.
|
"""Check if the object contains a key.
|
||||||
@ -266,7 +266,7 @@ class ObjectVar(ImmutableVar[OBJECT_TYPE]):
|
|||||||
Returns:
|
Returns:
|
||||||
The result of the check.
|
The result of the check.
|
||||||
"""
|
"""
|
||||||
return ObjectHasOwnProperty(self, key)
|
return ObjectHasOwnProperty.create(self, key)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(
|
@dataclasses.dataclass(
|
||||||
@ -281,29 +281,8 @@ class LiteralObjectVar(LiteralVar, ObjectVar[OBJECT_TYPE]):
|
|||||||
default_factory=dict
|
default_factory=dict
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(
|
def __post_init__(self):
|
||||||
self: LiteralObjectVar[OBJECT_TYPE],
|
"""Post initialization."""
|
||||||
_var_value: OBJECT_TYPE,
|
|
||||||
_var_type: Type[OBJECT_TYPE] | None = None,
|
|
||||||
_var_data: VarData | None = None,
|
|
||||||
):
|
|
||||||
"""Initialize the object var.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
_var_value: The value of the var.
|
|
||||||
_var_type: The type of the var.
|
|
||||||
_var_data: Additional hooks and imports associated with the Var.
|
|
||||||
"""
|
|
||||||
super(LiteralObjectVar, self).__init__(
|
|
||||||
_var_name="",
|
|
||||||
_var_type=(figure_out_type(_var_value) if _var_type is None else _var_type),
|
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
|
||||||
)
|
|
||||||
object.__setattr__(
|
|
||||||
self,
|
|
||||||
"_var_value",
|
|
||||||
_var_value,
|
|
||||||
)
|
|
||||||
object.__delattr__(self, "_var_name")
|
object.__delattr__(self, "_var_name")
|
||||||
|
|
||||||
def _key_type(self) -> Type:
|
def _key_type(self) -> Type:
|
||||||
@ -409,6 +388,30 @@ class LiteralObjectVar(LiteralVar, ObjectVar[OBJECT_TYPE]):
|
|||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self._var_name))
|
return hash((self.__class__.__name__, self._var_name))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
_var_value: OBJECT_TYPE,
|
||||||
|
_var_type: GenericType | None = None,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> LiteralObjectVar[OBJECT_TYPE]:
|
||||||
|
"""Create the literal object var.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
_var_value: The value of the var.
|
||||||
|
_var_type: The type of the var.
|
||||||
|
_var_data: Additional hooks and imports associated with the Var.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The literal object var.
|
||||||
|
"""
|
||||||
|
return LiteralObjectVar(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=(figure_out_type(_var_value) if _var_type is None else _var_type),
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_var_value=_var_value,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(
|
@dataclasses.dataclass(
|
||||||
eq=False,
|
eq=False,
|
||||||
@ -418,26 +421,12 @@ class LiteralObjectVar(LiteralVar, ObjectVar[OBJECT_TYPE]):
|
|||||||
class ObjectToArrayOperation(ArrayVar):
|
class ObjectToArrayOperation(ArrayVar):
|
||||||
"""Base class for object to array operations."""
|
"""Base class for object to array operations."""
|
||||||
|
|
||||||
value: ObjectVar = dataclasses.field(default_factory=lambda: LiteralObjectVar({}))
|
_value: ObjectVar = dataclasses.field(
|
||||||
|
default_factory=lambda: LiteralObjectVar.create({})
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(
|
def __post_init__(self):
|
||||||
self,
|
"""Post initialization."""
|
||||||
_var_value: ObjectVar,
|
|
||||||
_var_type: Type = list,
|
|
||||||
_var_data: VarData | None = None,
|
|
||||||
):
|
|
||||||
"""Initialize the object to array operation.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
_var_value: The value of the operation.
|
|
||||||
_var_data: Additional hooks and imports associated with the operation.
|
|
||||||
"""
|
|
||||||
super(ObjectToArrayOperation, self).__init__(
|
|
||||||
_var_name="",
|
|
||||||
_var_type=_var_type,
|
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
|
||||||
)
|
|
||||||
object.__setattr__(self, "value", _var_value)
|
|
||||||
object.__delattr__(self, "_var_name")
|
object.__delattr__(self, "_var_name")
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
@ -472,7 +461,7 @@ class ObjectToArrayOperation(ArrayVar):
|
|||||||
The VarData of the components and all of its children.
|
The VarData of the components and all of its children.
|
||||||
"""
|
"""
|
||||||
return ImmutableVarData.merge(
|
return ImmutableVarData.merge(
|
||||||
self.value._get_all_var_data(),
|
self._value._get_all_var_data(),
|
||||||
self._var_data,
|
self._var_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -490,26 +479,37 @@ class ObjectToArrayOperation(ArrayVar):
|
|||||||
Returns:
|
Returns:
|
||||||
The hash of the operation.
|
The hash of the operation.
|
||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self.value))
|
return hash((self.__class__.__name__, self._value))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
value: ObjectVar,
|
||||||
|
_var_type: GenericType | None = None,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> ObjectToArrayOperation:
|
||||||
|
"""Create the object to array operation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value: The value of the operation.
|
||||||
|
_var_data: Additional hooks and imports associated with the operation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The object to array operation.
|
||||||
|
"""
|
||||||
|
return cls(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=list if _var_type is None else _var_type,
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_value=value,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ObjectKeysOperation(ObjectToArrayOperation):
|
class ObjectKeysOperation(ObjectToArrayOperation):
|
||||||
"""Operation to get the keys of an object."""
|
"""Operation to get the keys of an object."""
|
||||||
|
|
||||||
def __init__(
|
# value, List[value._key_type()], _var_data
|
||||||
self,
|
# )
|
||||||
value: ObjectVar,
|
|
||||||
_var_data: VarData | None = None,
|
|
||||||
):
|
|
||||||
"""Initialize the object keys operation.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value: The value of the operation.
|
|
||||||
_var_data: Additional hooks and imports associated with the operation.
|
|
||||||
"""
|
|
||||||
super(ObjectKeysOperation, self).__init__(
|
|
||||||
value, List[value._key_type()], _var_data
|
|
||||||
)
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def _cached_var_name(self) -> str:
|
def _cached_var_name(self) -> str:
|
||||||
@ -518,27 +518,34 @@ class ObjectKeysOperation(ObjectToArrayOperation):
|
|||||||
Returns:
|
Returns:
|
||||||
The name of the operation.
|
The name of the operation.
|
||||||
"""
|
"""
|
||||||
return f"Object.keys({self.value._var_name})"
|
return f"Object.keys({str(self._value)})"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
value: ObjectVar,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> ObjectKeysOperation:
|
||||||
|
"""Create the object keys operation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value: The value of the operation.
|
||||||
|
_var_data: Additional hooks and imports associated with the operation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The object keys operation.
|
||||||
|
"""
|
||||||
|
return cls(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=List[str],
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_value=value,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ObjectValuesOperation(ObjectToArrayOperation):
|
class ObjectValuesOperation(ObjectToArrayOperation):
|
||||||
"""Operation to get the values of an object."""
|
"""Operation to get the values of an object."""
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
value: ObjectVar,
|
|
||||||
_var_data: VarData | None = None,
|
|
||||||
):
|
|
||||||
"""Initialize the object values operation.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value: The value of the operation.
|
|
||||||
_var_data: Additional hooks and imports associated with the operation.
|
|
||||||
"""
|
|
||||||
super(ObjectValuesOperation, self).__init__(
|
|
||||||
value, List[value._value_type()], _var_data
|
|
||||||
)
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def _cached_var_name(self) -> str:
|
def _cached_var_name(self) -> str:
|
||||||
"""The name of the operation.
|
"""The name of the operation.
|
||||||
@ -546,27 +553,34 @@ class ObjectValuesOperation(ObjectToArrayOperation):
|
|||||||
Returns:
|
Returns:
|
||||||
The name of the operation.
|
The name of the operation.
|
||||||
"""
|
"""
|
||||||
return f"Object.values({self.value._var_name})"
|
return f"Object.values({self._value._var_name})"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
value: ObjectVar,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> ObjectValuesOperation:
|
||||||
|
"""Create the object values operation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value: The value of the operation.
|
||||||
|
_var_data: Additional hooks and imports associated with the operation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The object values operation.
|
||||||
|
"""
|
||||||
|
return cls(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=List[value._value_type()],
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_value=value,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ObjectEntriesOperation(ObjectToArrayOperation):
|
class ObjectEntriesOperation(ObjectToArrayOperation):
|
||||||
"""Operation to get the entries of an object."""
|
"""Operation to get the entries of an object."""
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
value: ObjectVar,
|
|
||||||
_var_data: VarData | None = None,
|
|
||||||
):
|
|
||||||
"""Initialize the object entries operation.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value: The value of the operation.
|
|
||||||
_var_data: Additional hooks and imports associated with the operation.
|
|
||||||
"""
|
|
||||||
super(ObjectEntriesOperation, self).__init__(
|
|
||||||
value, List[Tuple[value._key_type(), value._value_type()]], _var_data
|
|
||||||
)
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def _cached_var_name(self) -> str:
|
def _cached_var_name(self) -> str:
|
||||||
"""The name of the operation.
|
"""The name of the operation.
|
||||||
@ -574,7 +588,29 @@ class ObjectEntriesOperation(ObjectToArrayOperation):
|
|||||||
Returns:
|
Returns:
|
||||||
The name of the operation.
|
The name of the operation.
|
||||||
"""
|
"""
|
||||||
return f"Object.entries({self.value._var_name})"
|
return f"Object.entries({self._value._var_name})"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
value: ObjectVar,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> ObjectEntriesOperation:
|
||||||
|
"""Create the object entries operation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value: The value of the operation.
|
||||||
|
_var_data: Additional hooks and imports associated with the operation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The object entries operation.
|
||||||
|
"""
|
||||||
|
return cls(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=List[Tuple[str, value._value_type()]],
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_value=value,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(
|
@dataclasses.dataclass(
|
||||||
@ -585,30 +621,12 @@ class ObjectEntriesOperation(ObjectToArrayOperation):
|
|||||||
class ObjectMergeOperation(ObjectVar):
|
class ObjectMergeOperation(ObjectVar):
|
||||||
"""Operation to merge two objects."""
|
"""Operation to merge two objects."""
|
||||||
|
|
||||||
left: ObjectVar = dataclasses.field(default_factory=lambda: LiteralObjectVar({}))
|
_lhs: ObjectVar = dataclasses.field(
|
||||||
right: ObjectVar = dataclasses.field(default_factory=lambda: LiteralObjectVar({}))
|
default_factory=lambda: LiteralObjectVar.create({})
|
||||||
|
)
|
||||||
def __init__(
|
_rhs: ObjectVar = dataclasses.field(
|
||||||
self,
|
default_factory=lambda: LiteralObjectVar.create({})
|
||||||
left: ObjectVar,
|
)
|
||||||
right: ObjectVar,
|
|
||||||
_var_data: VarData | None = None,
|
|
||||||
):
|
|
||||||
"""Initialize the object merge operation.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
left: The left object to merge.
|
|
||||||
right: The right object to merge.
|
|
||||||
_var_data: Additional hooks and imports associated with the operation.
|
|
||||||
"""
|
|
||||||
super(ObjectMergeOperation, self).__init__(
|
|
||||||
_var_name="",
|
|
||||||
_var_type=left._var_type,
|
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
|
||||||
)
|
|
||||||
object.__setattr__(self, "left", left)
|
|
||||||
object.__setattr__(self, "right", right)
|
|
||||||
object.__delattr__(self, "_var_name")
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def _cached_var_name(self) -> str:
|
def _cached_var_name(self) -> str:
|
||||||
@ -617,7 +635,7 @@ class ObjectMergeOperation(ObjectVar):
|
|||||||
Returns:
|
Returns:
|
||||||
The name of the operation.
|
The name of the operation.
|
||||||
"""
|
"""
|
||||||
return f"Object.assign({self.left._var_name}, {self.right._var_name})"
|
return f"Object.assign({self._lhs._var_name}, {self._rhs._var_name})"
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
"""Get an attribute of the operation.
|
"""Get an attribute of the operation.
|
||||||
@ -640,8 +658,8 @@ class ObjectMergeOperation(ObjectVar):
|
|||||||
The VarData of the components and all of its children.
|
The VarData of the components and all of its children.
|
||||||
"""
|
"""
|
||||||
return ImmutableVarData.merge(
|
return ImmutableVarData.merge(
|
||||||
self.left._get_all_var_data(),
|
self._lhs._get_all_var_data(),
|
||||||
self.right._get_all_var_data(),
|
self._rhs._get_all_var_data(),
|
||||||
self._var_data,
|
self._var_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -659,7 +677,33 @@ class ObjectMergeOperation(ObjectVar):
|
|||||||
Returns:
|
Returns:
|
||||||
The hash of the operation.
|
The hash of the operation.
|
||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self.left, self.right))
|
return hash((self.__class__.__name__, self._lhs, self._rhs))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
lhs: ObjectVar,
|
||||||
|
rhs: ObjectVar,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> ObjectMergeOperation:
|
||||||
|
"""Create the object merge operation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
lhs: The left object to merge.
|
||||||
|
rhs: The right object to merge.
|
||||||
|
_var_data: Additional hooks and imports associated with the operation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The object merge operation.
|
||||||
|
"""
|
||||||
|
# TODO: Figure out how to merge the types
|
||||||
|
return cls(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=lhs._var_type,
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_lhs=lhs,
|
||||||
|
_rhs=rhs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(
|
@dataclasses.dataclass(
|
||||||
@ -670,33 +714,10 @@ class ObjectMergeOperation(ObjectVar):
|
|||||||
class ObjectItemOperation(ImmutableVar):
|
class ObjectItemOperation(ImmutableVar):
|
||||||
"""Operation to get an item from an object."""
|
"""Operation to get an item from an object."""
|
||||||
|
|
||||||
value: ObjectVar = dataclasses.field(default_factory=lambda: LiteralObjectVar({}))
|
_object: ObjectVar = dataclasses.field(
|
||||||
key: Var | Any = dataclasses.field(default_factory=lambda: LiteralVar.create(None))
|
default_factory=lambda: LiteralObjectVar.create({})
|
||||||
|
)
|
||||||
def __init__(
|
_key: Var | Any = dataclasses.field(default_factory=lambda: LiteralVar.create(None))
|
||||||
self,
|
|
||||||
value: ObjectVar,
|
|
||||||
key: Var | Any,
|
|
||||||
_var_type: GenericType | None = None,
|
|
||||||
_var_data: VarData | None = None,
|
|
||||||
):
|
|
||||||
"""Initialize the object item operation.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value: The value of the operation.
|
|
||||||
key: The key to get from the object.
|
|
||||||
_var_data: Additional hooks and imports associated with the operation.
|
|
||||||
"""
|
|
||||||
super(ObjectItemOperation, self).__init__(
|
|
||||||
_var_name="",
|
|
||||||
_var_type=value._value_type() if _var_type is None else _var_type,
|
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
|
||||||
)
|
|
||||||
object.__setattr__(self, "value", value)
|
|
||||||
object.__setattr__(
|
|
||||||
self, "key", key if isinstance(key, Var) else LiteralVar.create(key)
|
|
||||||
)
|
|
||||||
object.__delattr__(self, "_var_name")
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def _cached_var_name(self) -> str:
|
def _cached_var_name(self) -> str:
|
||||||
@ -705,7 +726,7 @@ class ObjectItemOperation(ImmutableVar):
|
|||||||
Returns:
|
Returns:
|
||||||
The name of the operation.
|
The name of the operation.
|
||||||
"""
|
"""
|
||||||
return f"{str(self.value)}[{str(self.key)}]"
|
return f"{str(self._object)}[{str(self._key)}]"
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
"""Get an attribute of the operation.
|
"""Get an attribute of the operation.
|
||||||
@ -728,8 +749,8 @@ class ObjectItemOperation(ImmutableVar):
|
|||||||
The VarData of the components and all of its children.
|
The VarData of the components and all of its children.
|
||||||
"""
|
"""
|
||||||
return ImmutableVarData.merge(
|
return ImmutableVarData.merge(
|
||||||
self.value._get_all_var_data(),
|
self._object._get_all_var_data(),
|
||||||
self.key._get_all_var_data(),
|
self._key._get_all_var_data(),
|
||||||
self._var_data,
|
self._var_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -747,7 +768,38 @@ class ObjectItemOperation(ImmutableVar):
|
|||||||
Returns:
|
Returns:
|
||||||
The hash of the operation.
|
The hash of the operation.
|
||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self.value, self.key))
|
return hash((self.__class__.__name__, self._object, self._key))
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
"""Post initialization."""
|
||||||
|
object.__delattr__(self, "_var_name")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
object: ObjectVar,
|
||||||
|
key: Var | Any,
|
||||||
|
_var_type: GenericType | None = None,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> ObjectItemOperation:
|
||||||
|
"""Create the object item operation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
object: The object to get the item from.
|
||||||
|
key: The key to get from the object.
|
||||||
|
_var_type: The type of the item.
|
||||||
|
_var_data: Additional hooks and imports associated with the operation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The object item operation.
|
||||||
|
"""
|
||||||
|
return cls(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=object._value_type() if _var_type is None else _var_type,
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_object=object,
|
||||||
|
_key=key if isinstance(key, Var) else LiteralVar.create(key),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(
|
@dataclasses.dataclass(
|
||||||
@ -758,28 +810,9 @@ class ObjectItemOperation(ImmutableVar):
|
|||||||
class ToObjectOperation(ObjectVar):
|
class ToObjectOperation(ObjectVar):
|
||||||
"""Operation to convert a var to an object."""
|
"""Operation to convert a var to an object."""
|
||||||
|
|
||||||
_original_var: Var = dataclasses.field(default_factory=lambda: LiteralObjectVar({}))
|
_original_var: Var = dataclasses.field(
|
||||||
|
default_factory=lambda: LiteralObjectVar.create({})
|
||||||
def __init__(
|
)
|
||||||
self,
|
|
||||||
_original_var: Var,
|
|
||||||
_var_type: Type = dict,
|
|
||||||
_var_data: VarData | None = None,
|
|
||||||
):
|
|
||||||
"""Initialize the to object operation.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
_original_var: The original var to convert.
|
|
||||||
_var_type: The type of the var.
|
|
||||||
_var_data: Additional hooks and imports associated with the operation.
|
|
||||||
"""
|
|
||||||
super(ToObjectOperation, self).__init__(
|
|
||||||
_var_name="",
|
|
||||||
_var_type=_var_type,
|
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
|
||||||
)
|
|
||||||
object.__setattr__(self, "_original_var", _original_var)
|
|
||||||
object.__delattr__(self, "_var_name")
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def _cached_var_name(self) -> str:
|
def _cached_var_name(self) -> str:
|
||||||
@ -831,6 +864,34 @@ class ToObjectOperation(ObjectVar):
|
|||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self._original_var))
|
return hash((self.__class__.__name__, self._original_var))
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
"""Post initialization."""
|
||||||
|
object.__delattr__(self, "_var_name")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
original_var: Var,
|
||||||
|
_var_type: GenericType | None = None,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> ToObjectOperation:
|
||||||
|
"""Create the to object operation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
original_var: The original var to convert.
|
||||||
|
_var_type: The type of the var.
|
||||||
|
_var_data: Additional hooks and imports associated with the operation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The to object operation.
|
||||||
|
"""
|
||||||
|
return cls(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=dict if _var_type is None else _var_type,
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_original_var=original_var,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(
|
@dataclasses.dataclass(
|
||||||
eq=False,
|
eq=False,
|
||||||
@ -840,30 +901,13 @@ class ToObjectOperation(ObjectVar):
|
|||||||
class ObjectHasOwnProperty(BooleanVar):
|
class ObjectHasOwnProperty(BooleanVar):
|
||||||
"""Operation to check if an object has a property."""
|
"""Operation to check if an object has a property."""
|
||||||
|
|
||||||
value: ObjectVar = dataclasses.field(default_factory=lambda: LiteralObjectVar({}))
|
_object: ObjectVar = dataclasses.field(
|
||||||
key: Var | Any = dataclasses.field(default_factory=lambda: LiteralVar.create(None))
|
default_factory=lambda: LiteralObjectVar.create({})
|
||||||
|
)
|
||||||
|
_key: Var | Any = dataclasses.field(default_factory=lambda: LiteralVar.create(None))
|
||||||
|
|
||||||
def __init__(
|
def __post_init__(self):
|
||||||
self,
|
"""Post initialization."""
|
||||||
value: ObjectVar,
|
|
||||||
key: Var | Any,
|
|
||||||
_var_data: VarData | None = None,
|
|
||||||
):
|
|
||||||
"""Initialize the object has own property operation.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value: The value of the operation.
|
|
||||||
key: The key to check.
|
|
||||||
_var_data: Additional hooks and imports associated with the operation.
|
|
||||||
"""
|
|
||||||
super(ObjectHasOwnProperty, self).__init__(
|
|
||||||
_var_name="",
|
|
||||||
_var_data=ImmutableVarData.merge(_var_data),
|
|
||||||
)
|
|
||||||
object.__setattr__(self, "value", value)
|
|
||||||
object.__setattr__(
|
|
||||||
self, "key", key if isinstance(key, Var) else LiteralVar.create(key)
|
|
||||||
)
|
|
||||||
object.__delattr__(self, "_var_name")
|
object.__delattr__(self, "_var_name")
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
@ -873,7 +917,7 @@ class ObjectHasOwnProperty(BooleanVar):
|
|||||||
Returns:
|
Returns:
|
||||||
The name of the operation.
|
The name of the operation.
|
||||||
"""
|
"""
|
||||||
return f"{str(self.value)}.hasOwnProperty({str(self.key)})"
|
return f"{str(self._object)}.hasOwnProperty({str(self._key)})"
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
"""Get an attribute of the operation.
|
"""Get an attribute of the operation.
|
||||||
@ -896,8 +940,8 @@ class ObjectHasOwnProperty(BooleanVar):
|
|||||||
The VarData of the components and all of its children.
|
The VarData of the components and all of its children.
|
||||||
"""
|
"""
|
||||||
return ImmutableVarData.merge(
|
return ImmutableVarData.merge(
|
||||||
self.value._get_all_var_data(),
|
self._object._get_all_var_data(),
|
||||||
self.key._get_all_var_data(),
|
self._key._get_all_var_data(),
|
||||||
self._var_data,
|
self._var_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -915,4 +959,29 @@ class ObjectHasOwnProperty(BooleanVar):
|
|||||||
Returns:
|
Returns:
|
||||||
The hash of the operation.
|
The hash of the operation.
|
||||||
"""
|
"""
|
||||||
return hash((self.__class__.__name__, self.value, self.key))
|
return hash((self.__class__.__name__, self._object, self._key))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(
|
||||||
|
cls,
|
||||||
|
object: ObjectVar,
|
||||||
|
key: Var | Any,
|
||||||
|
_var_data: VarData | None = None,
|
||||||
|
) -> ObjectHasOwnProperty:
|
||||||
|
"""Create the object has own property operation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
object: The object to check.
|
||||||
|
key: The key to check.
|
||||||
|
_var_data: Additional hooks and imports associated with the operation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The object has own property operation.
|
||||||
|
"""
|
||||||
|
return cls(
|
||||||
|
_var_name="",
|
||||||
|
_var_type=bool,
|
||||||
|
_var_data=ImmutableVarData.merge(_var_data),
|
||||||
|
_object=object,
|
||||||
|
_key=key if isinstance(key, Var) else LiteralVar.create(key),
|
||||||
|
)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@ import dill
|
|||||||
from sqlalchemy.orm import DeclarativeBase
|
from sqlalchemy.orm import DeclarativeBase
|
||||||
|
|
||||||
from reflex.config import get_config
|
from reflex.config import get_config
|
||||||
from reflex.ivars.base import ImmutableVar
|
from reflex.ivars.base import ImmutableComputedVar, ImmutableVar, immutable_computed_var
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pydantic.v1 as pydantic
|
import pydantic.v1 as pydantic
|
||||||
@ -60,7 +60,6 @@ from reflex.vars import (
|
|||||||
ComputedVar,
|
ComputedVar,
|
||||||
ImmutableVarData,
|
ImmutableVarData,
|
||||||
Var,
|
Var,
|
||||||
computed_var,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -68,7 +67,7 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
Delta = Dict[str, Any]
|
Delta = Dict[str, Any]
|
||||||
var = computed_var
|
var = immutable_computed_var
|
||||||
|
|
||||||
|
|
||||||
# If the state is this large, it's considered a performance issue.
|
# If the state is this large, it's considered a performance issue.
|
||||||
@ -307,7 +306,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
base_vars: ClassVar[Dict[str, ImmutableVar]] = {}
|
base_vars: ClassVar[Dict[str, ImmutableVar]] = {}
|
||||||
|
|
||||||
# The computed vars of the class.
|
# The computed vars of the class.
|
||||||
computed_vars: ClassVar[Dict[str, ComputedVar]] = {}
|
computed_vars: ClassVar[Dict[str, Union[ComputedVar, ImmutableComputedVar]]] = {}
|
||||||
|
|
||||||
# Vars inherited by the parent state.
|
# Vars inherited by the parent state.
|
||||||
inherited_vars: ClassVar[Dict[str, Var]] = {}
|
inherited_vars: ClassVar[Dict[str, Var]] = {}
|
||||||
@ -420,7 +419,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
return f"{self.__class__.__name__}({self.dict()})"
|
return f"{self.__class__.__name__}({self.dict()})"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_computed_vars(cls) -> list[ComputedVar]:
|
def _get_computed_vars(cls) -> list[Union[ComputedVar, ImmutableComputedVar]]:
|
||||||
"""Helper function to get all computed vars of a instance.
|
"""Helper function to get all computed vars of a instance.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -430,7 +429,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
v
|
v
|
||||||
for mixin in cls._mixins() + [cls]
|
for mixin in cls._mixins() + [cls]
|
||||||
for v in mixin.__dict__.values()
|
for v in mixin.__dict__.values()
|
||||||
if isinstance(v, ComputedVar)
|
if isinstance(v, (ComputedVar, ImmutableComputedVar))
|
||||||
]
|
]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -534,7 +533,10 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
for f in cls.get_fields().values()
|
for f in cls.get_fields().values()
|
||||||
if f.name not in cls.get_skip_vars()
|
if f.name not in cls.get_skip_vars()
|
||||||
}
|
}
|
||||||
cls.computed_vars = {v._var_name: v._var_set_state(cls) for v in computed_vars}
|
cls.computed_vars = {
|
||||||
|
v._var_name: v._replace(merge_var_data=ImmutableVarData.from_state(cls))
|
||||||
|
for v in computed_vars
|
||||||
|
}
|
||||||
cls.vars = {
|
cls.vars = {
|
||||||
**cls.inherited_vars,
|
**cls.inherited_vars,
|
||||||
**cls.base_vars,
|
**cls.base_vars,
|
||||||
@ -555,12 +557,12 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
|
|
||||||
for mixin in cls._mixins():
|
for mixin in cls._mixins():
|
||||||
for name, value in mixin.__dict__.items():
|
for name, value in mixin.__dict__.items():
|
||||||
if isinstance(value, ComputedVar):
|
if isinstance(value, (ComputedVar, ImmutableComputedVar)):
|
||||||
fget = cls._copy_fn(value.fget)
|
fget = cls._copy_fn(value.fget)
|
||||||
newcv = value._replace(fget=fget)
|
newcv = value._replace(
|
||||||
|
fget=fget, _var_data=ImmutableVarData.from_state(cls)
|
||||||
|
)
|
||||||
# cleanup refs to mixin cls in var_data
|
# cleanup refs to mixin cls in var_data
|
||||||
newcv._var_data = None
|
|
||||||
newcv._var_set_state(cls)
|
|
||||||
setattr(cls, name, newcv)
|
setattr(cls, name, newcv)
|
||||||
cls.computed_vars[newcv._var_name] = newcv
|
cls.computed_vars[newcv._var_name] = newcv
|
||||||
cls.vars[newcv._var_name] = newcv
|
cls.vars[newcv._var_name] = newcv
|
||||||
@ -897,8 +899,9 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# create the variable based on name and type
|
# create the variable based on name and type
|
||||||
var = ImmutableVar(_var_name=name, _var_type=type_).guess_type()
|
var = ImmutableVar(
|
||||||
var._var_set_state(cls)
|
_var_name=name, _var_type=type_, _var_data=ImmutableVarData.from_state(cls)
|
||||||
|
).guess_type()
|
||||||
|
|
||||||
# add the pydantic field dynamically (must be done before _init_var)
|
# add the pydantic field dynamically (must be done before _init_var)
|
||||||
cls.add_field(var, default_value)
|
cls.add_field(var, default_value)
|
||||||
@ -983,7 +986,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
and not types.is_optional(prop._var_type)
|
and not types.is_optional(prop._var_type)
|
||||||
):
|
):
|
||||||
# Ensure frontend uses null coalescing when accessing.
|
# Ensure frontend uses null coalescing when accessing.
|
||||||
prop._var_type = Optional[prop._var_type]
|
object.__setattr__(prop, "_var_type", Optional[prop._var_type])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_base_functions() -> dict[str, FunctionType]:
|
def _get_base_functions() -> dict[str, FunctionType]:
|
||||||
@ -1783,7 +1786,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
|||||||
# Include initial computed vars.
|
# Include initial computed vars.
|
||||||
prop_name: (
|
prop_name: (
|
||||||
cv._initial_value
|
cv._initial_value
|
||||||
if isinstance(cv, ComputedVar)
|
if isinstance(cv, (ComputedVar, ImmutableComputedVar))
|
||||||
and not isinstance(cv._initial_value, types.Unset)
|
and not isinstance(cv._initial_value, types.Unset)
|
||||||
else self.get_value(getattr(self, prop_name))
|
else self.get_value(getattr(self, prop_name))
|
||||||
)
|
)
|
||||||
|
@ -9,8 +9,6 @@ import re
|
|||||||
from typing import TYPE_CHECKING, Any, Callable, List, Optional, Union
|
from typing import TYPE_CHECKING, Any, Callable, List, Optional, Union
|
||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.ivars.base import ImmutableVar
|
|
||||||
from reflex.ivars.function import FunctionVar
|
|
||||||
from reflex.utils import exceptions, types
|
from reflex.utils import exceptions, types
|
||||||
from reflex.vars import BaseVar, Var
|
from reflex.vars import BaseVar, Var
|
||||||
|
|
||||||
@ -274,8 +272,10 @@ def format_f_string_prop(prop: BaseVar) -> str:
|
|||||||
Returns:
|
Returns:
|
||||||
The formatted string.
|
The formatted string.
|
||||||
"""
|
"""
|
||||||
|
from reflex.ivars.base import VarData
|
||||||
|
|
||||||
s = prop._var_full_name
|
s = prop._var_full_name
|
||||||
var_data = prop._var_data
|
var_data = VarData.merge(prop._get_all_var_data())
|
||||||
interps = var_data.interpolations if var_data else []
|
interps = var_data.interpolations if var_data else []
|
||||||
parts: List[str] = []
|
parts: List[str] = []
|
||||||
|
|
||||||
@ -423,6 +423,7 @@ def format_prop(
|
|||||||
# import here to avoid circular import.
|
# import here to avoid circular import.
|
||||||
from reflex.event import EventChain
|
from reflex.event import EventChain
|
||||||
from reflex.utils import serializers
|
from reflex.utils import serializers
|
||||||
|
from reflex.vars import VarData
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Handle var props.
|
# Handle var props.
|
||||||
@ -430,7 +431,8 @@ def format_prop(
|
|||||||
if not prop._var_is_local or prop._var_is_string:
|
if not prop._var_is_local or prop._var_is_string:
|
||||||
return str(prop)
|
return str(prop)
|
||||||
if isinstance(prop, BaseVar) and types._issubclass(prop._var_type, str):
|
if isinstance(prop, BaseVar) and types._issubclass(prop._var_type, str):
|
||||||
if prop._var_data and prop._var_data.interpolations:
|
var_data = VarData.merge(prop._get_all_var_data())
|
||||||
|
if var_data and var_data.interpolations:
|
||||||
return format_f_string_prop(prop)
|
return format_f_string_prop(prop)
|
||||||
return format_string(prop._var_full_name)
|
return format_string(prop._var_full_name)
|
||||||
prop = prop._var_full_name
|
prop = prop._var_full_name
|
||||||
@ -485,17 +487,38 @@ def format_props(*single_props, **key_value_props) -> list[str]:
|
|||||||
The formatted props list.
|
The formatted props list.
|
||||||
"""
|
"""
|
||||||
# Format all the props.
|
# Format all the props.
|
||||||
from reflex.ivars.base import ImmutableVar
|
from reflex.ivars.base import ImmutableVar, LiteralVar
|
||||||
|
|
||||||
|
# print(
|
||||||
|
# *[
|
||||||
|
# f"{name}={{{format_prop(prop if isinstance(prop, Var) else LiteralVar.create(prop))}}}"
|
||||||
|
# for name, prop in sorted(key_value_props.items())
|
||||||
|
# if prop is not None
|
||||||
|
# ],
|
||||||
|
# sep="\n",
|
||||||
|
# )
|
||||||
|
|
||||||
|
# if single_props:
|
||||||
|
# print("single_props", single_props)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
(
|
(
|
||||||
f"{name}={{{format_prop(prop)}}}"
|
f"{name}={format_prop(prop)}"
|
||||||
if isinstance(prop, ImmutableVar)
|
if isinstance(prop, Var) and not isinstance(prop, ImmutableVar)
|
||||||
else f"{name}={format_prop(prop)}"
|
else (
|
||||||
|
f"{name}={{{format_prop(prop if isinstance(prop, Var) else LiteralVar.create(prop))}}}"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
for name, prop in sorted(key_value_props.items())
|
for name, prop in sorted(key_value_props.items())
|
||||||
if prop is not None
|
if prop is not None
|
||||||
] + [str(prop) for prop in single_props]
|
] + [
|
||||||
|
(
|
||||||
|
str(prop)
|
||||||
|
if isinstance(prop, Var) and not isinstance(prop, ImmutableVar)
|
||||||
|
else f"{{{str(LiteralVar.create(prop))}}}"
|
||||||
|
)
|
||||||
|
for prop in single_props
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]:
|
def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]:
|
||||||
@ -510,13 +533,13 @@ def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]:
|
|||||||
# Get the class that defines the event handler.
|
# Get the class that defines the event handler.
|
||||||
parts = handler.fn.__qualname__.split(".")
|
parts = handler.fn.__qualname__.split(".")
|
||||||
|
|
||||||
# If there's no enclosing class, just return the function name.
|
|
||||||
if len(parts) == 1:
|
|
||||||
return ("", parts[-1])
|
|
||||||
|
|
||||||
# Get the state full name
|
# Get the state full name
|
||||||
state_full_name = handler.state_full_name
|
state_full_name = handler.state_full_name
|
||||||
|
|
||||||
|
# If there's no enclosing class, just return the function name.
|
||||||
|
if not state_full_name:
|
||||||
|
return ("", parts[-1])
|
||||||
|
|
||||||
# Get the function name
|
# Get the function name
|
||||||
name = parts[-1]
|
name = parts[-1]
|
||||||
|
|
||||||
@ -655,6 +678,7 @@ def format_queue_events(
|
|||||||
call_event_fn,
|
call_event_fn,
|
||||||
call_event_handler,
|
call_event_handler,
|
||||||
)
|
)
|
||||||
|
from reflex.ivars.base import FunctionVar, ImmutableVar
|
||||||
|
|
||||||
if not events:
|
if not events:
|
||||||
return ImmutableVar("(() => null)").to(FunctionVar, EventChain)
|
return ImmutableVar("(() => null)").to(FunctionVar, EventChain)
|
||||||
@ -944,6 +968,8 @@ def format_data_editor_cell(cell: Any):
|
|||||||
Returns:
|
Returns:
|
||||||
The formatted cell.
|
The formatted cell.
|
||||||
"""
|
"""
|
||||||
|
from reflex.ivars.base import ImmutableVar
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"kind": ImmutableVar.create("GridCellKind.Text"),
|
"kind": ImmutableVar.create("GridCellKind.Text"),
|
||||||
"data": cell,
|
"data": cell,
|
||||||
|
@ -491,10 +491,18 @@ def is_backend_base_variable(name: str, cls: Type) -> bool:
|
|||||||
return False
|
return False
|
||||||
if callable(value):
|
if callable(value):
|
||||||
return False
|
return False
|
||||||
|
from reflex.ivars.base import ImmutableComputedVar
|
||||||
from reflex.vars import ComputedVar
|
from reflex.vars import ComputedVar
|
||||||
|
|
||||||
if isinstance(
|
if isinstance(
|
||||||
value, (types.FunctionType, property, cached_property, ComputedVar)
|
value,
|
||||||
|
(
|
||||||
|
types.FunctionType,
|
||||||
|
property,
|
||||||
|
cached_property,
|
||||||
|
ComputedVar,
|
||||||
|
ImmutableComputedVar,
|
||||||
|
),
|
||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -892,6 +892,7 @@ class Var:
|
|||||||
Raises:
|
Raises:
|
||||||
VarTypeError: If the var is not indexable.
|
VarTypeError: If the var is not indexable.
|
||||||
"""
|
"""
|
||||||
|
print(repr(self))
|
||||||
from reflex.utils import format
|
from reflex.utils import format
|
||||||
|
|
||||||
# Indexing is only supported for strings, lists, tuples, dicts, and dataframes.
|
# Indexing is only supported for strings, lists, tuples, dicts, and dataframes.
|
||||||
|
@ -154,6 +154,7 @@ class Var:
|
|||||||
def _var_set_state(self, state: Type[BaseState] | str) -> Any: ...
|
def _var_set_state(self, state: Type[BaseState] | str) -> Any: ...
|
||||||
def _get_all_var_data(self) -> VarData | ImmutableVarData: ...
|
def _get_all_var_data(self) -> VarData | ImmutableVarData: ...
|
||||||
def json(self) -> str: ...
|
def json(self) -> str: ...
|
||||||
|
def _type(self) -> Var: ...
|
||||||
|
|
||||||
@dataclass(eq=False)
|
@dataclass(eq=False)
|
||||||
class BaseVar(Var):
|
class BaseVar(Var):
|
||||||
|
Loading…
Reference in New Issue
Block a user