Skip to content

Commit

Permalink
minor renaming + better changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
rmorshea committed Dec 28, 2023
1 parent 98d92e1 commit 0dc1eaa
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 21 deletions.
7 changes: 3 additions & 4 deletions docs/source/about/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,9 @@ Unreleased
the string ``"None"``. Now ``None`` will not render at all. This is consistent with
how ``None`` is handled when returned from components. It also makes it easier to
conditionally render elements. For example, previously you would have needed to use a
fragment to conditionally render an element (e.g.
``something if condition else html._()``). Now you can write:
``something if condition else None``. The latter now has the minor performance
advantage of not needing to create and render a fragment.
fragment to conditionally render an element by writing
``something if condition else html._()``. Now you can simply write
``something if condition else None``.


v1.0.2
Expand Down
39 changes: 22 additions & 17 deletions src/py/reactpy/reactpy/core/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
wait,
)
from collections import Counter
from collections.abc import Iterator
from collections.abc import Sequence
from contextlib import AsyncExitStack
from logging import getLogger
from typing import (
Expand All @@ -27,6 +27,7 @@
from weakref import ref as weakref

from anyio import Semaphore
from typing_extensions import TypeAlias

from reactpy.config import (
REACTPY_ASYNC_RENDERING,
Expand All @@ -37,6 +38,7 @@
from reactpy.core.types import (
ComponentType,
EventHandlerDict,
Key,
LayoutEventMessage,
LayoutUpdateMessage,
VdomChild,
Expand Down Expand Up @@ -328,11 +330,11 @@ async def _render_model_children(
await self._unmount_model_states(list(old_state.children_by_key.values()))
return None

child_type_key_tuples = list(_process_child_type_and_key(raw_children))
children_info = _get_children_info(raw_children)

new_keys = {item[2] for item in child_type_key_tuples}
if len(new_keys) != len(child_type_key_tuples):
key_counter = Counter(item[2] for item in child_type_key_tuples)
new_keys = {k for _, _, k in children_info}
if len(new_keys) != len(children_info):
key_counter = Counter(item[2] for item in children_info)
duplicate_keys = [key for key, count in key_counter.items() if count > 1]
msg = f"Duplicate keys {duplicate_keys} at {new_state.patch_path or '/'!r}"
raise ValueError(msg)
Expand All @@ -344,7 +346,7 @@ async def _render_model_children(
)

new_state.model.current["children"] = []
for index, (child, child_type, key) in enumerate(child_type_key_tuples):
for index, (child, child_type, key) in enumerate(children_info):
old_child_state = old_state.children_by_key.get(key)
if child_type is _DICT_TYPE:
old_child_state = old_state.children_by_key.get(key)
Expand Down Expand Up @@ -419,17 +421,17 @@ async def _render_model_children_without_old_state(
new_state: _ModelState,
raw_children: list[Any],
) -> None:
child_type_key_tuples = list(_process_child_type_and_key(raw_children))
children_info = _get_children_info(raw_children)

new_keys = {item[2] for item in child_type_key_tuples}
if len(new_keys) != len(child_type_key_tuples):
key_counter = Counter(item[2] for item in child_type_key_tuples)
new_keys = {k for _, _, k in children_info}
if len(new_keys) != len(children_info):
key_counter = Counter(k for _, _, k in children_info)
duplicate_keys = [key for key, count in key_counter.items() if count > 1]
msg = f"Duplicate keys {duplicate_keys} at {new_state.patch_path or '/'!r}"
raise ValueError(msg)

new_state.model.current["children"] = []
for index, (child, child_type, key) in enumerate(child_type_key_tuples):
for index, (child, child_type, key) in enumerate(children_info):
if child_type is _DICT_TYPE:
child_state = _make_element_model_state(new_state, index, key)
await self._render_model(exit_stack, None, child_state, child)
Expand Down Expand Up @@ -608,7 +610,7 @@ def __init__(
key: Any,
model: Ref[VdomJson],
patch_path: str,
children_by_key: dict[str, _ModelState],
children_by_key: dict[Key, _ModelState],
targets_by_event: dict[str, str],
life_cycle_state: _LifeCycleState | None = None,
):
Expand Down Expand Up @@ -719,9 +721,8 @@ async def get(self) -> _Type:
return value


def _process_child_type_and_key(
children: list[VdomChild],
) -> Iterator[tuple[Any, _ElementType, Any]]:
def _get_children_info(children: list[VdomChild]) -> Sequence[_ChildInfo]:
infos: list[_ChildInfo] = []
for index, child in enumerate(children):
if child is None:
continue
Expand All @@ -730,7 +731,7 @@ def _process_child_type_and_key(
key = child.get("key")
elif isinstance(child, ComponentType):
child_type = _COMPONENT_TYPE
key = getattr(child, "key", None)
key = child.key
else:
child = f"{child}"
child_type = _STRING_TYPE
Expand All @@ -739,8 +740,12 @@ def _process_child_type_and_key(
if key is None:
key = index

yield (child, child_type, key)
infos.append((child, child_type, key))

return infos


_ChildInfo: TypeAlias = tuple[Any, "_ElementType", Key]

# used in _process_child_type_and_key
_ElementType = NewType("_ElementType", int)
Expand Down

0 comments on commit 0dc1eaa

Please sign in to comment.