cengal.data_manipulation.tree_traversal.versions.v_1.tree_traversal

  1#!/usr/bin/env python
  2# coding=utf-8
  3
  4# Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>
  5# 
  6# Licensed under the Apache License, Version 2.0 (the "License");
  7# you may not use this file except in compliance with the License.
  8# You may obtain a copy of the License at
  9# 
 10#     http://www.apache.org/licenses/LICENSE-2.0
 11# 
 12# Unless required by applicable law or agreed to in writing, software
 13# distributed under the License is distributed on an "AS IS" BASIS,
 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15# See the License for the specific language governing permissions and
 16# limitations under the License.
 17
 18
 19__all__ = ['AnAppropriateValues', 'AllPossibleValues', 'AnAppropriateContainers', 'data_2_tuple', 'data_2_ordered', 'TreeTraversalType', 'TreeTraversal']
 20__all__ = ['AnAppropriateValues', 'AllPossibleValues', 'AnAppropriateContainers', 'TupledDict', 'Contaiters', 'data_2_tuple', 'data_2_ordered', 'TreeTraversalType', 'NodeType', 'EntityType', 'findout_entity_type', 'TreeTraversal', 'KeyMultiValueTreeTraversal', 'KeyValueTreeTraversal']
 21
 22
 23from functools import partial
 24from typing import Any, Hashable, Union, Dict, Set, List, Tuple, Optional, Callable
 25from enum import Enum
 26from collections import deque
 27from cengal.code_flow_control.smart_values import ValueExistence, ValueType
 28from cengal.data_containers.stack import StackItem, TreeStackItem, Stack, recursion_insureness
 29
 30"""
 31Module Docstring
 32Docstrings: http://www.python.org/dev/peps/pep-0257/
 33"""
 34
 35__author__ = "ButenkoMS <gtalk@butenkoms.space>"
 36__copyright__ = "Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>"
 37__credits__ = ["ButenkoMS <gtalk@butenkoms.space>", ]
 38__license__ = "Apache License, Version 2.0"
 39__version__ = "4.4.1"
 40__maintainer__ = "ButenkoMS <gtalk@butenkoms.space>"
 41__email__ = "gtalk@butenkoms.space"
 42# __status__ = "Prototype"
 43__status__ = "Development"
 44# __status__ = "Production"
 45
 46
 47AnAppropriateValues = Union[str, bytes, int, float, None]
 48AllPossibleValues = Union['AnAppropriateContainers', AnAppropriateValues]
 49AnAppropriateContainers = Union[Dict[AnAppropriateValues, AllPossibleValues],
 50                                Set[AllPossibleValues],
 51                                List[AllPossibleValues],
 52                                Tuple[AllPossibleValues]]
 53
 54
 55class TupledDict:
 56    def __init__(self, data: Dict) -> None:
 57        self.dict: Dict = data
 58        self.items: Tuple[Tuple[Hashable, Any]] = tuple(data.items())
 59
 60
 61Contaiters = (TupledDict, dict, tuple, list, set, deque)
 62
 63
 64def data_2_tuple(data: AllPossibleValues) -> AllPossibleValues:
 65    if isinstance(data, Contaiters):
 66        if isinstance(data, dict):
 67            return tuple(data.values())
 68        elif isinstance(data, (tuple, list, deque)):
 69            return data
 70        elif isinstance(data, set):
 71            return tuple(data)
 72    else:
 73        return data
 74
 75
 76def data_2_ordered(data: AllPossibleValues) -> AllPossibleValues:
 77    if isinstance(data, Contaiters):
 78        if isinstance(data, dict):
 79            return TupledDict(data)
 80        elif isinstance(data, set):
 81            return tuple(data)
 82        else:
 83            return data
 84    else:
 85        return data
 86
 87
 88class TreeTraversalType(Enum):
 89    recursive = 0
 90    stack_based = 1
 91    recursive_with_stack_based_insureness = 2
 92
 93
 94class NodeType(Enum):
 95    dict = 0
 96    dict_item = 1
 97    sequence = 2
 98
 99
100class EntityType(Enum):
101    dict = 0
102    dict_item = 1
103    sequence = 2
104    child = 3
105
106
107def findout_entity_type(entity) -> EntityType:
108    if isinstance(entity, Contaiters):
109        if isinstance(entity, TupledDict):
110            entity_type: EntityType = EntityType.dict
111        else:
112            entity_type = EntityType.sequence
113    else:
114        entity_type = EntityType.child
115    
116    return entity_type
117
118
119class TreeTraversal:
120    def __init__(self,
121                 tree: AnAppropriateContainers=None,
122                 on_node: Optional[Callable]=None,
123                 on_child: Optional[Callable]=None,
124                 on_switched_to_stack_based_implementation: Optional[Callable]=None
125                 ):
126        self._tree = tree  # type: AnAppropriateContainers
127
128        self._callback_on_node = on_node  # type: Optional[Callable]
129        self._callback_on_child = on_child  # type: Optional[Callable]
130        self._on_switched_to_stack_based_implementation = \
131            on_switched_to_stack_based_implementation  # type: Optional[Callable]
132
133        self._last_tree_node = ValueExistence(False, None)
134        self._last_tree_child = ValueExistence(False, None)
135        self._empty_child = ValueExistence(False, None)
136
137    def set_callback_on_node(self, functor: Optional[Callable]):
138        self._callback_on_node = functor
139
140    def set_callback_on_child(self, functor: Optional[Callable]):
141        self._callback_on_child = functor
142
143    def set_callback_on_both_node_and_child(self, functor: Optional[Callable]):
144        self._callback_on_node = self._callback_on_child = functor
145
146    def set_callback_on_switched_to_stack_based_implementation(self, functor: Optional[Callable]):
147        self._on_switched_to_stack_based_implementation = functor
148
149    @property
150    def tree(self) -> AnAppropriateContainers:
151        return self._tree
152
153    @tree.setter
154    def tree(self, tree: AnAppropriateContainers):
155        self._tree = tree
156
157    def _traversal_recursive(self):
158        ordered_tree = data_2_ordered(self.tree)
159        self._traversal_recursive_impl(ordered_tree)
160
161    def _traversal_recursive_impl(self, entity: AnAppropriateContainers, deep: int = 0, index: Optional[int] = None):
162        if isinstance(entity, Contaiters):
163            last_tree_node_bak = self._last_tree_node
164            if isinstance(entity, TupledDict):
165                node_type: NodeType = NodeType.dict
166            else:
167                node_type = NodeType.sequence
168            
169            self._last_tree_node.value = ValueType(node_type, entity)
170            if self._callback_on_node:
171                self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
172
173            new_deep = deep + 1
174            if isinstance(entity, TupledDict):
175                value_deep = new_deep + 1
176                for index, node in enumerate(entity.items):
177                    self._last_tree_node.value = ValueType(NodeType.dict_item, node)
178                    if self._callback_on_node:
179                        self._callback_on_node(new_deep, self._last_tree_node, self._empty_child, index)
180                    
181                    item = node[1]
182                    self._traversal_recursive_impl(data_2_ordered(item), value_deep, 0)
183            else:
184                for index, item in enumerate(entity):
185                    self._traversal_recursive_impl(data_2_ordered(item), new_deep, index)
186
187            self._last_tree_node = last_tree_node_bak
188        else:
189            self._last_tree_child.value = entity
190            if self._callback_on_child:
191                self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
192
193    def _traversal_stack_based(self):
194        index: Optional[int] = None
195        deep: int = 0
196        entity = data_2_ordered(self.tree)
197        entity_type: EntityType = findout_entity_type(entity)
198        stack = Stack(TreeStackItem((entity_type, entity, deep, index)))
199        while stack:
200            top = stack.top()
201            entity_type, entity, deep, index = top.node
202            if EntityType.child == entity_type:
203                self._last_tree_child.value = entity
204                if self._callback_on_child:
205                    self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
206                
207                stack.pop()
208            elif EntityType.sequence == entity_type:
209                self._last_tree_node.value = ValueType(NodeType.sequence, entity)
210                if top.child is None:
211                    child_index = 0
212                    if self._callback_on_node:
213                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
214                else:
215                    child_index = top.child + 1
216                
217                if len(entity) > child_index:
218                    top.child = child_index
219                    child = data_2_ordered(entity[child_index])
220                    child_type = findout_entity_type(child)
221                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
222                else:
223                    stack.pop()
224            elif EntityType.dict_item == entity_type:
225                self._last_tree_node.value = ValueType(NodeType.dict_item, entity)
226                if top.child is None:
227                    child_index = 0
228                    if self._callback_on_node:
229                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
230
231                    top.child = child_index
232                    child = data_2_ordered(entity[1])
233                    child_type = findout_entity_type(child)
234                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
235                else:
236                    stack.pop()
237            elif EntityType.dict == entity_type:
238                self._last_tree_node.value = ValueType(NodeType.dict, entity.dict)
239                if top.child is None:
240                    child_index = 0
241                    if self._callback_on_node:
242                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
243                else:
244                    child_index = top.child + 1
245                
246                if len(entity.items) > child_index:
247                    top.child = child_index
248                    child = entity.items[child_index]
249                    stack.push(TreeStackItem((EntityType.dict_item, child, deep + 1, child_index)))
250                else:
251                    stack.pop()
252
253    def __call__(self, traversal_type: TreeTraversalType=TreeTraversalType.recursive_with_stack_based_insureness):
254        if TreeTraversalType.recursive == traversal_type:
255            self._traversal_recursive()
256        elif TreeTraversalType.stack_based == traversal_type:
257            self._traversal_stack_based()
258        else:
259            recursion_insureness(self._traversal_recursive,
260                                 self._traversal_stack_based,
261                                 self._on_switched_to_stack_based_implementation)
262
263
264class KeyMultiValueTreeTraversal:
265    def __init__(self,
266                 tree: AnAppropriateContainers=None,
267                 on_node: Optional[Callable]=None,
268                 on_child: Optional[Callable]=None,
269                 on_switched_to_stack_based_implementation: Optional[Callable]=None
270                 ):
271        self._tree = tree  # type: AnAppropriateContainers
272
273        self._callback_on_node = on_node  # type: Optional[Callable]
274        self._callback_on_child = on_child  # type: Optional[Callable]
275        self._on_switched_to_stack_based_implementation = \
276            on_switched_to_stack_based_implementation  # type: Optional[Callable]
277
278        self._last_tree_node = ValueExistence(False, None)
279        self._last_tree_child = ValueExistence(False, None)
280        self._empty_child = ValueExistence(False, None)
281
282    def set_callback_on_node(self, functor: Optional[Callable]):
283        self._callback_on_node = functor
284
285    def set_callback_on_child(self, functor: Optional[Callable]):
286        self._callback_on_child = functor
287
288    def set_callback_on_both_node_and_child(self, functor: Optional[Callable]):
289        self._callback_on_node = self._callback_on_child = functor
290
291    def set_callback_on_switched_to_stack_based_implementation(self, functor: Optional[Callable]):
292        self._on_switched_to_stack_based_implementation = functor
293
294    @property
295    def tree(self) -> AnAppropriateContainers:
296        return self._tree
297
298    @tree.setter
299    def tree(self, tree: AnAppropriateContainers):
300        self._tree = tree
301
302    def _traversal_recursive(self, initial_key: Hashable):
303        index: Optional[int] = None
304        deep: int = 0
305        self._last_tree_child.value = initial_key
306        if self._callback_on_child:
307            self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
308
309        try:
310            entity = self.tree[initial_key]
311        except KeyError:
312            return
313
314        self._last_tree_node.value = initial_key
315        if self._callback_on_node:
316            self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
317
318        entity = data_2_ordered(entity)
319        self._traversal_recursive_impl(entity, deep, index)
320
321    def _traversal_recursive_impl(self, entity: AnAppropriateContainers, deep: int = 0, index: Optional[int] = None):
322        if isinstance(entity, Contaiters):
323            last_tree_node_bak = self._last_tree_node
324            new_deep = deep + 1
325            for index, item in enumerate(entity):
326                self._traversal_recursive_impl(item, new_deep, index)
327                self._last_tree_node = last_tree_node_bak
328        else:
329            key = entity
330            index: Optional[int] = None
331            deep: int = 0
332            self._last_tree_child.value = key
333            if self._callback_on_child:
334                self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
335            
336            try:
337                entity = self.tree[key]
338            except KeyError:
339                return
340
341            self._last_tree_node.value = key
342            if self._callback_on_node:
343                self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
344
345            entity = data_2_ordered(entity)
346            self._traversal_recursive_impl(entity, deep, index)
347
348    def _traversal_stack_based(self, initial_key: Hashable):
349        raise NotImplementedError
350        index: Optional[int] = None
351        deep: int = 0
352        key: Hashable = initial_key
353        entity = data_2_ordered(self.tree)
354        entity_type: EntityType = findout_entity_type(entity)
355        stack = Stack(TreeStackItem((entity_type, entity, key, deep, index)))
356        while stack:
357            top = stack.top()
358            entity_type, entity, key, deep, index = top.node
359            if EntityType.child == entity_type:
360                self._last_tree_child.value = entity
361                if self._callback_on_child:
362                    self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
363                
364                stack.pop()
365            elif EntityType.sequence == entity_type:
366                self._last_tree_node.value = ValueType(NodeType.sequence, entity)
367                if top.child is None:
368                    child_index = 0
369                    if self._callback_on_node:
370                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
371                else:
372                    child_index = top.child + 1
373                
374                if len(entity) > child_index:
375                    top.child = child_index
376                    child = data_2_ordered(entity[child_index])
377                    child_type = findout_entity_type(child)
378                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
379                else:
380                    stack.pop()
381            elif EntityType.dict_item == entity_type:
382                self._last_tree_node.value = ValueType(NodeType.dict_item, entity)
383                if top.child is None:
384                    child_index = 0
385                    if self._callback_on_node:
386                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
387
388                    top.child = child_index
389                    child = data_2_ordered(entity[1])
390                    child_type = findout_entity_type(child)
391                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
392                else:
393                    stack.pop()
394            elif EntityType.dict == entity_type:
395                self._last_tree_node.value = ValueType(NodeType.dict, entity.dict)
396                if top.child is None:
397                    child_index = 0
398                    if self._callback_on_node:
399                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
400                else:
401                    child_index = top.child + 1
402                
403                if len(entity.items) > child_index:
404                    top.child = child_index
405                    child = entity.items[child_index]
406                    stack.push(TreeStackItem((EntityType.dict_item, child, deep + 1, child_index)))
407                else:
408                    stack.pop()
409
410    def __call__(self, initial_key: Hashable, traversal_type: TreeTraversalType=TreeTraversalType.recursive_with_stack_based_insureness):
411        if TreeTraversalType.recursive == traversal_type:
412            self._traversal_recursive(initial_key)
413        elif TreeTraversalType.stack_based == traversal_type:
414            self._traversal_stack_based(initial_key)
415        else:
416            recursive = partial(self._traversal_recursive, initial_key)
417            stack_based = partial(self._traversal_stack_based, initial_key)
418            recursion_insureness(recursive,
419                                 stack_based,
420                                 self._on_switched_to_stack_based_implementation)
421
422
423class KeyValueTreeTraversal:
424    def __init__(self,
425                 tree: AnAppropriateContainers=None,
426                 on_node: Optional[Callable]=None,
427                 on_child: Optional[Callable]=None,
428                 on_switched_to_stack_based_implementation: Optional[Callable]=None
429                 ):
430        self._tree = tree  # type: AnAppropriateContainers
431
432        self._callback_on_node = on_node  # type: Optional[Callable]
433        self._callback_on_child = on_child  # type: Optional[Callable]
434        self._on_switched_to_stack_based_implementation = \
435            on_switched_to_stack_based_implementation  # type: Optional[Callable]
436
437        self._last_tree_node = ValueExistence(False, None)
438        self._last_tree_child = ValueExistence(False, None)
439        self._empty_child = ValueExistence(False, None)
440
441    def set_callback_on_node(self, functor: Optional[Callable]):
442        self._callback_on_node = functor
443
444    def set_callback_on_child(self, functor: Optional[Callable]):
445        self._callback_on_child = functor
446
447    def set_callback_on_both_node_and_child(self, functor: Optional[Callable]):
448        self._callback_on_node = self._callback_on_child = functor
449
450    def set_callback_on_switched_to_stack_based_implementation(self, functor: Optional[Callable]):
451        self._on_switched_to_stack_based_implementation = functor
452
453    @property
454    def tree(self) -> AnAppropriateContainers:
455        return self._tree
456
457    @tree.setter
458    def tree(self, tree: AnAppropriateContainers):
459        self._tree = tree
460
461    def _traversal_recursive(self, initial_key: Hashable):
462        index: Optional[int] = None
463        deep: int = 0
464        self._last_tree_child.value = initial_key
465        if self._callback_on_child:
466            self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
467
468        try:
469            entity = self.tree[initial_key]
470        except KeyError:
471            return
472
473        self._last_tree_node.value = initial_key
474        if self._callback_on_node:
475            self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
476
477        self._traversal_recursive_impl(entity, deep + 1, index)
478
479    def _traversal_recursive_impl(self, entity: AnAppropriateContainers, deep: int = 0, index: Optional[int] = None):
480        key = entity
481        index: Optional[int] = None
482        deep: int = 0
483        self._last_tree_child.value = key
484        if self._callback_on_child:
485            self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
486        
487        try:
488            entity = self.tree[key]
489        except KeyError:
490            return
491
492        self._last_tree_node.value = key
493        if self._callback_on_node:
494            self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
495
496        self._traversal_recursive_impl(entity, deep + 1, index)
497
498    def _traversal_stack_based(self, initial_key: Hashable):
499        raise NotImplementedError
500        index: Optional[int] = None
501        deep: int = 0
502        key: Hashable = initial_key
503        entity = data_2_ordered(self.tree)
504        entity_type: EntityType = findout_entity_type(entity)
505        stack = Stack(TreeStackItem((entity_type, entity, key, deep, index)))
506        while stack:
507            top = stack.top()
508            entity_type, entity, key, deep, index = top.node
509            if EntityType.child == entity_type:
510                self._last_tree_child.value = entity
511                if self._callback_on_child:
512                    self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
513                
514                stack.pop()
515            elif EntityType.sequence == entity_type:
516                self._last_tree_node.value = ValueType(NodeType.sequence, entity)
517                if top.child is None:
518                    child_index = 0
519                    if self._callback_on_node:
520                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
521                else:
522                    child_index = top.child + 1
523                
524                if len(entity) > child_index:
525                    top.child = child_index
526                    child = data_2_ordered(entity[child_index])
527                    child_type = findout_entity_type(child)
528                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
529                else:
530                    stack.pop()
531            elif EntityType.dict_item == entity_type:
532                self._last_tree_node.value = ValueType(NodeType.dict_item, entity)
533                if top.child is None:
534                    child_index = 0
535                    if self._callback_on_node:
536                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
537
538                    top.child = child_index
539                    child = data_2_ordered(entity[1])
540                    child_type = findout_entity_type(child)
541                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
542                else:
543                    stack.pop()
544            elif EntityType.dict == entity_type:
545                self._last_tree_node.value = ValueType(NodeType.dict, entity.dict)
546                if top.child is None:
547                    child_index = 0
548                    if self._callback_on_node:
549                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
550                else:
551                    child_index = top.child + 1
552                
553                if len(entity.items) > child_index:
554                    top.child = child_index
555                    child = entity.items[child_index]
556                    stack.push(TreeStackItem((EntityType.dict_item, child, deep + 1, child_index)))
557                else:
558                    stack.pop()
559
560    def __call__(self, initial_key: Hashable, traversal_type: TreeTraversalType=TreeTraversalType.recursive_with_stack_based_insureness):
561        if TreeTraversalType.recursive == traversal_type:
562            self._traversal_recursive(initial_key)
563        elif TreeTraversalType.stack_based == traversal_type:
564            self._traversal_stack_based(initial_key)
565        else:
566            recursive = partial(self._traversal_recursive, initial_key)
567            stack_based = partial(self._traversal_stack_based, initial_key)
568            recursion_insureness(recursive,
569                                 stack_based,
570                                 self._on_switched_to_stack_based_implementation)
AnAppropriateValues = typing.Union[str, bytes, int, float, NoneType]
AllPossibleValues = typing.Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]
AnAppropriateContainers = typing.Union[typing.Dict[typing.Union[str, bytes, int, float, NoneType], typing.Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], typing.Set[typing.Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], typing.List[typing.Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], typing.Tuple[typing.Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]]
class TupledDict:
56class TupledDict:
57    def __init__(self, data: Dict) -> None:
58        self.dict: Dict = data
59        self.items: Tuple[Tuple[Hashable, Any]] = tuple(data.items())
TupledDict(data: Dict)
57    def __init__(self, data: Dict) -> None:
58        self.dict: Dict = data
59        self.items: Tuple[Tuple[Hashable, Any]] = tuple(data.items())
dict: Dict
items: Tuple[Tuple[Hashable, Any]]
Contaiters = (<class 'TupledDict'>, <class 'dict'>, <class 'tuple'>, <class 'list'>, <class 'set'>, <class 'collections.deque'>)
def data_2_tuple( data: Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]) -> Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]:
65def data_2_tuple(data: AllPossibleValues) -> AllPossibleValues:
66    if isinstance(data, Contaiters):
67        if isinstance(data, dict):
68            return tuple(data.values())
69        elif isinstance(data, (tuple, list, deque)):
70            return data
71        elif isinstance(data, set):
72            return tuple(data)
73    else:
74        return data
def data_2_ordered( data: Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]) -> Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]:
77def data_2_ordered(data: AllPossibleValues) -> AllPossibleValues:
78    if isinstance(data, Contaiters):
79        if isinstance(data, dict):
80            return TupledDict(data)
81        elif isinstance(data, set):
82            return tuple(data)
83        else:
84            return data
85    else:
86        return data
class TreeTraversalType(enum.Enum):
89class TreeTraversalType(Enum):
90    recursive = 0
91    stack_based = 1
92    recursive_with_stack_based_insureness = 2

An enumeration.

recursive = <TreeTraversalType.recursive: 0>
stack_based = <TreeTraversalType.stack_based: 1>
recursive_with_stack_based_insureness = <TreeTraversalType.recursive_with_stack_based_insureness: 2>
Inherited Members
enum.Enum
name
value
class NodeType(enum.Enum):
95class NodeType(Enum):
96    dict = 0
97    dict_item = 1
98    sequence = 2

An enumeration.

dict = <NodeType.dict: 0>
dict_item = <NodeType.dict_item: 1>
sequence = <NodeType.sequence: 2>
Inherited Members
enum.Enum
name
value
class EntityType(enum.Enum):
101class EntityType(Enum):
102    dict = 0
103    dict_item = 1
104    sequence = 2
105    child = 3

An enumeration.

dict = <EntityType.dict: 0>
dict_item = <EntityType.dict_item: 1>
sequence = <EntityType.sequence: 2>
child = <EntityType.child: 3>
Inherited Members
enum.Enum
name
value
def findout_entity_type( entity) -> EntityType:
108def findout_entity_type(entity) -> EntityType:
109    if isinstance(entity, Contaiters):
110        if isinstance(entity, TupledDict):
111            entity_type: EntityType = EntityType.dict
112        else:
113            entity_type = EntityType.sequence
114    else:
115        entity_type = EntityType.child
116    
117    return entity_type
class TreeTraversal:
120class TreeTraversal:
121    def __init__(self,
122                 tree: AnAppropriateContainers=None,
123                 on_node: Optional[Callable]=None,
124                 on_child: Optional[Callable]=None,
125                 on_switched_to_stack_based_implementation: Optional[Callable]=None
126                 ):
127        self._tree = tree  # type: AnAppropriateContainers
128
129        self._callback_on_node = on_node  # type: Optional[Callable]
130        self._callback_on_child = on_child  # type: Optional[Callable]
131        self._on_switched_to_stack_based_implementation = \
132            on_switched_to_stack_based_implementation  # type: Optional[Callable]
133
134        self._last_tree_node = ValueExistence(False, None)
135        self._last_tree_child = ValueExistence(False, None)
136        self._empty_child = ValueExistence(False, None)
137
138    def set_callback_on_node(self, functor: Optional[Callable]):
139        self._callback_on_node = functor
140
141    def set_callback_on_child(self, functor: Optional[Callable]):
142        self._callback_on_child = functor
143
144    def set_callback_on_both_node_and_child(self, functor: Optional[Callable]):
145        self._callback_on_node = self._callback_on_child = functor
146
147    def set_callback_on_switched_to_stack_based_implementation(self, functor: Optional[Callable]):
148        self._on_switched_to_stack_based_implementation = functor
149
150    @property
151    def tree(self) -> AnAppropriateContainers:
152        return self._tree
153
154    @tree.setter
155    def tree(self, tree: AnAppropriateContainers):
156        self._tree = tree
157
158    def _traversal_recursive(self):
159        ordered_tree = data_2_ordered(self.tree)
160        self._traversal_recursive_impl(ordered_tree)
161
162    def _traversal_recursive_impl(self, entity: AnAppropriateContainers, deep: int = 0, index: Optional[int] = None):
163        if isinstance(entity, Contaiters):
164            last_tree_node_bak = self._last_tree_node
165            if isinstance(entity, TupledDict):
166                node_type: NodeType = NodeType.dict
167            else:
168                node_type = NodeType.sequence
169            
170            self._last_tree_node.value = ValueType(node_type, entity)
171            if self._callback_on_node:
172                self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
173
174            new_deep = deep + 1
175            if isinstance(entity, TupledDict):
176                value_deep = new_deep + 1
177                for index, node in enumerate(entity.items):
178                    self._last_tree_node.value = ValueType(NodeType.dict_item, node)
179                    if self._callback_on_node:
180                        self._callback_on_node(new_deep, self._last_tree_node, self._empty_child, index)
181                    
182                    item = node[1]
183                    self._traversal_recursive_impl(data_2_ordered(item), value_deep, 0)
184            else:
185                for index, item in enumerate(entity):
186                    self._traversal_recursive_impl(data_2_ordered(item), new_deep, index)
187
188            self._last_tree_node = last_tree_node_bak
189        else:
190            self._last_tree_child.value = entity
191            if self._callback_on_child:
192                self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
193
194    def _traversal_stack_based(self):
195        index: Optional[int] = None
196        deep: int = 0
197        entity = data_2_ordered(self.tree)
198        entity_type: EntityType = findout_entity_type(entity)
199        stack = Stack(TreeStackItem((entity_type, entity, deep, index)))
200        while stack:
201            top = stack.top()
202            entity_type, entity, deep, index = top.node
203            if EntityType.child == entity_type:
204                self._last_tree_child.value = entity
205                if self._callback_on_child:
206                    self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
207                
208                stack.pop()
209            elif EntityType.sequence == entity_type:
210                self._last_tree_node.value = ValueType(NodeType.sequence, entity)
211                if top.child is None:
212                    child_index = 0
213                    if self._callback_on_node:
214                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
215                else:
216                    child_index = top.child + 1
217                
218                if len(entity) > child_index:
219                    top.child = child_index
220                    child = data_2_ordered(entity[child_index])
221                    child_type = findout_entity_type(child)
222                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
223                else:
224                    stack.pop()
225            elif EntityType.dict_item == entity_type:
226                self._last_tree_node.value = ValueType(NodeType.dict_item, entity)
227                if top.child is None:
228                    child_index = 0
229                    if self._callback_on_node:
230                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
231
232                    top.child = child_index
233                    child = data_2_ordered(entity[1])
234                    child_type = findout_entity_type(child)
235                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
236                else:
237                    stack.pop()
238            elif EntityType.dict == entity_type:
239                self._last_tree_node.value = ValueType(NodeType.dict, entity.dict)
240                if top.child is None:
241                    child_index = 0
242                    if self._callback_on_node:
243                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
244                else:
245                    child_index = top.child + 1
246                
247                if len(entity.items) > child_index:
248                    top.child = child_index
249                    child = entity.items[child_index]
250                    stack.push(TreeStackItem((EntityType.dict_item, child, deep + 1, child_index)))
251                else:
252                    stack.pop()
253
254    def __call__(self, traversal_type: TreeTraversalType=TreeTraversalType.recursive_with_stack_based_insureness):
255        if TreeTraversalType.recursive == traversal_type:
256            self._traversal_recursive()
257        elif TreeTraversalType.stack_based == traversal_type:
258            self._traversal_stack_based()
259        else:
260            recursion_insureness(self._traversal_recursive,
261                                 self._traversal_stack_based,
262                                 self._on_switched_to_stack_based_implementation)
TreeTraversal( tree: Union[dict[Union[str, bytes, int, float, NoneType], Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], set[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], list[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], tuple[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]]] = None, on_node: Union[Callable, NoneType] = None, on_child: Union[Callable, NoneType] = None, on_switched_to_stack_based_implementation: Union[Callable, NoneType] = None)
121    def __init__(self,
122                 tree: AnAppropriateContainers=None,
123                 on_node: Optional[Callable]=None,
124                 on_child: Optional[Callable]=None,
125                 on_switched_to_stack_based_implementation: Optional[Callable]=None
126                 ):
127        self._tree = tree  # type: AnAppropriateContainers
128
129        self._callback_on_node = on_node  # type: Optional[Callable]
130        self._callback_on_child = on_child  # type: Optional[Callable]
131        self._on_switched_to_stack_based_implementation = \
132            on_switched_to_stack_based_implementation  # type: Optional[Callable]
133
134        self._last_tree_node = ValueExistence(False, None)
135        self._last_tree_child = ValueExistence(False, None)
136        self._empty_child = ValueExistence(False, None)
def set_callback_on_node(self, functor: Union[Callable, NoneType]):
138    def set_callback_on_node(self, functor: Optional[Callable]):
139        self._callback_on_node = functor
def set_callback_on_child(self, functor: Union[Callable, NoneType]):
141    def set_callback_on_child(self, functor: Optional[Callable]):
142        self._callback_on_child = functor
def set_callback_on_both_node_and_child(self, functor: Union[Callable, NoneType]):
144    def set_callback_on_both_node_and_child(self, functor: Optional[Callable]):
145        self._callback_on_node = self._callback_on_child = functor
def set_callback_on_switched_to_stack_based_implementation(self, functor: Union[Callable, NoneType]):
147    def set_callback_on_switched_to_stack_based_implementation(self, functor: Optional[Callable]):
148        self._on_switched_to_stack_based_implementation = functor
tree: Union[dict[Union[str, bytes, int, float, NoneType], Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], set[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], list[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], tuple[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]]]
150    @property
151    def tree(self) -> AnAppropriateContainers:
152        return self._tree
class KeyMultiValueTreeTraversal:
265class KeyMultiValueTreeTraversal:
266    def __init__(self,
267                 tree: AnAppropriateContainers=None,
268                 on_node: Optional[Callable]=None,
269                 on_child: Optional[Callable]=None,
270                 on_switched_to_stack_based_implementation: Optional[Callable]=None
271                 ):
272        self._tree = tree  # type: AnAppropriateContainers
273
274        self._callback_on_node = on_node  # type: Optional[Callable]
275        self._callback_on_child = on_child  # type: Optional[Callable]
276        self._on_switched_to_stack_based_implementation = \
277            on_switched_to_stack_based_implementation  # type: Optional[Callable]
278
279        self._last_tree_node = ValueExistence(False, None)
280        self._last_tree_child = ValueExistence(False, None)
281        self._empty_child = ValueExistence(False, None)
282
283    def set_callback_on_node(self, functor: Optional[Callable]):
284        self._callback_on_node = functor
285
286    def set_callback_on_child(self, functor: Optional[Callable]):
287        self._callback_on_child = functor
288
289    def set_callback_on_both_node_and_child(self, functor: Optional[Callable]):
290        self._callback_on_node = self._callback_on_child = functor
291
292    def set_callback_on_switched_to_stack_based_implementation(self, functor: Optional[Callable]):
293        self._on_switched_to_stack_based_implementation = functor
294
295    @property
296    def tree(self) -> AnAppropriateContainers:
297        return self._tree
298
299    @tree.setter
300    def tree(self, tree: AnAppropriateContainers):
301        self._tree = tree
302
303    def _traversal_recursive(self, initial_key: Hashable):
304        index: Optional[int] = None
305        deep: int = 0
306        self._last_tree_child.value = initial_key
307        if self._callback_on_child:
308            self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
309
310        try:
311            entity = self.tree[initial_key]
312        except KeyError:
313            return
314
315        self._last_tree_node.value = initial_key
316        if self._callback_on_node:
317            self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
318
319        entity = data_2_ordered(entity)
320        self._traversal_recursive_impl(entity, deep, index)
321
322    def _traversal_recursive_impl(self, entity: AnAppropriateContainers, deep: int = 0, index: Optional[int] = None):
323        if isinstance(entity, Contaiters):
324            last_tree_node_bak = self._last_tree_node
325            new_deep = deep + 1
326            for index, item in enumerate(entity):
327                self._traversal_recursive_impl(item, new_deep, index)
328                self._last_tree_node = last_tree_node_bak
329        else:
330            key = entity
331            index: Optional[int] = None
332            deep: int = 0
333            self._last_tree_child.value = key
334            if self._callback_on_child:
335                self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
336            
337            try:
338                entity = self.tree[key]
339            except KeyError:
340                return
341
342            self._last_tree_node.value = key
343            if self._callback_on_node:
344                self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
345
346            entity = data_2_ordered(entity)
347            self._traversal_recursive_impl(entity, deep, index)
348
349    def _traversal_stack_based(self, initial_key: Hashable):
350        raise NotImplementedError
351        index: Optional[int] = None
352        deep: int = 0
353        key: Hashable = initial_key
354        entity = data_2_ordered(self.tree)
355        entity_type: EntityType = findout_entity_type(entity)
356        stack = Stack(TreeStackItem((entity_type, entity, key, deep, index)))
357        while stack:
358            top = stack.top()
359            entity_type, entity, key, deep, index = top.node
360            if EntityType.child == entity_type:
361                self._last_tree_child.value = entity
362                if self._callback_on_child:
363                    self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
364                
365                stack.pop()
366            elif EntityType.sequence == entity_type:
367                self._last_tree_node.value = ValueType(NodeType.sequence, entity)
368                if top.child is None:
369                    child_index = 0
370                    if self._callback_on_node:
371                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
372                else:
373                    child_index = top.child + 1
374                
375                if len(entity) > child_index:
376                    top.child = child_index
377                    child = data_2_ordered(entity[child_index])
378                    child_type = findout_entity_type(child)
379                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
380                else:
381                    stack.pop()
382            elif EntityType.dict_item == entity_type:
383                self._last_tree_node.value = ValueType(NodeType.dict_item, entity)
384                if top.child is None:
385                    child_index = 0
386                    if self._callback_on_node:
387                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
388
389                    top.child = child_index
390                    child = data_2_ordered(entity[1])
391                    child_type = findout_entity_type(child)
392                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
393                else:
394                    stack.pop()
395            elif EntityType.dict == entity_type:
396                self._last_tree_node.value = ValueType(NodeType.dict, entity.dict)
397                if top.child is None:
398                    child_index = 0
399                    if self._callback_on_node:
400                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
401                else:
402                    child_index = top.child + 1
403                
404                if len(entity.items) > child_index:
405                    top.child = child_index
406                    child = entity.items[child_index]
407                    stack.push(TreeStackItem((EntityType.dict_item, child, deep + 1, child_index)))
408                else:
409                    stack.pop()
410
411    def __call__(self, initial_key: Hashable, traversal_type: TreeTraversalType=TreeTraversalType.recursive_with_stack_based_insureness):
412        if TreeTraversalType.recursive == traversal_type:
413            self._traversal_recursive(initial_key)
414        elif TreeTraversalType.stack_based == traversal_type:
415            self._traversal_stack_based(initial_key)
416        else:
417            recursive = partial(self._traversal_recursive, initial_key)
418            stack_based = partial(self._traversal_stack_based, initial_key)
419            recursion_insureness(recursive,
420                                 stack_based,
421                                 self._on_switched_to_stack_based_implementation)
KeyMultiValueTreeTraversal( tree: Union[dict[Union[str, bytes, int, float, NoneType], Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], set[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], list[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], tuple[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]]] = None, on_node: Union[Callable, NoneType] = None, on_child: Union[Callable, NoneType] = None, on_switched_to_stack_based_implementation: Union[Callable, NoneType] = None)
266    def __init__(self,
267                 tree: AnAppropriateContainers=None,
268                 on_node: Optional[Callable]=None,
269                 on_child: Optional[Callable]=None,
270                 on_switched_to_stack_based_implementation: Optional[Callable]=None
271                 ):
272        self._tree = tree  # type: AnAppropriateContainers
273
274        self._callback_on_node = on_node  # type: Optional[Callable]
275        self._callback_on_child = on_child  # type: Optional[Callable]
276        self._on_switched_to_stack_based_implementation = \
277            on_switched_to_stack_based_implementation  # type: Optional[Callable]
278
279        self._last_tree_node = ValueExistence(False, None)
280        self._last_tree_child = ValueExistence(False, None)
281        self._empty_child = ValueExistence(False, None)
def set_callback_on_node(self, functor: Union[Callable, NoneType]):
283    def set_callback_on_node(self, functor: Optional[Callable]):
284        self._callback_on_node = functor
def set_callback_on_child(self, functor: Union[Callable, NoneType]):
286    def set_callback_on_child(self, functor: Optional[Callable]):
287        self._callback_on_child = functor
def set_callback_on_both_node_and_child(self, functor: Union[Callable, NoneType]):
289    def set_callback_on_both_node_and_child(self, functor: Optional[Callable]):
290        self._callback_on_node = self._callback_on_child = functor
def set_callback_on_switched_to_stack_based_implementation(self, functor: Union[Callable, NoneType]):
292    def set_callback_on_switched_to_stack_based_implementation(self, functor: Optional[Callable]):
293        self._on_switched_to_stack_based_implementation = functor
tree: Union[dict[Union[str, bytes, int, float, NoneType], Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], set[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], list[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], tuple[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]]]
295    @property
296    def tree(self) -> AnAppropriateContainers:
297        return self._tree
class KeyValueTreeTraversal:
424class KeyValueTreeTraversal:
425    def __init__(self,
426                 tree: AnAppropriateContainers=None,
427                 on_node: Optional[Callable]=None,
428                 on_child: Optional[Callable]=None,
429                 on_switched_to_stack_based_implementation: Optional[Callable]=None
430                 ):
431        self._tree = tree  # type: AnAppropriateContainers
432
433        self._callback_on_node = on_node  # type: Optional[Callable]
434        self._callback_on_child = on_child  # type: Optional[Callable]
435        self._on_switched_to_stack_based_implementation = \
436            on_switched_to_stack_based_implementation  # type: Optional[Callable]
437
438        self._last_tree_node = ValueExistence(False, None)
439        self._last_tree_child = ValueExistence(False, None)
440        self._empty_child = ValueExistence(False, None)
441
442    def set_callback_on_node(self, functor: Optional[Callable]):
443        self._callback_on_node = functor
444
445    def set_callback_on_child(self, functor: Optional[Callable]):
446        self._callback_on_child = functor
447
448    def set_callback_on_both_node_and_child(self, functor: Optional[Callable]):
449        self._callback_on_node = self._callback_on_child = functor
450
451    def set_callback_on_switched_to_stack_based_implementation(self, functor: Optional[Callable]):
452        self._on_switched_to_stack_based_implementation = functor
453
454    @property
455    def tree(self) -> AnAppropriateContainers:
456        return self._tree
457
458    @tree.setter
459    def tree(self, tree: AnAppropriateContainers):
460        self._tree = tree
461
462    def _traversal_recursive(self, initial_key: Hashable):
463        index: Optional[int] = None
464        deep: int = 0
465        self._last_tree_child.value = initial_key
466        if self._callback_on_child:
467            self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
468
469        try:
470            entity = self.tree[initial_key]
471        except KeyError:
472            return
473
474        self._last_tree_node.value = initial_key
475        if self._callback_on_node:
476            self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
477
478        self._traversal_recursive_impl(entity, deep + 1, index)
479
480    def _traversal_recursive_impl(self, entity: AnAppropriateContainers, deep: int = 0, index: Optional[int] = None):
481        key = entity
482        index: Optional[int] = None
483        deep: int = 0
484        self._last_tree_child.value = key
485        if self._callback_on_child:
486            self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
487        
488        try:
489            entity = self.tree[key]
490        except KeyError:
491            return
492
493        self._last_tree_node.value = key
494        if self._callback_on_node:
495            self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
496
497        self._traversal_recursive_impl(entity, deep + 1, index)
498
499    def _traversal_stack_based(self, initial_key: Hashable):
500        raise NotImplementedError
501        index: Optional[int] = None
502        deep: int = 0
503        key: Hashable = initial_key
504        entity = data_2_ordered(self.tree)
505        entity_type: EntityType = findout_entity_type(entity)
506        stack = Stack(TreeStackItem((entity_type, entity, key, deep, index)))
507        while stack:
508            top = stack.top()
509            entity_type, entity, key, deep, index = top.node
510            if EntityType.child == entity_type:
511                self._last_tree_child.value = entity
512                if self._callback_on_child:
513                    self._callback_on_child(deep, self._last_tree_node, self._last_tree_child, index)
514                
515                stack.pop()
516            elif EntityType.sequence == entity_type:
517                self._last_tree_node.value = ValueType(NodeType.sequence, entity)
518                if top.child is None:
519                    child_index = 0
520                    if self._callback_on_node:
521                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
522                else:
523                    child_index = top.child + 1
524                
525                if len(entity) > child_index:
526                    top.child = child_index
527                    child = data_2_ordered(entity[child_index])
528                    child_type = findout_entity_type(child)
529                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
530                else:
531                    stack.pop()
532            elif EntityType.dict_item == entity_type:
533                self._last_tree_node.value = ValueType(NodeType.dict_item, entity)
534                if top.child is None:
535                    child_index = 0
536                    if self._callback_on_node:
537                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
538
539                    top.child = child_index
540                    child = data_2_ordered(entity[1])
541                    child_type = findout_entity_type(child)
542                    stack.push(TreeStackItem((child_type, child, deep + 1, child_index)))
543                else:
544                    stack.pop()
545            elif EntityType.dict == entity_type:
546                self._last_tree_node.value = ValueType(NodeType.dict, entity.dict)
547                if top.child is None:
548                    child_index = 0
549                    if self._callback_on_node:
550                        self._callback_on_node(deep, self._last_tree_node, self._empty_child, index)
551                else:
552                    child_index = top.child + 1
553                
554                if len(entity.items) > child_index:
555                    top.child = child_index
556                    child = entity.items[child_index]
557                    stack.push(TreeStackItem((EntityType.dict_item, child, deep + 1, child_index)))
558                else:
559                    stack.pop()
560
561    def __call__(self, initial_key: Hashable, traversal_type: TreeTraversalType=TreeTraversalType.recursive_with_stack_based_insureness):
562        if TreeTraversalType.recursive == traversal_type:
563            self._traversal_recursive(initial_key)
564        elif TreeTraversalType.stack_based == traversal_type:
565            self._traversal_stack_based(initial_key)
566        else:
567            recursive = partial(self._traversal_recursive, initial_key)
568            stack_based = partial(self._traversal_stack_based, initial_key)
569            recursion_insureness(recursive,
570                                 stack_based,
571                                 self._on_switched_to_stack_based_implementation)
KeyValueTreeTraversal( tree: Union[dict[Union[str, bytes, int, float, NoneType], Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], set[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], list[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], tuple[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]]] = None, on_node: Union[Callable, NoneType] = None, on_child: Union[Callable, NoneType] = None, on_switched_to_stack_based_implementation: Union[Callable, NoneType] = None)
425    def __init__(self,
426                 tree: AnAppropriateContainers=None,
427                 on_node: Optional[Callable]=None,
428                 on_child: Optional[Callable]=None,
429                 on_switched_to_stack_based_implementation: Optional[Callable]=None
430                 ):
431        self._tree = tree  # type: AnAppropriateContainers
432
433        self._callback_on_node = on_node  # type: Optional[Callable]
434        self._callback_on_child = on_child  # type: Optional[Callable]
435        self._on_switched_to_stack_based_implementation = \
436            on_switched_to_stack_based_implementation  # type: Optional[Callable]
437
438        self._last_tree_node = ValueExistence(False, None)
439        self._last_tree_child = ValueExistence(False, None)
440        self._empty_child = ValueExistence(False, None)
def set_callback_on_node(self, functor: Union[Callable, NoneType]):
442    def set_callback_on_node(self, functor: Optional[Callable]):
443        self._callback_on_node = functor
def set_callback_on_child(self, functor: Union[Callable, NoneType]):
445    def set_callback_on_child(self, functor: Optional[Callable]):
446        self._callback_on_child = functor
def set_callback_on_both_node_and_child(self, functor: Union[Callable, NoneType]):
448    def set_callback_on_both_node_and_child(self, functor: Optional[Callable]):
449        self._callback_on_node = self._callback_on_child = functor
def set_callback_on_switched_to_stack_based_implementation(self, functor: Union[Callable, NoneType]):
451    def set_callback_on_switched_to_stack_based_implementation(self, functor: Optional[Callable]):
452        self._on_switched_to_stack_based_implementation = functor
tree: Union[dict[Union[str, bytes, int, float, NoneType], Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], set[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], list[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]], tuple[Union[Union[Dict[Union[str, bytes, int, float, NoneType], Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Set[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], List[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]], Tuple[Union[ForwardRef('AnAppropriateContainers'), str, bytes, int, float, NoneType]]], str, bytes, int, float, NoneType]]]
454    @property
455    def tree(self) -> AnAppropriateContainers:
456        return self._tree