
    i)?                     @    S SK Jr  S SKJr  SSKJrJr   " S S5      rg)    )
ASSERTIONS)PreOrderIter   )	LoopError	TreeErrorc                      \ rS rSrSrSS/rSr\S 5       r\R                  S 5       rS r
S	 rS
 r\S 5       r\S 5       r\S 5       r\R                  S 5       r\R"                  S 5       rS rS rS rS r\S 5       rS r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r \S 5       r!\S  5       r"S! r#S" r$S# r%S$ r&S%r'g&)'LightNodeMixin   u  
The :any:`LightNodeMixin` behaves identical to :any:`NodeMixin`, but uses `__slots__`.

There are some minor differences in the object behaviour.
See slots_ for any details.

.. _slots: https://docs.python.org/3/reference/datamodel.html#slots

The only tree relevant information is the `parent` attribute.
If `None` the :any:`LightNodeMixin` is root node.
If set to another node, the :any:`LightNodeMixin` becomes the child of it.

The `children` attribute can be used likewise.
If `None` the :any:`LightNodeMixin` has no children.
The `children` attribute can be set to any iterable of :any:`LightNodeMixin` instances.
These instances become children of the node.

>>> from anytree import LightNodeMixin, RenderTree
>>> class MyBaseClass():  # Just an example of a base class
...     __slots__ = []
>>> class MyClass(MyBaseClass, LightNodeMixin):  # Add Node feature
...     __slots__ = ['name', 'length', 'width']
...     def __init__(self, name, length, width, parent=None, children=None):
...         super().__init__()
...         self.name = name
...         self.length = length
...         self.width = width
...         self.parent = parent
...         if children:
...             self.children = children

Construction via `parent`:

>>> my0 = MyClass('my0', 0, 0)
>>> my1 = MyClass('my1', 1, 0, parent=my0)
>>> my2 = MyClass('my2', 0, 2, parent=my0)

>>> for pre, _, node in RenderTree(my0):
...     treestr = u"%s%s" % (pre, node.name)
...     print(treestr.ljust(8), node.length, node.width)
my0      0 0
├── my1  1 0
└── my2  0 2

Construction via `children`:

>>> my0 = MyClass('my0', 0, 0, children=[
...     MyClass('my1', 1, 0),
...     MyClass('my2', 0, 2),
... ])

>>> for pre, _, node in RenderTree(my0):
...     treestr = u"%s%s" % (pre, node.name)
...     print(treestr.ljust(8), node.length, node.width)
my0      0 0
├── my1  1 0
└── my2  0 2

Both approaches can be mixed:

>>> my0 = MyClass('my0', 0, 0, children=[
...     MyClass('my1', 1, 0),
... ])
>>> my2 = MyClass('my2', 0, 2, parent=my0)

>>> for pre, _, node in RenderTree(my0):
...     treestr = u"%s%s" % (pre, node.name)
...     print(treestr.ljust(8), node.length, node.width)
my0      0 0
├── my1  1 0
└── my2  0 2

__children__parent/c                 >    [        U S5      (       a  U R                  $ g)ut  
Parent Node.

On set, the node is detached from any previous parent node and attached
to the new node.

>>> from anytree import Node, RenderTree
>>> udo = Node("Udo")
>>> marc = Node("Marc")
>>> lian = Node("Lian", parent=marc)
>>> print(RenderTree(udo))
Node('/Udo')
>>> print(RenderTree(marc))
Node('/Marc')
└── Node('/Marc/Lian')

**Attach**

>>> marc.parent = udo
>>> print(RenderTree(udo))
Node('/Udo')
└── Node('/Udo/Marc')
    └── Node('/Udo/Marc/Lian')

**Detach**

To make a node to a root node, just set this attribute to `None`.

>>> marc.is_root
False
>>> marc.parent = None
>>> marc.is_root
True
_LightNodeMixin__parentN)hasattrr   selfs    H/app/mltbenv/lib/python3.13/site-packages/anytree/node/lightnodemixin.pyparentLightNodeMixin.parentU   s     H 4233==     c                     [        U S5      (       a  U R                  nOS nX!La4  U R                  U5        U R                  U5        U R	                  U5        g g )Nr   )r   r   _LightNodeMixin__check_loop_LightNodeMixin__detach_LightNodeMixin__attach)r   valuer   s      r   r   r   }   sO    4233]]FFe$MM&!MM%  r   c                    ^  UbQ  UT L a  Sn[        UT 4-  5      e[        U 4S jUR                  5        5       5      (       a  Sn[        UT U4-  5      eg g )Nz1Cannot set parent. %r cannot be parent of itself.c              3   *   >#    U  H  oTL v   M
     g 7fN .0childr   s     r   	<genexpr>.LightNodeMixin.__check_loop.<locals>.<genexpr>   s     G.FUD=.F   z&Cannot set parent. %r is parent of %r.)r   anyiter_path_reverse)r   nodemsgs   `  r   __check_loopLightNodeMixin.__check_loop   sd    t|Itg..Gd.D.D.FGGG>tTl 233 H	 r   c                   ^  Ub  T R                  U5        UR                  n[        (       a!  [        U 4S jU 5       5      (       d   S5       eU Vs/ s H  o3T Ld  M	  UPM     snUl        S T l        T R                  U5        g g s  snf )Nc              3   *   >#    U  H  oTL v   M
     g 7fr   r   r    s     r   r#   *LightNodeMixin.__detach.<locals>.<genexpr>   s     EnUD=nr%   Tree is corrupt.)_pre_detach"_LightNodeMixin__children_or_emptyr   r&   _LightNodeMixin__childrenr   _post_detach)r   r   parentchildrenr"   s   `   r   __detachLightNodeMixin.__detach   s    V$#77NzEnEEEYGYYE4B XN5SWFWN XF DMf%  !Ys   BBc                    ^  Ubs  T R                  U5        UR                  n[        (       a!  [        U 4S jU 5       5      (       a   S5       eUR	                  T 5        UT l        T R                  U5        g g )Nc              3   *   >#    U  H  oTL v   M
     g 7fr   r   r    s     r   r#   *LightNodeMixin.__attach.<locals>.<genexpr>   s     I.}.r%   r/   )_pre_attachr1   r   r&   appendr   _post_attach)r   r   r4   s   `  r   __attachLightNodeMixin.__attach   sl    V$#77NzI.III]K]]I!!$'"DMf% r   c                 J    [        U S5      (       d  / U l        U R                  $ )Nr2   )r   r2   r   s    r   __children_or_empty"LightNodeMixin.__children_or_empty   s!    t899 DOr   c                 ,    [        U R                  5      $ )a  
All child nodes.

>>> from anytree import Node
>>> n = Node("n")
>>> a = Node("a", parent=n)
>>> b = Node("b", parent=n)
>>> c = Node("c", parent=n)
>>> n.children
(Node('/n/a'), Node('/n/b'), Node('/n/c'))

Modifying the children attribute modifies the tree.

**Detach**

The children attribute can be updated by setting to an iterable.

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

Node `c` is removed from the tree.
In case of an existing reference, the node `c` does not vanish and is the root of its own tree.

>>> c
Node('/c')

**Attach**

>>> d = Node("d")
>>> d
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.
)tupler1   r   s    r   childrenLightNodeMixin.children   s    b T--..r   c                     [        5       nU  H6  n[        U5      nX1;  a  UR                  U5        M&  SU< S3n[        U5      e   g )NzCannot add node z multiple times as child.)setidaddr   )rD   seenr"   childidr)   s        r   __check_childrenLightNodeMixin.__check_children   sG    uEiG"!(	1JKn$ r   c                 N   [        U5      n[        R                  U5        U R                  nU ? U R	                  U5        U H	  nXl        M     U R                  U5        [        (       a%  [        U R                  5      [        U5      :X  d   eg g ! [         a    X l        e f = fr   )
rC   r	   _LightNodeMixin__check_childrenrD   _pre_attach_childrenr   _post_attach_childrenr   len	Exception)r   rD   old_childrenr"   s       r   rD   rE      s     ?''1}}M		%%h/!# "&&x0z4==)S]:::  	(M	s   A B B$c                     U R                   nU R                  U5        U R                    H
  nS Ul        M     [        (       a  [	        U R                   5      S:X  d   eU R                  U5        g )Nr   )rD   _pre_detach_childrenr   r   rR   _post_detach_children)r   rD   r"   s      r   rD   rE     sX    ==!!(+]]EEL #:t}}%***""8,r   c                     g)z(Method call before detaching `children`.Nr   r   rD   s     r   rV   #LightNodeMixin._pre_detach_children      r   c                     g)z'Method call after detaching `children`.Nr   rY   s     r   rW   $LightNodeMixin._post_detach_children  r[   r   c                     g)z(Method call before attaching `children`.Nr   rY   s     r   rP   #LightNodeMixin._pre_attach_children  r[   r   c                     g)z'Method call after attaching `children`.Nr   rY   s     r   rQ   $LightNodeMixin._post_attach_children  r[   r   c                     U R                   $ )a<  
Path from root node down to this `Node`.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.path
(Node('/Udo'),)
>>> marc.path
(Node('/Udo'), Node('/Udo/Marc'))
>>> lian.path
(Node('/Udo'), Node('/Udo/Marc'), Node('/Udo/Marc/Lian'))
)_pathr   s    r   pathLightNodeMixin.path  s      zzr   c              #   B   #    U nUb  Uv   UR                   nUb  M  gg7f)a  
Iterate up the tree from the current node to the root node.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> for node in udo.iter_path_reverse():
...     print(node)
Node('/Udo')
>>> for node in marc.iter_path_reverse():
...     print(node)
Node('/Udo/Marc')
Node('/Udo')
>>> for node in lian.iter_path_reverse():
...     print(node)
Node('/Udo/Marc/Lian')
Node('/Udo/Marc')
Node('/Udo')
Nr   r   r(   s     r   r'    LightNodeMixin.iter_path_reverse+  s(     * J;;D s   c                 X    [        [        [        U R                  5       5      5      5      $ r   )rC   reversedlistr'   r   s    r   rc   LightNodeMixin._pathE  s     Xd4#9#9#;<=>>r   c                 J    U R                   c  gU R                   R                  $ )a  
All parent nodes and their parent nodes.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.ancestors
()
>>> marc.ancestors
(Node('/Udo'),)
>>> lian.ancestors
(Node('/Udo'), Node('/Udo/Marc'))
r   )r   rd   r   s    r   	ancestorsLightNodeMixin.ancestorsI  s!      ;;{{r   c                 0    [        [        U 5      5      SS $ )a  
All child nodes and all their child nodes.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> loui = Node("Loui", parent=marc)
>>> soe = Node("Soe", parent=lian)
>>> udo.descendants
(Node('/Udo/Marc'), Node('/Udo/Marc/Lian'), Node('/Udo/Marc/Lian/Soe'), Node('/Udo/Marc/Loui'))
>>> marc.descendants
(Node('/Udo/Marc/Lian'), Node('/Udo/Marc/Lian/Soe'), Node('/Udo/Marc/Loui'))
>>> lian.descendants
(Node('/Udo/Marc/Lian/Soe'),)
r   NrC   r   r   s    r   descendantsLightNodeMixin.descendants]  s    $ \$'(,,r   c                 Z    U nUR                   b  UR                   nUR                   b  M  U$ )z
Tree Root Node.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.root
Node('/Udo')
>>> marc.root
Node('/Udo')
>>> lian.root
Node('/Udo')
rg   rh   s     r   rootLightNodeMixin.rootq  s-      kk%;;D kk%r   c                 b   ^  T R                   nUc  g[        U 4S jUR                   5       5      $ )a  
Tuple of nodes with the same parent.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> loui = Node("Loui", parent=marc)
>>> lazy = Node("Lazy", parent=marc)
>>> udo.siblings
()
>>> marc.siblings
()
>>> lian.siblings
(Node('/Udo/Marc/Loui'), Node('/Udo/Marc/Lazy'))
>>> loui.siblings
(Node('/Udo/Marc/Lian'), Node('/Udo/Marc/Lazy'))
r   c              3   4   >#    U  H  oTLd  M	  Uv   M     g 7fr   r   )r!   r(   r   s     r   r#   *LightNodeMixin.siblings.<locals>.<genexpr>  s     JodT9ITTos   	)r   rC   rD   r   r   s   ` r   siblingsLightNodeMixin.siblings  s+    ( >JfooJJJr   c                 *    [        [        U S S95      $ )a  
Tuple of all leaf nodes.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> loui = Node("Loui", parent=marc)
>>> lazy = Node("Lazy", parent=marc)
>>> udo.leaves
(Node('/Udo/Marc/Lian'), Node('/Udo/Marc/Loui'), Node('/Udo/Marc/Lazy'))
>>> marc.leaves
(Node('/Udo/Marc/Lian'), Node('/Udo/Marc/Loui'), Node('/Udo/Marc/Lazy'))
c                     U R                   $ r   )is_leaf)r(   s    r   <lambda>'LightNodeMixin.leaves.<locals>.<lambda>  s    T\\r   )filter_rr   r   s    r   leavesLightNodeMixin.leaves  s      \$0IJKKr   c                 2    [        U R                  5      S:H  $ )z
`Node` has no children (External Node).

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.is_leaf
False
>>> marc.is_leaf
False
>>> lian.is_leaf
True
r   )rR   r1   r   s    r   r   LightNodeMixin.is_leaf  s      4++,11r   c                     U R                   SL $ )z
`Node` is tree root.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.is_root
True
>>> marc.is_root
False
>>> lian.is_root
False
Nrg   r   s    r   is_rootLightNodeMixin.is_root  s      {{d""r   c                 T    U R                   nU(       a  [        S U 5       5      S-   $ g)z
Number of edges on the longest path to a leaf `Node`.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.height
2
>>> marc.height
1
>>> lian.height
0
c              3   8   #    U  H  oR                   v   M     g 7fr   )height)r!   r"   s     r   r#   (LightNodeMixin.height.<locals>.<genexpr>  s     :||s   r   r   )r1   maxrY   s     r   r   LightNodeMixin.height  s+      ++:::Q>>r   c                 J    [        U R                  5       5       H  u  pM     W$ )z
Number of edges to the root `Node`.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> udo.depth
0
>>> marc.depth
1
>>> lian.depth
2
)	enumerater'   )r   depth_s      r   r   LightNodeMixin.depth  s&    $ "$"8"8":;HE <r   c                 B    [        [        U 5      S5       H  u  pM     W$ )aF  
Tree size --- the number of nodes in tree starting at this node.

>>> from anytree import Node
>>> udo = Node("Udo")
>>> marc = Node("Marc", parent=udo)
>>> lian = Node("Lian", parent=marc)
>>> loui = Node("Loui", parent=marc)
>>> soe = Node("Soe", parent=lian)
>>> udo.size
5
>>> marc.size
4
>>> lian.size
2
>>> loui.size
1
r   )r   r   )r   sizer   s      r   r   LightNodeMixin.size   s$    , !d!3Q7GD 8r   c                     g)z+Method call before detaching from `parent`.Nr   r{   s     r   r0   LightNodeMixin._pre_detach  r[   r   c                     g)z*Method call after detaching from `parent`.Nr   r{   s     r   r3   LightNodeMixin._post_detach  r[   r   c                     g)z)Method call before attaching to `parent`.Nr   r{   s     r   r:   LightNodeMixin._pre_attach   r[   r   c                     g)z(Method call after attaching to `parent`.Nr   r{   s     r   r<   LightNodeMixin._post_attach#  r[   r   )r   r   rD   N)(__name__
__module____qualname____firstlineno____doc__	__slots__	separatorpropertyr   setterr   r   r   r1   rD   staticmethodrO   deleterrV   rW   rP   rQ   rd   r'   rc   ro   rs   rv   r|   r   r   r   r   r   r   r0   r3   r:   r<   __static_attributes__r   r   r   r	   r	      s   GR z*II% %N ]]! !4&&  
 0/ 0/d % % __ & - -7676  "4 ? ?    & - -&  ( K K0 L L" 2 2" # #"  (  *  2:987r   r	   N)anytree.configr   anytree.iteratorsr   
exceptionsr   r   r	   r   r   r   <module>r      s    % * ,]7 ]7r   