-
-
Notifications
You must be signed in to change notification settings - Fork 328
Expand file tree
/
Copy pathcomponent.py
More file actions
70 lines (55 loc) · 2.08 KB
/
component.py
File metadata and controls
70 lines (55 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from __future__ import annotations
import inspect
from functools import wraps
from typing import Any, Callable, Dict, Optional, Tuple, Union
from .proto import ComponentType, VdomDict
def component(
function: Callable[..., Union[ComponentType, VdomDict | None]]
) -> Callable[..., Component]:
"""A decorator for defining a new component.
Parameters:
function: The component's :meth:`idom.core.proto.ComponentType.render` function.
"""
sig = inspect.signature(function)
if "key" in sig.parameters and sig.parameters["key"].kind in (
inspect.Parameter.KEYWORD_ONLY,
inspect.Parameter.POSITIONAL_OR_KEYWORD,
):
raise TypeError(
f"Component render function {function} uses reserved parameter 'key'"
)
@wraps(function)
def constructor(*args: Any, key: Optional[Any] = None, **kwargs: Any) -> Component:
return Component(function, key, args, kwargs, sig)
return constructor
class Component:
"""An object for rending component models."""
__slots__ = "__weakref__", "_func", "_args", "_kwargs", "_sig", "key", "type"
def __init__(
self,
function: Callable[..., ComponentType | VdomDict | None],
key: Optional[Any],
args: Tuple[Any, ...],
kwargs: Dict[str, Any],
sig: inspect.Signature,
) -> None:
self.key = key
self.type = function
self._args = args
self._kwargs = kwargs
self._sig = sig
def render(self) -> VdomDict | ComponentType | None:
return self.type(*self._args, **self._kwargs)
def should_render(self, new: Component) -> bool:
return True
def __repr__(self) -> str:
try:
args = self._sig.bind(*self._args, **self._kwargs).arguments
except TypeError:
return f"{self.type.__name__}(...)"
else:
items = ", ".join(f"{k}={v!r}" for k, v in args.items())
if items:
return f"{self.type.__name__}({id(self):02x}, {items})"
else:
return f"{self.type.__name__}({id(self):02x})"