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