فهرست منبع

Clean up tag rendering

Nikhil Rao 2 سال پیش
والد
کامیت
67058b66a4

+ 0 - 14
pynecone/compiler/templates.py

@@ -131,20 +131,6 @@ EVENT_FN = join(
 ).format
 
 
-def format_event_declaration(fn: Callable) -> str:
-    """Format an event declaration.
-
-    Args:
-        fn: The function to declare.
-
-    Returns:
-        The compiled event declaration.
-    """
-    name = utils.format_event_fn(fn=fn)
-    event = utils.to_snake_case(fn.__qualname__)
-    return f"const {name} = Event('{event}')"
-
-
 # Effects.
 ROUTER = constants.ROUTER
 RESULT = constants.RESULT

+ 3 - 0
pynecone/components/component.py

@@ -137,6 +137,9 @@ class Component(Base, ABC):
 
         Returns:
             The event chain.
+
+        Raises:
+            ValueError: If the value is not a valid event chain.
         """
         arg = self.get_controlled_value()
 

+ 0 - 3
pynecone/components/datadisplay/code.py

@@ -1,12 +1,9 @@
 """A code component."""
 
-import json
 from typing import Dict
 
-from pynecone import utils
 from pynecone.components.component import Component
 from pynecone.components.libs.chakra import ChakraComponent
-from pynecone.components.tags import Tag
 from pynecone.var import Var
 
 

+ 2 - 1
pynecone/components/tags/iter_tag.py

@@ -65,7 +65,8 @@ class IterTag(Tag):
             assert len(args) == 2
             component = render_fn(arg, index)
         if component.key is None:
-            component.key = utils.wrap(str(index), "{", check_first=False)
+            component.key = index
+            # component.key = utils.wrap(str(index), "{", check_first=False)
         return component
 
     def __str__(self) -> str:

+ 13 - 24
pynecone/components/tags/tag.py

@@ -57,29 +57,19 @@ class Tag(Base):
         Returns:
             The formatted prop to display within a tag.
         """
-
-        def format_fn(value):
-            args = ",".join([":".join((name, val)) for name, val in value.args])
-            return f"E(\"{utils.to_snake_case(value.handler.fn.__qualname__)}\", {utils.wrap(args, '{')})"
-
         # Handle var props.
         if isinstance(prop, Var):
             if not prop.is_local or prop.is_string:
                 return str(prop)
             if issubclass(prop.type_, str):
-                prop = json.dumps(prop.full_name)
-                prop = re.sub('"{', "", prop)
-                prop = re.sub('}"', "", prop)
-                prop = re.sub('"`', '{"', prop)
-                prop = re.sub('`"', '"}', prop)
-                return prop
+                return json.dumps(prop.full_name)
             prop = prop.full_name
 
-        # Handle events.
+        # Handle event props.
         elif isinstance(prop, EventChain):
             local_args = ",".join(prop.events[0].local_args)
-            fns = ",".join([format_fn(event) for event in prop.events])
-            prop = f"({local_args}) => Event([{fns}])"
+            events = ",".join([utils.format_event(event) for event in prop.events])
+            prop = f"({local_args}) => Event([{events}])"
 
         # Handle other types.
         elif isinstance(prop, str):
@@ -93,19 +83,18 @@ class Tag(Base):
         # For dictionaries, convert any properties to strings.
         else:
             if isinstance(prop, dict):
-                prop = json.dumps(
-                    {
-                        key: str(val) if isinstance(val, Var) else val
-                        for key, val in prop.items()
-                    }
-                )
-            else:
-                prop = json.dumps(prop)
+                # Convert any var keys to strings.
+                prop = {
+                    key: str(val) if isinstance(val, Var) else val
+                    for key, val in prop.items()
+                }
+
+            # Dump the prop as JSON.
+            prop = json.dumps(prop)
 
+            # This substitution is necessary to unwrap var values.
             prop = re.sub('"{', "", prop)
             prop = re.sub('}"', "", prop)
-            prop = re.sub('"`', '{"', prop)
-            prop = re.sub('`"', '"}', prop)
 
         # Wrap the variable in braces.
         assert isinstance(prop, str), "The prop must be a string."

+ 5 - 3
pynecone/components/typography/markdown.py

@@ -1,8 +1,10 @@
 """Table components."""
 
+from typing import List
+
 from pynecone import utils
 from pynecone.components.component import Component
-from pynecone.var import Var
+from pynecone.var import BaseVar, Var
 
 
 class Markdown(Component):
@@ -55,7 +57,7 @@ class Markdown(Component):
                     "\n", " "
                 ),
             },
-            remark_plugins="{{[remarkMath, remarkGfm]}}",
-            rehype_plugins="{{[rehypeKatex]}}",
+            remark_plugins=BaseVar(name="[remarkMath, remarkGfm]", type_=List[str]),
+            rehype_plugins=BaseVar(name="[rehypeKatex]", type_=List[str]),
             src="",
         )

+ 12 - 0
pynecone/state.py

@@ -177,6 +177,9 @@ class State(Base, ABC):
 
         Returns:
             The class substate.
+
+        Raises:
+            ValueError: If the substate is not found.
         """
         if len(path) == 0:
             return cls
@@ -198,6 +201,9 @@ class State(Base, ABC):
 
         Returns:
             The class var.
+
+        Raises:
+            ValueError: If the path is invalid.
         """
         path, name = path[:-1], path[-1]
         substate = cls.get_class_substate(tuple(path))
@@ -247,6 +253,9 @@ class State(Base, ABC):
 
         Returns:
             The attribute.
+
+        Raises:
+            Exception: If the attribute is not found.
         """
         # If it is an inherited var, return from the parent state.
         if name != "inherited_vars" and name in self.inherited_vars:
@@ -300,6 +309,9 @@ class State(Base, ABC):
 
         Returns:
             The substate.
+
+        Raises:
+            ValueError: If the substate is not found.
         """
         if len(path) == 0:
             return self

+ 24 - 3
pynecone/utils.py

@@ -441,6 +441,9 @@ def get_close_char(open: str, close: Optional[str] = None) -> str:
 
     Returns:
         The close character.
+
+    Raises:
+        ValueError: If the open character is not a valid brace.
     """
     if close is not None:
         return close
@@ -591,7 +594,20 @@ def format_event_fn(fn: Callable) -> str:
 
     if isinstance(fn, EventHandler):
         fn = fn.fn
-    return fn.__qualname__.replace(".", "_")
+    return to_snake_case(fn.__qualname__)
+
+
+def format_event(event_spec: EventSpec) -> str:
+    """Format an event.
+
+    Args:
+        event_spec: The event to format.
+
+    Returns:
+        The compiled event.
+    """
+    args = ",".join([":".join((name, val)) for name, val in event_spec.args])
+    return f"E(\"{format_event_fn(event_spec.handler.fn)}\", {wrap(args, '{')})"
 
 
 USED_VARIABLES = set()
@@ -633,7 +649,7 @@ def is_dataframe(value: Type) -> bool:
     return value.__name__ == "DataFrame"
 
 
-def format_state(value: Dict) -> Dict:
+def format_state(value: Any) -> Dict:
     """Recursively format values in the given state.
 
     Args:
@@ -724,6 +740,9 @@ def call_event_fn(fn: Callable, arg: Var) -> List[EventSpec]:
 
     Returns:
         The event specs from calling the function.
+
+    Raises:
+        ValueError: If the lambda has an invalid signature.
     """
     args = inspect.getfullargspec(fn).args
     if len(args) == 0:
@@ -764,6 +783,8 @@ def fix_events(events: Optional[List[Event]], token: str) -> List[Event]:
     Returns:
         The fixed events.
     """
+    from pynecone.event import Event, EventHandler, EventSpec
+
     # If the event handler returns nothing, return an empty list.
     if events is None:
         return []
@@ -786,7 +807,7 @@ def fix_events(events: Optional[List[Event]], token: str) -> List[Event]:
             if isinstance(e, EventHandler):
                 e = e()
             assert isinstance(e, EventSpec), f"Unexpected event type, {type(e)}."
-            name = to_snake_case(e.handler.fn.__qualname__)
+            name = format_event_fn(e.handler.fn)
             payload = dict(e.args)
 
         # Create an event and append it to the list.

+ 7 - 1
pynecone/var.py

@@ -126,7 +126,7 @@ class Var(ABC):
             out = utils.format_string(out)
         return out
 
-    def __getitem__(self, i) -> Var:
+    def __getitem__(self, i: Any) -> Var:
         """Index into a var.
 
         Args:
@@ -134,6 +134,9 @@ class Var(ABC):
 
         Returns:
             The indexed var.
+
+        Raises:
+            TypeError: If the var is not indexable.
         """
         # The type of the indexed var.
         type_ = str
@@ -174,6 +177,9 @@ class Var(ABC):
 
         Returns:
             The var attribute.
+
+        Raises:
+            Exception: If the attribute is not found.
         """
         try:
             return super().__getattribute__(name)

+ 1 - 1
pyproject.toml

@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "pynecone-io"
-version = "0.1.0"
+version = "0.1.2"
 description = ""
 authors = [
     "Nikhil Rao <nikhil@pynecone.io>",