# Path: anytree/iterators/preorderiter.py
# class PreOrderIter(AbstractIter):
#     """
#     Iterate over tree applying pre-order strategy starting at `node`.
# 
#     Start at root and go-down until reaching a leaf node.
#     Step upwards then, and search for the next leafs.
# 
#     >>> from anytree import Node, RenderTree, AsciiStyle, PreOrderIter
#     >>> f = Node("f")
#     >>> b = Node("b", parent=f)
#     >>> a = Node("a", parent=b)
#     >>> d = Node("d", parent=b)
#     >>> c = Node("c", parent=d)
#     >>> e = Node("e", parent=d)
#     >>> g = Node("g", parent=f)
#     >>> i = Node("i", parent=g)
#     >>> h = Node("h", parent=i)
#     >>> print(RenderTree(f, style=AsciiStyle()).by_attr())
#     f
#     |-- b
#     |   |-- a
#     |   +-- d
#     |       |-- c
#     |       +-- e
#     +-- g
#         +-- i
#             +-- h
#     >>> [node.name for node in PreOrderIter(f)]
#     ['f', 'b', 'a', 'd', 'c', 'e', 'g', 'i', 'h']
#     >>> [node.name for node in PreOrderIter(f, maxlevel=3)]
#     ['f', 'b', 'a', 'd', 'g', 'i']
#     >>> [node.name for node in PreOrderIter(f, filter_=lambda n: n.name not in ('e', 'g'))]
#     ['f', 'b', 'a', 'd', 'c', 'i', 'h']
#     >>> [node.name for node in PreOrderIter(f, stop=lambda n: n.name == 'd')]
#     ['f', 'b', 'a', 'g', 'i', 'h']
#     """
# 
#     @staticmethod
#     def _iter(children, filter_, stop, maxlevel):
#         for child_ in children:
#             if stop(child_):
#                 continue
#             if filter_(child_):
#                 yield child_
#             if not AbstractIter._abort_at_level(2, maxlevel):
#                 descendantmaxlevel = maxlevel - 1 if maxlevel else None
#                 for descendant_ in PreOrderIter._iter(child_.children, filter_, stop, descendantmaxlevel):
#                     yield descendant_
# 
# Path: anytree/node/exceptions.py
# class LoopError(TreeError):
#     """Tree contains infinite loop."""
# 
#     pass
# 
# Path: anytree/node/exceptions.py
# class TreeError(RuntimeError):
#     """Tree Error."""
# 
#     pass


import warnings
from anytree.iterators import PreOrderIter
from .exceptions import LoopError
from .exceptions import TreeError
        Node('/d')
        >>> n.children = [a, b, d]
        >>> n.children
        (Node('/n/a'), Node('/n/b'), Node('/n/d'))
        >>> d
        Node('/n/d')

        **Duplicate**

        A node can just be the children once. Duplicates cause a :any:`TreeError`:

        >>> n.children = [a, b, d, a]
        Traceback (most recent call last):
            ...
        anytree.node.exceptions.TreeError: Cannot add node Node('/n/a') multiple times as child.
        """
        return tuple(self.__children_or_empty)

    @staticmethod
    def __check_children(children):
        seen = set()
        for child in children:
            if not isinstance(child, NodeMixin):
                msg = "Cannot add non-node object %r. It is not a subclass of 'NodeMixin'." % (child, )
                raise TreeError(msg)
            childid = id(child)
            if childid not in seen:
                seen.add(childid)
            else:
                msg = "Cannot add node %r multiple times as child." % (child, )

# Path: anytree/iterators/preorderiter.py
# class PreOrderIter(AbstractIter):
#     """
#     Iterate over tree applying pre-order strategy starting at `node`.
# 
#     Start at root and go-down until reaching a leaf node.
#     Step upwards then, and search for the next leafs.
# 
#     >>> from anytree import Node, RenderTree, AsciiStyle, PreOrderIter
#     >>> f = Node("f")
#     >>> b = Node("b", parent=f)
#     >>> a = Node("a", parent=b)
#     >>> d = Node("d", parent=b)
#     >>> c = Node("c", parent=d)
#     >>> e = Node("e", parent=d)
#     >>> g = Node("g", parent=f)
#     >>> i = Node("i", parent=g)
#     >>> h = Node("h", parent=i)
#     >>> print(RenderTree(f, style=AsciiStyle()).by_attr())
#     f
#     |-- b
#     |   |-- a
#     |   +-- d
#     |       |-- c
#     |       +-- e
#     +-- g
#         +-- i
#             +-- h
#     >>> [node.name for node in PreOrderIter(f)]
#     ['f', 'b', 'a', 'd', 'c', 'e', 'g', 'i', 'h']
#     >>> [node.name for node in PreOrderIter(f, maxlevel=3)]
#     ['f', 'b', 'a', 'd', 'g', 'i']
#     >>> [node.name for node in PreOrderIter(f, filter_=lambda n: n.name not in ('e', 'g'))]
#     ['f', 'b', 'a', 'd', 'c', 'i', 'h']
#     >>> [node.name for node in PreOrderIter(f, stop=lambda n: n.name == 'd')]
#     ['f', 'b', 'a', 'g', 'i', 'h']
#     """
# 
#     @staticmethod
#     def _iter(children, filter_, stop, maxlevel):
#         for child_ in children:
#             if stop(child_):
#                 continue
#             if filter_(child_):
#                 yield child_
#             if not AbstractIter._abort_at_level(2, maxlevel):
#                 descendantmaxlevel = maxlevel - 1 if maxlevel else None
#                 for descendant_ in PreOrderIter._iter(child_.children, filter_, stop, descendantmaxlevel):
#                     yield descendant_
# 
# Path: anytree/node/exceptions.py
# class LoopError(TreeError):
#     """Tree contains infinite loop."""
# 
#     pass
# 
# Path: anytree/node/exceptions.py
# class TreeError(RuntimeError):
#     """Tree Error."""
# 
#     pass


# Path: anytree/node/nodemixin.py
import warnings
from anytree.iterators import PreOrderIter
from .exceptions import LoopError
from .exceptions import TreeError

        Node('/d')
        >>> n.children = [a, b, d]
        >>> n.children
        (Node('/n/a'), Node('/n/b'), Node('/n/d'))
        >>> d
        Node('/n/d')

        **Duplicate**

        A node can just be the children once. Duplicates cause a :any:`TreeError`:

        >>> n.children = [a, b, d, a]
        Traceback (most recent call last):
            ...
        anytree.node.exceptions.TreeError: Cannot add node Node('/n/a') multiple times as child.
        """
        return tuple(self.__children_or_empty)

    @staticmethod
    def __check_children(children):
        seen = set()
        for child in children:
            if not isinstance(child, NodeMixin):
                msg = "Cannot add non-node object %r. It is not a subclass of 'NodeMixin'." % (child, )
                raise TreeError(msg)
            childid = id(child)
            if childid not in seen:
                seen.add(childid)
            else:
                msg = "Cannot add node %r multiple times as child." % (child, )

                raise TreeError(msg)