Skip to content

Commit 555086a

Browse files
committed
only one attr dict in vdom constructor
this allows for some minor performance and logical optimizations that simplifies things slightly
1 parent be2de80 commit 555086a

File tree

2 files changed

+19
-48
lines changed

2 files changed

+19
-48
lines changed

src/idom/core/vdom.py

+19-24
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from __future__ import annotations
77

8-
from typing import Any, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple, Union
8+
from typing import Any, Iterable, List, Mapping, Optional, Sequence, Tuple, Union
99

1010
from fastjsonschema import compile as compile_json_schema
1111
from mypy_extensions import TypedDict
@@ -119,10 +119,9 @@ def vdom(
119119
tag:
120120
The type of element (e.g. 'div', 'h1', 'img')
121121
attributes_and_children:
122-
Attribute mappings followed by iterables of children for the element. The
123-
attributes **must** precede the children, though you may pass multiple sets
124-
of attributes, or children which will be merged into their respective parts
125-
of the model.
122+
An optional attribute mapping followed by any number of children or
123+
iterables of children. The attribute mapping **must** precede the children,
124+
or children which will be merged into their respective parts of the model.
126125
key:
127126
A string idicating the identity of a particular element. This is significant
128127
to preserve event handlers across updates - without a key, a re-render would
@@ -201,26 +200,22 @@ def constructor(
201200

202201

203202
def coalesce_attributes_and_children(
204-
attributes_and_children: _AttributesAndChildrenArg,
205-
) -> Tuple[Dict[str, Any], List[Any]]:
206-
attributes: Dict[str, Any] = {}
207-
children: List[Any] = []
203+
values: Sequence[Any],
204+
) -> Tuple[Mapping[str, Any], List[Any]]:
205+
if not values:
206+
return {}, []
207+
208+
children_or_iterables: Sequence[Any]
209+
attributes, *children_or_iterables = values
210+
if not isinstance(attributes, Mapping) or "tagName" in attributes:
211+
attributes = {}
212+
children_or_iterables = values
208213

209-
began_children = False
210-
for argument in attributes_and_children:
211-
if isinstance(argument, Mapping):
212-
if "tagName" not in argument:
213-
if began_children:
214-
raise ValueError("Attribute dictionaries should precede children.")
215-
attributes.update(argument)
216-
else:
217-
children.append(argument)
218-
began_children = True
219-
elif not isinstance(argument, str) and isinstance(argument, Iterable):
220-
children.extend(argument)
221-
began_children = True
214+
children: List[Any] = []
215+
for child in children_or_iterables:
216+
if isinstance(child, (str, Mapping)) or not hasattr(child, "__iter__"):
217+
children.append(child)
222218
else:
223-
children.append(argument)
224-
began_children = True
219+
children.extend(child)
225220

226221
return attributes, children

tests/test_core/test_vdom.py

-24
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,6 @@ async def handler(event):
3232
"children": [{"tagName": "div"}, 1, {"tagName": "div"}, 2],
3333
},
3434
),
35-
(
36-
# multiple dictionaries of attributes are merged
37-
idom.vdom("div", {"width": "30px"}, {"height": "20px"}),
38-
{"tagName": "div", "attributes": {"width": "30px", "height": "20px"}},
39-
),
40-
(
41-
idom.vdom(
42-
"div",
43-
{"width": "30px"},
44-
{"height": "20px"},
45-
[idom.vdom("div"), 1],
46-
(idom.vdom("div"), 2),
47-
),
48-
{
49-
"tagName": "div",
50-
"children": [{"tagName": "div"}, 1, {"tagName": "div"}, 2],
51-
"attributes": {"width": "30px", "height": "20px"},
52-
},
53-
),
5435
(
5536
idom.vdom("div", event_handlers=fake_events),
5637
{"tagName": "div", "eventHandlers": fake_events},
@@ -96,11 +77,6 @@ def test_simple_node_construction(actual, expected):
9677
assert actual == expected
9778

9879

99-
def test_vdom_attribute_arguments_come_before_children():
100-
with pytest.raises(ValueError):
101-
idom.vdom("div", ["c1", "c2"], {"attr": 1})
102-
103-
10480
def test_make_vdom_constructor():
10581
elmt = make_vdom_constructor("some-tag")
10682

0 commit comments

Comments
 (0)