|
@@ -9,14 +9,15 @@ import os
|
|
import os.path as op
|
|
import os.path as op
|
|
import re
|
|
import re
|
|
import sys
|
|
import sys
|
|
-from typing import TYPE_CHECKING, Any, Type, Union
|
|
|
|
|
|
+import types as builtin_types
|
|
|
|
+from typing import TYPE_CHECKING, Any, Callable, Type, Union
|
|
|
|
|
|
import plotly.graph_objects as go
|
|
import plotly.graph_objects as go
|
|
from plotly.graph_objects import Figure
|
|
from plotly.graph_objects import Figure
|
|
from plotly.io import to_json
|
|
from plotly.io import to_json
|
|
|
|
|
|
from reflex import constants
|
|
from reflex import constants
|
|
-from reflex.utils import types
|
|
|
|
|
|
+from reflex.utils import exceptions, types
|
|
from reflex.vars import Var
|
|
from reflex.vars import Var
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
if TYPE_CHECKING:
|
|
@@ -288,7 +289,8 @@ def format_prop(
|
|
The formatted prop to display within a tag.
|
|
The formatted prop to display within a tag.
|
|
|
|
|
|
Raises:
|
|
Raises:
|
|
- TypeError: If the prop is not a valid type.
|
|
|
|
|
|
+ exceptions.InvalidStylePropError: If the style prop value is not a valid type.
|
|
|
|
+ TypeError: If the prop is not valid.
|
|
"""
|
|
"""
|
|
# import here to avoid circular import.
|
|
# import here to avoid circular import.
|
|
from reflex.event import EVENT_ARG, EventChain
|
|
from reflex.event import EVENT_ARG, EventChain
|
|
@@ -324,6 +326,8 @@ def format_prop(
|
|
else:
|
|
else:
|
|
# Dump the prop as JSON.
|
|
# Dump the prop as JSON.
|
|
prop = json_dumps(prop)
|
|
prop = json_dumps(prop)
|
|
|
|
+ except exceptions.InvalidStylePropError:
|
|
|
|
+ raise
|
|
except TypeError as e:
|
|
except TypeError as e:
|
|
raise TypeError(f"Could not format prop: {prop} of type {type(prop)}") from e
|
|
raise TypeError(f"Could not format prop: {prop} of type {type(prop)}") from e
|
|
|
|
|
|
@@ -584,15 +588,28 @@ def format_dict(prop: ComponentStyle) -> str:
|
|
|
|
|
|
Returns:
|
|
Returns:
|
|
The formatted dict.
|
|
The formatted dict.
|
|
|
|
+
|
|
|
|
+ Raises:
|
|
|
|
+ InvalidStylePropError: If a style prop has a callable value
|
|
"""
|
|
"""
|
|
# Import here to avoid circular imports.
|
|
# Import here to avoid circular imports.
|
|
|
|
+ from reflex.event import EventHandler
|
|
from reflex.vars import Var
|
|
from reflex.vars import Var
|
|
|
|
|
|
|
|
+ prop_dict = {}
|
|
|
|
+
|
|
# Convert any var keys to strings.
|
|
# Convert any var keys to strings.
|
|
- prop = {key: str(val) if isinstance(val, Var) else val for key, val in prop.items()}
|
|
|
|
|
|
+ for key, value in prop.items():
|
|
|
|
+ if issubclass(type(value), Callable):
|
|
|
|
+ raise exceptions.InvalidStylePropError(
|
|
|
|
+ f"The style prop `{to_snake_case(key)}` cannot have " # type: ignore
|
|
|
|
+ f"`{value.fn.__qualname__ if isinstance(value, EventHandler) else value.__qualname__ if isinstance(value, builtin_types.FunctionType) else value}`, "
|
|
|
|
+ f"an event handler or callable as its value"
|
|
|
|
+ )
|
|
|
|
+ prop_dict[key] = str(value) if isinstance(value, Var) else value
|
|
|
|
|
|
# Dump the dict to a string.
|
|
# Dump the dict to a string.
|
|
- fprop = json_dumps(prop)
|
|
|
|
|
|
+ fprop = json_dumps(prop_dict)
|
|
|
|
|
|
def unescape_double_quotes_in_var(m: re.Match) -> str:
|
|
def unescape_double_quotes_in_var(m: re.Match) -> str:
|
|
# Since the outer quotes are removed, the inner escaped quotes must be unescaped.
|
|
# Since the outer quotes are removed, the inner escaped quotes must be unescaped.
|