@@ -47,7 +47,26 @@ def offset(self, v: int) -> None:
4747
4848class CompatChildren (MutableSequence ):
4949 def __init__ (self , parent : "Node" ) -> None :
50- self ._children = parent .get_dict ()["@children" ]
50+ self ._par_dict = parent .get_dict ()
51+ self ._children = self ._sync_children ()
52+
53+ def _sync_children (self ) -> None :
54+ if "_children" not in self ._par_dict :
55+ self ._par_dict ["_children" ] = []
56+ children = self ._par_dict ["_children" ]
57+ for k , v in self ._par_dict .items ():
58+ if k in ("_children" , "@pos" , "@role" , "@type" ):
59+ continue
60+
61+ tv = type (v )
62+ if tv in (Node , dict ):
63+ if v not in children :
64+ children .append (v )
65+ elif tv in (list , tuple ):
66+ # Get all node|dict types inside the list and add to children
67+ children .extend ([i for i in v if type (i ) in (Node , dict ) and i not in children ])
68+ # else ignore it
69+ return children
5170
5271 @staticmethod
5372 def _node2dict (n : Union ['Node' , dict ]) -> dict :
@@ -66,13 +85,16 @@ def __delitem__(self, idx: Union[int, slice]) -> None:
6685 del self ._children [idx ]
6786
6887 def __setitem__ (self , idx : Union [int , slice ], val : Union ['Node' , dict ]) -> None :
69- self ._children [idx ] = self ._node2dict (val )
88+ self ._par_dict ["_children" ].__setitem__ (idx , self ._node2dict (val ))
89+ self ._children = self ._sync_children ()
7090
7191 def insert (self , idx : int , val : Union ['Node' , dict ]) -> None :
72- self ._children .insert (idx , self ._node2dict (val ))
92+ self ._par_dict ["_children" ].insert (idx , self ._node2dict (val ))
93+ self ._children = self ._sync_children ()
7394
7495 def append (self , val : Union ['Node' , dict ]) -> None :
75- self ._children .append (self ._node2dict (val ))
96+ self ._par_dict ["_children" ].append (self ._node2dict (val ))
97+ self ._children = self ._sync_children ()
7698
7799 def extend (self , items : List [Union ['Node' , dict ]]) -> None :
78100 for i in items :
@@ -112,32 +134,6 @@ def __init__(self, node_ext: NodeExt = None, value: ResultMultiType = None) -> N
112134
113135 self .node_ext = node_ext
114136
115- if isinstance (self .internal_node , dict ):
116- self ._load_children ()
117-
118- # This is for v1 "node.children" compatibility. It will update the children
119- # property with the dict or Node objects in properties or list/tuple properties
120- # when .children is accessed (because the user could change the node using get_dict()
121- # or .properties).
122- # Also, all these " in children" are O(1) so this will be slow for frequently accessing
123- # the children property on big nodes.
124- def _load_children (self ) -> None :
125- """Get all properties of type node or dict and load them into the list"""
126- d = self .get_dict ()
127- children = d .get ("@children" , [])
128- for k , v in d .items ():
129- if k in ("@children" , "@pos" , "@role" , "@type" ):
130- continue
131-
132- tv = type (v )
133- if tv in (Node , dict ):
134- if v not in children :
135- children .append (v )
136- elif tv in (list , tuple ):
137- # Get all node|dict types inside the list and add to children
138- children .extend ([i for i in v if type (i ) in (Node , dict ) and i not in children ])
139- # else ignore it
140-
141137 def __str__ (self ) -> str :
142138 return str (self .get ())
143139
@@ -200,7 +196,6 @@ def _is_dict_list(self, key: str) -> Optional[List]:
200196
201197 @property
202198 def children (self ) -> CompatChildren :
203- self ._load_children ()
204199 return CompatChildren (self )
205200
206201 @property
0 commit comments