Browse Source

Add error message for invalid var ops (#664)

Nikhil Rao 2 years ago
parent
commit
2ee8c73d5a

+ 1 - 1
pynecone/.templates/web/pynecone.json

@@ -1,3 +1,3 @@
 {
-    "version": "0.1.19"
+    "version": "0.1.20"
 }

+ 14 - 9
pynecone/app.py

@@ -204,7 +204,6 @@ class App(Base):
         description: str = constants.DEFAULT_DESCRIPTION,
         image=constants.DEFAULT_IMAGE,
         on_load: Optional[Union[EventHandler, List[EventHandler]]] = None,
-        path: Optional[str] = None,
         meta: List[Dict] = constants.DEFAULT_META_LIST,
         script_tags: Optional[List[Component]] = None,
     ):
@@ -215,7 +214,6 @@ class App(Base):
 
         Args:
             component: The component to display at the page.
-            path: (deprecated) The path to the component.
             route: The route to display the component at.
             title: The title of the page.
             description: The description of the page.
@@ -223,13 +221,10 @@ class App(Base):
             on_load: The event handler(s) that will be called each time the page load.
             meta: The metadata of the page.
             script_tags: List of script tags to be added to component
-        """
-        if path is not None:
-            utils.deprecate(
-                "The `path` argument is deprecated for `add_page`. Use `route` instead."
-            )
-            route = path
 
+        Raises:
+            TypeError: If an invalid var operation is used.
+        """
         # If the route is not set, get it from the callable.
         if route is None:
             assert isinstance(
@@ -244,7 +239,17 @@ class App(Base):
         self.state.setup_dynamic_args(utils.get_route_args(route))
 
         # Generate the component if it is a callable.
-        component = component if isinstance(component, Component) else component()
+        try:
+            component = component if isinstance(component, Component) else component()
+        except TypeError as e:
+            message = str(e)
+            if "BaseVar" in message or "ComputedVar" in message:
+                raise TypeError(
+                    "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. "
+                    "See the var operation docs here: https://pynecone.io/docs/state/vars "
+                ) from e
+            raise e
 
         # Add meta information to the component.
         compiler_utils.add_meta(

+ 1 - 3
pynecone/components/base/body.py

@@ -1,11 +1,9 @@
 """Display the page body."""
 
 from pynecone.components.component import Component
-from pynecone.components.tags import Tag
 
 
 class Body(Component):
     """A body component."""
 
-    def _render(self) -> Tag:
-        return Tag(name="body")
+    tag = "body"

+ 16 - 48
pynecone/components/base/link.py

@@ -1,76 +1,44 @@
 """Display the title of the current page."""
 
-from typing import Optional
 
 from pynecone.components.component import Component
-from pynecone.components.tags import Tag
 from pynecone.var import Var
 
 
 class Link(Component):
     """A component that displays the title of the current page."""
 
+    tag = "link"
+
     # The href.
     href: Var[str]
 
     # The type of link.
     rel: Var[str]
 
-    def _render(self) -> Tag:
-        return Tag(name="link").add_props(
-            href=self.href,
-            rel=self.rel,
-        )
-
 
 class ScriptTag(Component):
-    """A component that creates a script tag with the speacified type and source.
-
-
-    Args:
-        type: This attribute indicates the type of script represented.
-            The value of this attribute will be one of the following:
-
-            - module: This value causes the code to be treated as a JavaScript module.
-            - importmap: This value indicates that the body of the element
-                contains an import map.
-            - Any value: The embedded content is treated as a data block, and won't be
-                processed by the browser.
-            - blocking: This attribute explicitly indicates that certain operations
-                should be blocked on the fetching of the script.
-
-        source: This attribute specifies the URI of an external script; this can be
-            used as an alternative to embedding a script directly within a document.
-
-        integrity: This attribute contains inline metadata that a user agent can use
-            to verify that a fetched resource has been delivered free of unexpected manipulation
-
-        crossorigin: To allow error logging for sites which use a separate domain for static media,
-            use this attribute.
-
-        referrer_policy: Indicates which referrer to send when fetching the script, or resources fetched by the script
-            refrence: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#:~:text=Indicates%20which%20referrer%20to%20send%20when%20fetching%20the%20script%2C%20or%20resources%20fetched%20by%20the%20script%3A
-
-        is_async: This attribute allows the elimination of parser-blocking JavaScript where the browser would have to
-            load and evaluate scripts before continuing to parse. defer has a similar effect in this case.
-
-        defer: This Boolean attribute is set to indicate to a browser that the script is
-            meant to be executed after the document has been parsed, but before firing DOMContentLoaded.
-
-    """
+    """A script tag with the specified type and source."""
 
     tag = "script"
 
-    type: Var[str]
+    # The type of script represented.
+    type_: Var[str]
 
+    # The URI of an external script.
     source: Var[str]
 
-    integrity: Optional[Var[str]]
+    # Metadata to verify the content of the script.
+    integrity: Var[str]
 
-    crossorigin: Optional[Var[str]]
+    # Whether to allow cross-origin requests.
+    crossorigin: Var[str]
 
-    referrer_policy: Optional[Var[str]]
+    # Indicates which referrer to send when fetching the script.
+    referrer_policy: Var[str]
 
-    is_async: Optional[Var[bool]]
+    # Whether to asynchronously load the script.
+    is_async: Var[bool]
 
-    defer: Optional[Var[bool]]
+    # Whether to defer loading the script.
+    defer: Var[bool]

+ 1 - 0
pynecone/watch.py

@@ -44,6 +44,7 @@ class AssetFolderHandler(FileSystemEventHandler):
 
     def on_modified(self, event: FileSystemEvent):
         """Event handler when a file or folder was modified.
+
         This is called every time after a file is created, modified and deleted.
 
         Args:

+ 1 - 0
tests/components/datadisplay/__init__.py

@@ -0,0 +1 @@
+"""Datadisplay component tests."""

+ 11 - 0
tests/components/datadisplay/conftest.py

@@ -1,3 +1,5 @@
+"""Data display component tests fixtures."""
+
 import pytest
 
 import pynecone as pc
@@ -5,6 +7,15 @@ import pynecone as pc
 
 @pytest.fixture
 def data_table_state(request):
+    """Get a data table state.
+
+    Args:
+        request: The request.
+
+    Returns:
+        The data table state class.
+    """
+
     class DataTableState(pc.State):
         data = request.param["data"]
         columns = ["column1", "column2"]