Fix component decorator bugs (#203)
This commit is contained in:
parent
858008d3b1
commit
3f27ce3442
@ -11,7 +11,6 @@ from pynecone.components.component import Component, CustomComponent, ImportDict
|
||||
from pynecone.state import State
|
||||
from pynecone.style import Style
|
||||
|
||||
|
||||
# Imports to be included in every Pynecone app.
|
||||
DEFAULT_IMPORTS: ImportDict = {
|
||||
"react": {"useEffect", "useRef", "useState"},
|
||||
|
@ -1,11 +1,8 @@
|
||||
"""Common utility functions used in the compiler."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import inspect
|
||||
import json
|
||||
import os
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Set, Type
|
||||
from typing import Dict, List, Set, Tuple, Type
|
||||
|
||||
from pynecone import constants, utils
|
||||
from pynecone.compiler import templates
|
||||
@ -21,14 +18,9 @@ from pynecone.components.base import (
|
||||
Script,
|
||||
Title,
|
||||
)
|
||||
from pynecone.components.component import ImportDict
|
||||
from pynecone.components.component import Component, CustomComponent, ImportDict
|
||||
from pynecone.state import State
|
||||
from pynecone.style import Style
|
||||
from pynecone.var import BaseVar, Var
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pynecone.components.component import Component, CustomComponent
|
||||
|
||||
|
||||
# To re-export this function.
|
||||
merge_imports = utils.merge_imports
|
||||
@ -170,7 +162,7 @@ def compile_render(component: Component) -> str:
|
||||
return component.render()
|
||||
|
||||
|
||||
def compile_custom_component(component: CustomComponent) -> tuple[str, ImportDict]:
|
||||
def compile_custom_component(component: CustomComponent) -> Tuple[str, ImportDict]:
|
||||
"""Compile a custom component.
|
||||
|
||||
Args:
|
||||
@ -179,20 +171,18 @@ def compile_custom_component(component: CustomComponent) -> tuple[str, ImportDic
|
||||
Returns:
|
||||
A tuple of the compiled component and the imports required by the component.
|
||||
"""
|
||||
props = [
|
||||
BaseVar(
|
||||
name=name,
|
||||
type_=prop.type_ if utils._isinstance(prop, Var) else type(prop),
|
||||
is_local=True,
|
||||
)
|
||||
for name, prop in component.props.items()
|
||||
]
|
||||
# Render the component.
|
||||
render = component.get_component()
|
||||
|
||||
# Compile the component.
|
||||
render = component.component_fn(*props)
|
||||
# Get the imports.
|
||||
imports = {
|
||||
lib: fields
|
||||
for lib, fields in render.get_imports().items()
|
||||
if lib != component.library
|
||||
}
|
||||
|
||||
# Concatenate the props.
|
||||
props = ", ".join([prop.name for prop in props])
|
||||
props = ", ".join([prop.name for prop in component.get_prop_vars()])
|
||||
|
||||
# Compile the component.
|
||||
return (
|
||||
@ -201,7 +191,7 @@ def compile_custom_component(component: CustomComponent) -> tuple[str, ImportDic
|
||||
props=props,
|
||||
render=render,
|
||||
),
|
||||
render.get_imports(),
|
||||
imports,
|
||||
)
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ from pynecone.event import (
|
||||
EventSpec,
|
||||
)
|
||||
from pynecone.style import Style
|
||||
from pynecone.var import Var
|
||||
from pynecone.var import BaseVar, Var
|
||||
|
||||
ImportDict = Dict[str, Set[str]]
|
||||
|
||||
@ -440,7 +440,7 @@ class CustomComponent(Component):
|
||||
if utils._issubclass(type_, EventChain):
|
||||
value = self._create_event_chain(key, value)
|
||||
else:
|
||||
value = Var.create(value)
|
||||
value = Var.create(value, is_string=type(value) is str)
|
||||
self.props[utils.to_camel_case(key)] = value
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
@ -477,7 +477,11 @@ class CustomComponent(Component):
|
||||
Returns:
|
||||
The set of custom components.
|
||||
"""
|
||||
return {self} | super().get_custom_components()
|
||||
return (
|
||||
{self}
|
||||
| super().get_custom_components()
|
||||
| self.get_component().get_custom_components()
|
||||
)
|
||||
|
||||
def _render(self) -> Tag:
|
||||
"""Define how to render the component in React.
|
||||
@ -487,6 +491,28 @@ class CustomComponent(Component):
|
||||
"""
|
||||
return Tag(name=self.tag).add_props(**self.props)
|
||||
|
||||
def get_prop_vars(self) -> List[BaseVar]:
|
||||
"""Get the prop vars.
|
||||
|
||||
Returns:
|
||||
The prop vars.
|
||||
"""
|
||||
return [
|
||||
BaseVar(
|
||||
name=name,
|
||||
type_=prop.type_ if utils._isinstance(prop, Var) else type(prop),
|
||||
)
|
||||
for name, prop in self.props.items()
|
||||
]
|
||||
|
||||
def get_component(self) -> Component:
|
||||
"""Render the component.
|
||||
|
||||
Returns:
|
||||
The code to render the component.
|
||||
"""
|
||||
return self.component_fn(*self.get_prop_vars())
|
||||
|
||||
|
||||
def custom_component(
|
||||
component_fn: Callable[..., Component]
|
||||
|
@ -13,8 +13,6 @@ import signal
|
||||
import string
|
||||
import subprocess
|
||||
import sys
|
||||
import uvicorn
|
||||
from urllib.parse import urlparse
|
||||
from collections import defaultdict
|
||||
from subprocess import PIPE
|
||||
from types import ModuleType
|
||||
@ -30,9 +28,11 @@ from typing import (
|
||||
Type,
|
||||
Union,
|
||||
)
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import plotly.graph_objects as go
|
||||
import typer
|
||||
import uvicorn
|
||||
from plotly.io import to_json
|
||||
from redis import Redis
|
||||
from rich.console import Console
|
||||
|
@ -161,7 +161,9 @@ class Var(ABC):
|
||||
else:
|
||||
type_ = Any
|
||||
else:
|
||||
raise TypeError("Var does not support indexing.")
|
||||
raise TypeError(
|
||||
f"Var {self.name} of type {self.type_} does not support indexing."
|
||||
)
|
||||
|
||||
return BaseVar(
|
||||
name=f"{self.name}[{i}]",
|
||||
|
@ -110,7 +110,7 @@ def my_component():
|
||||
A test component function.
|
||||
"""
|
||||
|
||||
def my_component(prop1: str, prop2: int):
|
||||
def my_component(prop1: Var[str], prop2: Var[int]):
|
||||
return Box.create(prop1, prop2)
|
||||
|
||||
return my_component
|
||||
@ -286,7 +286,7 @@ def test_create_custom_component(my_component):
|
||||
Args:
|
||||
my_component: A test custom component.
|
||||
"""
|
||||
component = CustomComponent(component_fn=my_component)
|
||||
component = CustomComponent(component_fn=my_component, prop1="test", prop2=1)
|
||||
assert component.tag == "MyComponent"
|
||||
assert component.get_props() == set()
|
||||
assert component.get_custom_components() == {component}
|
||||
@ -298,6 +298,6 @@ def test_custom_component_hash(my_component):
|
||||
Args:
|
||||
my_component: A test custom component.
|
||||
"""
|
||||
component1 = CustomComponent(component_fn=my_component)
|
||||
component2 = CustomComponent(component_fn=my_component)
|
||||
component1 = CustomComponent(component_fn=my_component, prop1="test", prop2=1)
|
||||
component2 = CustomComponent(component_fn=my_component, prop1="test", prop2=2)
|
||||
assert set([component1, component2]) == {component1}
|
||||
|
Loading…
Reference in New Issue
Block a user