Skip to content

Commit 3a8a0b2

Browse files
committed
remove ComponentType, replace with Component
1 parent b1b4985 commit 3a8a0b2

File tree

7 files changed

+65
-81
lines changed

7 files changed

+65
-81
lines changed

src/reactpy/core/_life_cycle_hook.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from anyio import Semaphore
1111

1212
from reactpy.core._thread_local import ThreadLocal
13-
from reactpy.types import ComponentType, Context, ContextProviderType
13+
from reactpy.types import Component, Context, ContextProviderType
1414
from reactpy.utils import Singleton
1515

1616
T = TypeVar("T")
@@ -146,7 +146,7 @@ async def my_effect(stop_event):
146146
"component",
147147
)
148148

149-
component: ComponentType
149+
component: Component
150150

151151
def __init__(
152152
self,
@@ -219,7 +219,7 @@ def get_context_provider(
219219
"""
220220
return self._context_providers.get(context)
221221

222-
async def affect_component_will_render(self, component: ComponentType) -> None:
222+
async def affect_component_will_render(self, component: Component) -> None:
223223
"""The component is about to render"""
224224
await self._render_access.acquire()
225225
self._scheduled_render = False

src/reactpy/core/component.py

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
from functools import wraps
66
from typing import Any
77

8-
from reactpy.types import ComponentType, VdomDict
8+
from reactpy.types import Component, VdomDict
99

1010

1111
def component(
12-
function: Callable[..., ComponentType | VdomDict | str | None],
12+
function: Callable[..., Component | VdomDict | str | None],
1313
) -> Callable[..., Component]:
1414
"""A decorator for defining a new component.
1515
@@ -30,38 +30,3 @@ def constructor(*args: Any, key: Any | None = None, **kwargs: Any) -> Component:
3030
return Component(function, key, args, kwargs, sig)
3131

3232
return constructor
33-
34-
35-
class Component:
36-
"""An object for rending component models."""
37-
38-
__slots__ = "__weakref__", "_args", "_func", "_kwargs", "_sig", "key", "type"
39-
40-
def __init__(
41-
self,
42-
function: Callable[..., ComponentType | VdomDict | str | None],
43-
key: Any | None,
44-
args: tuple[Any, ...],
45-
kwargs: dict[str, Any],
46-
sig: inspect.Signature,
47-
) -> None:
48-
self.key = key
49-
self.type = function
50-
self._args = args
51-
self._kwargs = kwargs
52-
self._sig = sig
53-
54-
def render(self) -> ComponentType | VdomDict | str | None:
55-
return self.type(*self._args, **self._kwargs)
56-
57-
def __repr__(self) -> str:
58-
try:
59-
args = self._sig.bind(*self._args, **self._kwargs).arguments
60-
except TypeError:
61-
return f"{self.type.__name__}(...)"
62-
else:
63-
items = ", ".join(f"{k}={v!r}" for k, v in args.items())
64-
if items:
65-
return f"{self.type.__name__}({id(self):02x}, {items})"
66-
else:
67-
return f"{self.type.__name__}({id(self):02x})"

src/reactpy/core/layout.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from reactpy.core._life_cycle_hook import LifeCycleHook
3838
from reactpy.core.vdom import validate_vdom_json
3939
from reactpy.types import (
40-
ComponentType,
40+
Component,
4141
Context,
4242
Event,
4343
EventHandlerDict,
@@ -69,9 +69,9 @@ class Layout:
6969
if not hasattr(abc.ABC, "__weakref__"): # nocov
7070
__slots__ += ("__weakref__",)
7171

72-
def __init__(self, root: ComponentType | Context[Any]) -> None:
72+
def __init__(self, root: Component | Context[Any]) -> None:
7373
super().__init__()
74-
if not isinstance(root, ComponentType):
74+
if not isinstance(root, Component):
7575
msg = f"Expected a ComponentType, not {type(root)!r}."
7676
raise TypeError(msg)
7777
self.root = root
@@ -183,7 +183,7 @@ async def _render_component(
183183
exit_stack: AsyncExitStack,
184184
old_state: _ModelState | None,
185185
new_state: _ModelState,
186-
component: ComponentType,
186+
component: Component,
187187
) -> None:
188188
life_cycle_state = new_state.life_cycle_state
189189
life_cycle_hook = life_cycle_state.hook
@@ -386,7 +386,7 @@ async def _render_model_children(
386386
new_state.append_child(new_child_state.model.current)
387387
new_state.children_by_key[key] = new_child_state
388388
elif child_type is _COMPONENT_TYPE:
389-
child = cast(ComponentType, child)
389+
child = cast(Component, child)
390390
old_child_state = old_state.children_by_key.get(key)
391391
if old_child_state is None:
392392
new_child_state = _make_component_model_state(
@@ -490,7 +490,7 @@ def __repr__(self) -> str:
490490

491491

492492
def _new_root_model_state(
493-
component: ComponentType, schedule_render: Callable[[_LifeCycleStateId], None]
493+
component: Component, schedule_render: Callable[[_LifeCycleStateId], None]
494494
) -> _ModelState:
495495
return _ModelState(
496496
parent=None,
@@ -508,7 +508,7 @@ def _make_component_model_state(
508508
parent: _ModelState,
509509
index: int,
510510
key: Any,
511-
component: ComponentType,
511+
component: Component,
512512
schedule_render: Callable[[_LifeCycleStateId], None],
513513
) -> _ModelState:
514514
return _ModelState(
@@ -546,7 +546,7 @@ def _update_component_model_state(
546546
old_model_state: _ModelState,
547547
new_parent: _ModelState,
548548
new_index: int,
549-
new_component: ComponentType,
549+
new_component: Component,
550550
schedule_render: Callable[[_LifeCycleStateId], None],
551551
) -> _ModelState:
552552
return _ModelState(
@@ -672,7 +672,7 @@ def __repr__(self) -> str: # nocov
672672

673673

674674
def _make_life_cycle_state(
675-
component: ComponentType,
675+
component: Component,
676676
schedule_render: Callable[[_LifeCycleStateId], None],
677677
) -> _LifeCycleState:
678678
life_cycle_state_id = _LifeCycleStateId(uuid4().hex)
@@ -685,7 +685,7 @@ def _make_life_cycle_state(
685685

686686
def _update_life_cycle_state(
687687
old_life_cycle_state: _LifeCycleState,
688-
new_component: ComponentType,
688+
new_component: Component,
689689
) -> _LifeCycleState:
690690
return _LifeCycleState(
691691
old_life_cycle_state.id,
@@ -707,7 +707,7 @@ class _LifeCycleState(NamedTuple):
707707
hook: LifeCycleHook
708708
"""The life cycle hook"""
709709

710-
component: ComponentType
710+
component: Component
711711
"""The current component instance"""
712712

713713

@@ -739,7 +739,7 @@ def _get_children_info(children: list[VdomChild]) -> Sequence[_ChildInfo]:
739739
elif isinstance(child, dict):
740740
child_type = _DICT_TYPE
741741
key = child.get("key")
742-
elif isinstance(child, ComponentType):
742+
elif isinstance(child, Component):
743743
child_type = _COMPONENT_TYPE
744744
key = child.key
745745
else:

src/reactpy/core/vdom.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from reactpy.core._f_back import f_module_name
1818
from reactpy.core.events import EventHandler, to_event_handler_function
1919
from reactpy.types import (
20-
ComponentType,
20+
Component,
2121
CustomVdomConstructor,
2222
EllipsisRepr,
2323
EventHandlerDict,
@@ -275,7 +275,7 @@ def _validate_child_key_integrity(value: Any) -> None:
275275
)
276276
else:
277277
for child in value:
278-
if isinstance(child, ComponentType) and child.key is None:
278+
if isinstance(child, Component) and child.key is None:
279279
warn(f"Key not specified for child in list {child}", UserWarning)
280280
elif isinstance(child, Mapping) and "key" not in child:
281281
# remove 'children' to reduce log spam

src/reactpy/pyscript/components.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from reactpy import component, hooks
77
from reactpy.pyscript.utils import pyscript_component_html
8-
from reactpy.types import ComponentType, Key
8+
from reactpy.types import Component, Key
99
from reactpy.utils import string_to_reactpy
1010

1111
if TYPE_CHECKING:
@@ -39,10 +39,10 @@ def _pyscript_component(
3939

4040
def pyscript_component(
4141
*file_paths: str | Path,
42-
initial: str | VdomDict | ComponentType = "",
42+
initial: str | VdomDict | Component = "",
4343
root: str = "root",
4444
key: Key | None = None,
45-
) -> ComponentType:
45+
) -> Component:
4646
"""
4747
Args:
4848
file_paths: File path to your client-side ReactPy component. If multiple paths are \

src/reactpy/types.py

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import inspect
34
from collections.abc import Awaitable, Callable, Mapping, Sequence
45
from dataclasses import dataclass
56
from pathlib import Path
@@ -26,31 +27,49 @@ class State(NamedTuple, Generic[_Type]):
2627
set_value: Callable[[_Type | Callable[[_Type], _Type]], None]
2728

2829

29-
ComponentConstructor = Callable[..., "ComponentType"]
30+
ComponentConstructor = Callable[..., "Component"]
3031
"""Simple function returning a new component"""
3132

32-
RootComponentConstructor = Callable[[], "ComponentType"]
33+
RootComponentConstructor = Callable[[], "Component"]
3334
"""The root component should be constructed by a function accepting no arguments."""
3435

3536

3637
Key: TypeAlias = str | int
3738

3839

39-
@runtime_checkable
40-
class ComponentType(Protocol):
41-
"""The expected interface for all component-like objects"""
42-
43-
key: Key | None
44-
"""An identifier which is unique amongst a component's immediate siblings"""
40+
class Component:
41+
"""An object for rending component models."""
4542

46-
type: Any
47-
"""The function or class defining the behavior of this component
43+
__slots__ = "__weakref__", "_args", "_func", "_kwargs", "_sig", "key", "type"
4844

49-
This is used to see if two component instances share the same definition.
50-
"""
45+
def __init__(
46+
self,
47+
function: Callable[..., Component | VdomDict | str | None],
48+
key: Any | None,
49+
args: tuple[Any, ...],
50+
kwargs: dict[str, Any],
51+
sig: inspect.Signature,
52+
) -> None:
53+
self.key = key
54+
self.type = function
55+
self._args = args
56+
self._kwargs = kwargs
57+
self._sig = sig
58+
59+
def render(self) -> Component | VdomDict | str | None:
60+
return self.type(*self._args, **self._kwargs)
5161

52-
def render(self) -> VdomDict | ComponentType | str | None:
53-
"""Render the component's view model."""
62+
def __repr__(self) -> str:
63+
try:
64+
args = self._sig.bind(*self._args, **self._kwargs).arguments
65+
except TypeError:
66+
return f"{self.type.__name__}(...)"
67+
else:
68+
items = ", ".join(f"{k}={v!r}" for k, v in args.items())
69+
if items:
70+
return f"{self.type.__name__}({id(self):02x}, {items})"
71+
else:
72+
return f"{self.type.__name__}({id(self):02x})"
5473

5574

5675
_Render_co = TypeVar("_Render_co", covariant=True)
@@ -787,7 +806,7 @@ class VdomTypeDict(TypedDict):
787806

788807
tagName: str
789808
key: NotRequired[Key | None]
790-
children: NotRequired[Sequence[ComponentType | VdomChild]]
809+
children: NotRequired[Sequence[Component | VdomChild]]
791810
attributes: NotRequired[VdomAttributes]
792811
eventHandlers: NotRequired[EventHandlerDict]
793812
inlineJavaScript: NotRequired[InlineJavaScriptDict]
@@ -815,7 +834,7 @@ def __getitem__(self, key: Literal["key"]) -> Key | None: ...
815834
@overload
816835
def __getitem__(
817836
self, key: Literal["children"]
818-
) -> Sequence[ComponentType | VdomChild]: ...
837+
) -> Sequence[Component | VdomChild]: ...
819838
@overload
820839
def __getitem__(self, key: Literal["attributes"]) -> VdomAttributes: ...
821840
@overload
@@ -833,7 +852,7 @@ def __setitem__(self, key: Literal["tagName"], value: str) -> None: ...
833852
def __setitem__(self, key: Literal["key"], value: Key | None) -> None: ...
834853
@overload
835854
def __setitem__(
836-
self, key: Literal["children"], value: Sequence[ComponentType | VdomChild]
855+
self, key: Literal["children"], value: Sequence[Component | VdomChild]
837856
) -> None: ...
838857
@overload
839858
def __setitem__(
@@ -857,7 +876,7 @@ def __setitem__(self, key: VdomDictKeys, value: Any) -> None:
857876
super().__setitem__(key, value)
858877

859878

860-
VdomChild: TypeAlias = ComponentType | VdomDict | str | None | Any
879+
VdomChild: TypeAlias = Component | VdomDict | str | None | Any
861880
"""A single child element of a :class:`VdomDict`"""
862881

863882
VdomChildren: TypeAlias = Sequence[VdomChild] | VdomChild
@@ -994,7 +1013,7 @@ def __call__(
9941013
) -> ContextProviderType[_Type]: ...
9951014

9961015

997-
class ContextProviderType(ComponentType, Protocol[_Type]):
1016+
class ContextProviderType(Component, Protocol[_Type]):
9981017
"""A component which provides a context value to its children"""
9991018

10001019
type: Context[_Type]

src/reactpy/utils.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from reactpy import html
1313
from reactpy.transforms import RequiredTransforms, attributes_to_reactjs
14-
from reactpy.types import ComponentType, VdomDict
14+
from reactpy.types import Component, VdomDict
1515

1616
_RefValue = TypeVar("_RefValue")
1717
_ModelTransform = Callable[[VdomDict], Any]
@@ -63,7 +63,7 @@ def __repr__(self) -> str:
6363
return f"{type(self).__name__}({current})"
6464

6565

66-
def reactpy_to_string(root: VdomDict | ComponentType) -> str:
66+
def reactpy_to_string(root: VdomDict | Component) -> str:
6767
"""Convert a ReactPy component or `reactpy.html` element into an HTML string.
6868
6969
Parameters:
@@ -186,7 +186,7 @@ def _add_vdom_to_etree(parent: etree._Element, vdom: VdomDict | dict[str, Any])
186186

187187
for c in vdom.get("children", []):
188188
if hasattr(c, "render"):
189-
c = component_to_vdom(cast(ComponentType, c))
189+
c = component_to_vdom(cast(Component, c))
190190
if isinstance(c, dict):
191191
_add_vdom_to_etree(element, c)
192192

@@ -232,14 +232,14 @@ def _generate_vdom_children(
232232
)
233233

234234

235-
def component_to_vdom(component: ComponentType) -> VdomDict:
235+
def component_to_vdom(component: Component) -> VdomDict:
236236
"""Convert the first render of a component into a VDOM dictionary"""
237237
result = component.render()
238238

239239
if isinstance(result, dict):
240240
return result
241241
if hasattr(result, "render"):
242-
return component_to_vdom(cast(ComponentType, result))
242+
return component_to_vdom(cast(Component, result))
243243
elif isinstance(result, str):
244244
return html.div(result)
245245
return html.fragment()

0 commit comments

Comments
 (0)