
    0Vhu                       U d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	m
Z
mZ ddlmZmZ ddlmZ ddlmZmZmZmZmZmZmZmZ ddlmZ ddlmZmZmZm Z m!Z!m"Z" dd	l#m$Z$m%Z%m&Z&m'Z'm(Z( dd
l)m*Z*m+Z+m,Z, er)ddl-Z-ddl.m/Z/m0Z0m1Z1 ddl#m2Z2m3Z3m4Z4m5Z5m6Z6  ede7e4         Z8g dZ9ejt                  dk\  rddini Z; ejx                  dKddddde; G d dee&                Z=[; G d d      Z> e>       Z?de@d<    e       ZAde@d<   [>er8ddlBmCZC  eCd      ZD ed      ZE eCd      ZF ed       ZG G d! d"eeDeEeFeGf         ZH	 	 	 	 dLd#ZIed$d%	 	 	 	 	 dMd&       ZJe	 dNd$d%	 	 	 	 	 dOd'       ZJ	 dNd$d%	 	 	 	 	 dPd(ZJ eIeJ      ed)	 	 	 	 	 	 	 	 	 	 	 dQd*       ZK[J[Ie	 dNddd+	 	 	 	 	 	 	 dRd,       ZLe	 	 	 	 	 	 	 	 dSd-       ZL	 dNddd+	 	 	 	 	 	 	 dTd.ZLdUd/ZMej                  dVd0       ZOdWd1ZPdXd2ZQdYd3ZRdZd4ZSd[d5ZTd\d6ZUd]d7ZVd^d8ZWd_d9ZX	 	 	 	 d^d:ZYd_d;ZZ	 	 	 	 d`d<Z[dad=Z\	 	 	 	 dbd>Z]	 	 	 	 	 	 dcd?Z^	 	 	 	 dbd@Z_	 	 	 	 	 	 dcdAZ`dddBZadedCZbdfdDZcdgdEZddhdFZe	 	 	 	 	 	 didGZf e7d       e= e7d      eQeRe e$j                  H      eh e=eheSeTe!e$j                  H      ej e=ejeUeVe!e$j                  H      el e=eleWeXee$j                  H      e e=eecedee$j                  H      e e=ee[e\ee$j                  H      e	 e=e	e]e^ee$j                  H      e
 e=e
eaebe!e$j                  H      e% e=e%eeefe"e$j                  H      i	ZsdIe@dJ<    e=eleYeZee$j                  H      Zt e=e	e_e`ee$j                  H      Zuy)jz&Registry for custom pytree node types.    )annotationsN)OrderedDictdefaultdictdeque
namedtuple)
itemgettermethodcaller)Lock)TYPE_CHECKINGAnyCallableClassVarGeneric
NamedTupleTypeVaroverload)	AutoEntryMappingEntryNamedTupleEntryPyTreeEntrySequenceEntryStructSequenceEntry)
PyTreeKindStructSequenceTis_namedtuple_classis_structseq_class)safe_ziptotal_order_sortedunzip2)
Collection	GeneratorIterable)KTVTCustomTreeNodeFlattenFuncUnflattenFuncCustomTreeNodeType)bound)register_pytree_noderegister_pytree_node_classunregister_pytree_nodedict_insertion_ordered   
   slotsT)initrepreqfrozenc                      e Zd ZU dZded<   ded<   ded<   ej                  dk\  rd	ed
<   eZded<   e	j                  Zded<   dZded<   y)PyTreeNodeRegistryEntryz>A dataclass that stores the information of a pytree node type.zbuiltins.type[Collection[T]]typeFlattenFunc[T]flatten_funcUnflattenFunc[T]unflatten_funcr/   zdataclasses.KW_ONLY_zbuiltins.type[PyTreeEntry]path_entry_typer   kind str	namespaceN)__name__
__module____qualname____doc____annotations__sysversion_infor   r?   r   CUSTOMr@   rC        ?/home/dcms/DCMS/lib/python3.12/site-packages/optree/registry.pyr8   r8   @   sP    H
&&  $$
7"2;O/;!((D*(IsrM   r8   c                  $    e Zd ZU dZded<   ddZy)GlobalNamespacerL   zClassVar[tuple[()]]	__slots__c                    y)Nz<GLOBAL NAMESPACE>rL   )selfs    rN   __repr__zGlobalNamespace.__repr__W   s    #rM   N)returnrB   )rD   rE   rF   rQ   rH   rT   rL   rM   rN   rP   rP   T   s    %'I"'$rM   rP   rB   __GLOBAL_NAMESPACEr
   __REGISTRY_LOCK)	ParamSpec_P_T_GetP_GetTc                      e Zd ZddZddZy)_CallableWithGetc                   t         NNotImplementedErrorrS   argskwargss      rN   __call__z_CallableWithGet.__call__i       %%rM   c                   t         r`   ra   rc   s      rN   getz_CallableWithGet.getm   rg   rM   N)rd   z_P.argsre   z	_P.kwargsrU   rZ   )rd   z
_GetP.argsre   z_GetP.kwargsrU   r\   )rD   rE   rF   rf   ri   rL   rM   rN   r^   r^   h   s    	&	&rM   r^   c                    d fd}|S )Nc                   | _         | S r`   )ri   )funcri   s    rN   	decoratorz_add_get.<locals>.decoratorx   s    rM   )rl   zCallable[_P, _T]rU   z&_CallableWithGet[_P, _T, _GetP, _GetT]rL   )ri   rm   s   ` rN   _add_getrn   q   s     rM   rA   )rC   c                   y r`   rL   clsrC   s     rN   pytree_node_registry_getrr      s     &)rM   c                   y r`   rL   rp   s     rN   rr   rr      s     +.rM   c              J   |t         u rd}| ,| t        ur$t        j                  |       st	        d| d      t        |t              st	        d|d      | t        |dh      }t        5  t        j                         D ci c]  }|j                  |v r|j                  | }}ddd       t        j                  |      rt        t         <   t"        |t$        <   S |dk7  rt        j'                  || f      }||S t        j                  |      r| t         u rt        S | t$        u rt"        S t        j'                  |       }||S t)        |       rt        j'                  t*              S t-        |       rt        j'                  t              S yc c}w # 1 sw Y   xY w)a  Lookup the pytree node registry.

    >>> register_pytree_node.get()  # doctest: +IGNORE_WHITESPACE,ELLIPSIS
    {
        <class 'NoneType'>: PyTreeNodeRegistryEntry(
            type=<class 'NoneType'>,
            flatten_func=<function ...>,
            unflatten_func=<function ...>,
            path_entry_type=<class 'optree.PyTreeEntry'>,
            kind=<PyTreeKind.NONE: 2>,
            namespace=''
        ),
        <class 'tuple'>: PyTreeNodeRegistryEntry(
            type=<class 'tuple'>,
            flatten_func=<function ...>,
            unflatten_func=<function ...>,
            path_entry_type=<class 'optree.SequenceEntry'>,
            kind=<PyTreeKind.TUPLE: 3>,
            namespace=''
        ),
        <class 'list'>: PyTreeNodeRegistryEntry(
            type=<class 'list'>,
            flatten_func=<function ...>,
            unflatten_func=<function ...>,
            path_entry_type=<class 'optree.SequenceEntry'>,
            kind=<PyTreeKind.LIST: 4>,
            namespace=''
        ),
        ...
    }
    >>> register_pytree_node.get(defaultdict)  # doctest: +IGNORE_WHITESPACE,ELLIPSIS
    PyTreeNodeRegistryEntry(
        type=<class 'collections.defaultdict'>,
        flatten_func=<function ...>,
        unflatten_func=<function ...>,
        path_entry_type=<class 'optree.MappingEntry'>,
        kind=<PyTreeKind.DEFAULTDICT: 8>,
        namespace=''
    )
    >>> register_pytree_node.get(frozenset)  # frozenset is considered as a leaf node
    None

    Args:
        cls (type or None, optional): The class of the pytree node to retrieve. If not provided, all
            the registered pytree nodes in the namespace are returned.
        namespace (str, optional): The namespace of the registry to retrieve. If not provided, the
            global namespace is used.

    Returns:
        If the ``cls`` is not provided, a dictionary of all the registered pytree nodes in the
        namespace is returned. If the ``cls`` is provided, the corresponding registry entry is
        returned if the ``cls`` is registered as a pytree node. Otherwise, :data:`None` is returned,
        i.e., the ``cls`` is represented as a leaf node.
    rA   NzExpected a class or None, got .$The namespace must be a string, got )rV   r   inspectisclass	TypeError
isinstancerB   	frozensetrW   _NODETYPE_REGISTRYvaluesrC   r9   _Cis_dict_insertion_ordered&_DICT_INSERTION_ORDERED_REGISTRY_ENTRYdict-_DEFAULTDICT_INSERTION_ORDERED_REGISTRY_ENTRYr   ri   r   r   r   )rq   rC   
namespaceshandlerregistrys        rN   rr   rr      s   x &&	z!$8qABBi%29-qA
 	
 {	2/
 	  288:$$
2 g%H 	 ''	2CHTN$QH[!B$(()S)9:N	##I.$;99+@@ $$S)G#!%%n553!%%j119	 	s   -F"F&FFF")r?   c                 t        j                  |       st        d| d      t        j                  |      rt        |t              st        d|d      |t
        urt        |t              st        d|d      |dk(  rt        d      |t
        u r| }d}n|| f}t        5  t        j                  | ||||       t        | ||||      t        |<   ddd       | S # 1 sw Y   | S xY w)	a  Extend the set of types that are considered internal nodes in pytrees.

    See also :func:`register_pytree_node_class` and :func:`unregister_pytree_node`.

    The ``namespace`` argument is used to avoid collisions that occur when different libraries
    register the same Python type with different behaviors. It is recommended to add a unique prefix
    to the namespace to avoid conflicts with other libraries. Namespaces can also be used to specify
    the same class in different namespaces for different use cases.

    .. warning::
        For safety reasons, a ``namespace`` must be specified while registering a custom type. It is
        used to isolate the behavior of flattening and unflattening a pytree node type. This is to
        prevent accidental collisions between different libraries that may register the same type.

    Args:
        cls (type): A Python type to treat as an internal pytree node.
        flatten_func (callable): A function to be used during flattening, taking an instance of ``cls``
            and returning a triple or optionally a pair, with (1) an iterable for the children to be
            flattened recursively, and (2) some hashable metadata to be stored in the treespec and
            to be passed to the ``unflatten_func``, and (3) (optional) an iterable for the tree path
            entries to the corresponding children. If the entries are not provided or given by
            :data:`None`, then `range(len(children))` will be used.
        unflatten_func (callable): A function taking two arguments: the metadata that was returned
            by ``flatten_func`` and stored in the treespec, and the unflattened children. The
            function should return an instance of ``cls``.
        path_entry_type (type, optional): The type of the path entry to be used in the treespec.
            (default: :class:`AutoEntry`)
        namespace (str): A non-empty string that uniquely identifies the namespace of the type registry.
            This is used to isolate the registry from other modules that might register a different
            custom behavior for the same type.

    Returns:
        The same type as the input ``cls``.

    Raises:
        TypeError: If the input type is not a class.
        TypeError: If the path entry class is not a subclass of :class:`PyTreeEntry`.
        TypeError: If the namespace is not a string.
        ValueError: If the namespace is an empty string.
        ValueError: If the type is already registered in the registry.

    Examples:
        >>> # Registry a Python type with lambda functions
        >>> register_pytree_node(
        ...     set,
        ...     lambda s: (sorted(s), None, None),
        ...     lambda _, children: set(children),
        ...     namespace='set',
        ... )
        <class 'set'>

        >>> # Register a Python type into a namespace
        >>> import torch
        >>> register_pytree_node(
        ...     torch.Tensor,
        ...     flatten_func=lambda tensor: (
        ...         (tensor.cpu().detach().numpy(),),
        ...         {'dtype': tensor.dtype, 'device': tensor.device, 'requires_grad': tensor.requires_grad},
        ...     ),
        ...     unflatten_func=lambda metadata, children: torch.tensor(children[0], **metadata),
        ...     namespace='torch2numpy',
        ... )
        <class 'torch.Tensor'>

        >>> # doctest: +SKIP
        >>> tree = {'weight': torch.ones(size=(1, 2)).cuda(), 'bias': torch.zeros(size=(2,))}
        >>> tree
        {'weight': tensor([[1., 1.]], device='cuda:0'), 'bias': tensor([0., 0.])}

        >>> # Flatten without specifying the namespace
        >>> tree_flatten(tree)  # `torch.Tensor`s are leaf nodes
        ([tensor([0., 0.]), tensor([[1., 1.]], device='cuda:0')], PyTreeSpec({'bias': *, 'weight': *}))

        >>> # Flatten with the namespace
        >>> tree_flatten(tree, namespace='torch2numpy')
        (
            [array([0., 0.], dtype=float32), array([[1., 1.]], dtype=float32)],
            PyTreeSpec(
                {
                    'bias': CustomTreeNode(Tensor[{'dtype': torch.float32, 'device': device(type='cpu'), 'requires_grad': False}], [*]),
                    'weight': CustomTreeNode(Tensor[{'dtype': torch.float32, 'device': device(type='cuda', index=0), 'requires_grad': False}], [*])
                },
                namespace='torch2numpy'
            )
        )

        >>> # Register the same type with a different namespace for different behaviors
        >>> def tensor2flatparam(tensor):
        ...     return [torch.nn.Parameter(tensor.reshape(-1))], tensor.shape, None
        ...
        ... def flatparam2tensor(metadata, children):
        ...     return children[0].reshape(metadata)
        ...
        ... register_pytree_node(
        ...     torch.Tensor,
        ...     flatten_func=tensor2flatparam,
        ...     unflatten_func=flatparam2tensor,
        ...     namespace='tensor2flatparam',
        ... )
        <class 'torch.Tensor'>

        >>> # Flatten with the new namespace
        >>> tree_flatten(tree, namespace='tensor2flatparam')
        (
            [
                Parameter containing: tensor([0., 0.], requires_grad=True),
                Parameter containing: tensor([1., 1.], device='cuda:0', requires_grad=True)
            ],
            PyTreeSpec(
                {
                    'bias': CustomTreeNode(Tensor[torch.Size([2])], [*]),
                    'weight': CustomTreeNode(Tensor[torch.Size([1, 2])], [*])
                },
                namespace='tensor2flatparam'
            )
        )
    Expected a class, got ru   (Expected a subclass of PyTreeEntry, got rv   rA   (The namespace cannot be an empty string.r?   rC   N)rw   rx   ry   
issubclassr   rV   rz   rB   
ValueErrorrW   r~   register_noder8   r|   )rq   r;   r=   r?   rC   registration_keys         rN   r+   r+      s   ~ ??30q9::OOO,O[1YB?BUUVWXX**:i3M>ym1MNNBCDD &&	%s+	 

	
 0G+0
+,
 J
 Js   '1C""C,r   c                   y r`   rL   rq   r?   rC   s      rN   r,   r,     s     :=rM   c                   y r`   rL   r   s      rN   r,   r,     s     rM   c              6   | t         u st        | t              r"t        d      | dk(  rt        d      d| c} t        d      t         urt        t              st	        d      dk(  rt        d      | 	dfd}|S t        j                  |       st	        d| d	      t        | d
t              t        j                        rt        t              st	        dd	      t        | t        d      | j                         | S )an
  Extend the set of types that are considered internal nodes in pytrees.

    See also :func:`register_pytree_node` and :func:`unregister_pytree_node`.

    The ``namespace`` argument is used to avoid collisions that occur when different libraries
    register the same Python type with different behaviors. It is recommended to add a unique prefix
    to the namespace to avoid conflicts with other libraries. Namespaces can also be used to specify
    the same class in different namespaces for different use cases.

    .. warning::
        For safety reasons, a ``namespace`` must be specified while registering a custom type. It is
        used to isolate the behavior of flattening and unflattening a pytree node type. This is to
        prevent accidental collisions between different libraries that may register the same type.

    Args:
        cls (type, optional): A Python type to treat as an internal pytree node.
        path_entry_type (type, optional): The type of the path entry to be used in the treespec.
            (default: :class:`AutoEntry`)
        namespace (str, optional): A non-empty string that uniquely identifies the namespace of the
            type registry. This is used to isolate the registry from other modules that might
            register a different custom behavior for the same type.

    Returns:
        The same type as the input ``cls`` if the argument presents. Otherwise, return a decorator
        function that registers the class as a pytree node.

    Raises:
        TypeError: If the path entry class is not a subclass of :class:`PyTreeEntry`.
        TypeError: If the namespace is not a string.
        ValueError: If the namespace is an empty string.
        ValueError: If the type is already registered in the registry.

    This function is a thin wrapper around :func:`register_pytree_node`, and provides a
    class-oriented interface::

        @register_pytree_node_class(namespace='foo')
        class Special:
            TREE_PATH_ENTRY_TYPE = GetAttrEntry

            def __init__(self, x, y):
                self.x = x
                self.y = y

            def tree_flatten(self):
                return ((self.x, self.y), None, ('x', 'y'))

            @classmethod
            def tree_unflatten(cls, metadata, children):
                return cls(*children)

        @register_pytree_node_class('mylist')
        class MyList(UserList):
            TREE_PATH_ENTRY_TYPE = SequenceEntry

            def tree_flatten(self):
                return self.data, None, None

            @classmethod
            def tree_unflatten(cls, metadata, children):
                return cls(*children)
    Nz?Cannot specify `namespace` when the first argument is a string.rA   r   z<Must specify `namespace` when the first argument is a class.rv   c                    t        |       S )Nr   )r,   )rq   rC   r?   s    rN   rm   z-register_pytree_node_class.<locals>.decorator	  s    - /# rM   r   ru   TREE_PATH_ENTRY_TYPEr   tree_flattenr   )rq   r)   rU   r)   )rV   rz   rB   r   ry   rw   rx   getattrr   r   r   r+   r	   tree_unflatten)rq   r?   rC   rm   s    `` rN   r,   r,     s/   H   JsC$8 ^__"9GHHsYWXX**:i3M>ymLMMBCDD
{	 ??30q9::!#'=yIOOO,O[1YB?BUUVWXX^$' JrM   c              h   t        j                  |       st        d| d      |t        urt	        |t
              st        d|d      |dk(  rt        d      |t        u r| }d}n|| f}t        5  t        j                  | |       t        j                  |      cddd       S # 1 sw Y   yxY w)a  Remove a type from the pytree node registry.

    See also :func:`register_pytree_node` and :func:`register_pytree_node_class`.

    This function is the inverse operation of function :func:`register_pytree_node`.

    Args:
        cls (type): A Python type to remove from the pytree node registry.
        namespace (str): The namespace of the pytree node registry to remove the type from.

    Returns:
        The removed registry entry.

    Raises:
        TypeError: If the input type is not a class.
        TypeError: If the namespace is not a string.
        ValueError: If the namespace is an empty string.
        ValueError: If the type is a built-in type that cannot be unregistered.
        ValueError: If the type is not found in the registry.

    Examples:
        >>> # Register a Python type with lambda functions
        >>> register_pytree_node(
        ...     set,
        ...     lambda s: (sorted(s), None, None),
        ...     lambda _, children: set(children),
        ...     namespace='temp',
        ... )
        <class 'set'>

        >>> # Unregister the Python type
        >>> unregister_pytree_node(set, namespace='temp')
    r   ru   rv   rA   r   N)rw   rx   ry   rV   rz   rB   r   rW   r~   unregister_noder|   pop)rq   rC   r   s      rN   r-   r-   #  s    D ??30q9::**:i3M>ym1MNNBCDD &&	%s+	 8
3	*!%%&678 8 8s   3+B((B1c            #    K   |t         urt        |t              st        d|d      |dk(  rt	        d      |t         u rd}t
        5  t        j                  |d      }t        j                  t        |       |       ddd       	 d t
        5  t        j                  |       ddd       y# 1 sw Y   4xY w# 1 sw Y   yxY w# t
        5  t        j                  |       ddd       w # 1 sw Y   w xY wxY ww)a  Context manager to temporarily set the dictionary sorting mode.

    This context manager is used to temporarily set the dictionary sorting mode for a specific
    namespace. The dictionary sorting mode is used to determine whether the keys of a dictionary
    should be sorted or keeping the insertion order when flattening a pytree.

    >>> tree = {'b': (2, [3, 4]), 'a': 1, 'c': None, 'd': 5}
    >>> tree_flatten(tree)  # doctest: +IGNORE_WHITESPACE
    (
        [1, 2, 3, 4, 5],
        PyTreeSpec({'a': *, 'b': (*, [*, *]), 'c': None, 'd': *})
    )
    >>> with dict_insertion_ordered(True, namespace='some-namespace'):  # doctest: +IGNORE_WHITESPACE
    ...     tree_flatten(tree, namespace='some-namespace')
    (
        [2, 3, 4, 1, 5],
        PyTreeSpec({'b': (*, [*, *]), 'a': *, 'c': None, 'd': *}, namespace='some-namespace')
    )

    .. warning::
        The dictionary sorting mode is a global setting and is **not thread-safe**. It is
        recommended to use this context manager in a single-threaded environment.

    Args:
        mode (bool): The dictionary sorting mode to set.
        namespace (str): The namespace to set the dictionary sorting mode for.
    rv   ru   rA   r   F)inherit_global_namespaceN)
rV   rz   rB   ry   r   rW   r~   r   set_dict_insertion_orderedbool)moderC   prevs      rN   r.   r.   X  s     : **:i3M>ym1MNNBCDD&&		 =++IPUV
%%d4j)<=; 	;))$	:	; 	;= =	; 	;_ 	;))$	:	; 	; 	;sf   AD
7B4D
C DC +	D4B=9D C	DC?C3*	C?3C<8C??Dc               .    t        | t        d            S )Nr   )key)r   r   )itemss    rN   _sorted_itemsr     s    eA77rM   c                    y)N)rL   NrL   )r>   s    rN   _none_flattenr     s    rM   c               \    t               }t        t        |      |      |urt        d      y )NzExpected no children.)objectnextiterr   )r>   childrensentinels      rN   _none_unflattenr     s-    xHDNH%X5011 6rM   c               
    | d fS r`   rL   tups    rN   _tuple_flattenr         9rM   c                   t        |      S r`   )tupler>   r   s     rN   _tuple_unflattenr     s    ?rM   c               
    | d fS r`   rL   )lsts    rN   _list_flattenr     r   rM   c                   t        |      S r`   )listr   s     rN   _list_unflattenr     s    >rM   c               h    t        t        | j                                     \  }}|t        |      |fS r`   )r    r   r   r   dctkeysr}   s      rN   _dict_flattenr     s,    -		45LD&4:t##rM   c               ,    t        t        | |            S r`   r   r   r   r}   s     rN   _dict_unflattenr         v&''rM   c               V    t        | j                               \  }}|t        |      |fS r`   r    r   r   r   s      rN   _dict_insertion_ordered_flattenr     )     #))+&LD&4:t##rM   c               ,    t        t        | |            S r`   r   r   s     rN   !_dict_insertion_ordered_unflattenr     r   rM   c               V    t        | j                               \  }}|t        |      |fS r`   r   r   s      rN   _ordereddict_flattenr     r   rM   c               ,    t        t        | |            S r`   )r   r   r   s     rN   _ordereddict_unflattenr     s    xf-..rM   c               B    t        |       \  }}}|| j                  |f|fS r`   )r   default_factoryr   r}   r   entriess       rN   _defaultdict_flattenr     s-     *#.FD'C''.77rM   c               8    | \  }}t        |t        ||            S r`   )r   r   metadatar}   r   r   s       rN   _defaultdict_unflattenr     s"    
 %OTf(EFFrM   c               B    t        |       \  }}}|| j                  |f|fS r`   )r   r   r   s       rN   &_defaultdict_insertion_ordered_flattenr     s-     <C@FD'C''.77rM   c               8    | \  }}t        |t        ||            S r`   )r   r   r   s       rN   (_defaultdict_insertion_ordered_unflattenr     s$    
 %OT(I$PV(WXXrM   c                   | | j                   fS r`   maxlen)deqs    rN   _deque_flattenr     s    

?rM   c                   t        ||       S )Nr   )r   )r   r   s     rN   _deque_unflattenr     s    &))rM   c                   | t        |       fS r`   r9   r   s    rN   _namedtuple_flattenr          S	>rM   c                    | | S r`   rL   rq   r   s     rN   _namedtuple_unflattenr     s    >rM   c                   | t        |       fS r`   r   )seqs    rN   _structseq_flattenr   	  r   rM   c                    | |      S r`   rL   r   s     rN   _structseq_unflattenr     s    
 x=rM   )r?   r@   z6dict[type | tuple[str, type], PyTreeNodeRegistryEntry]r|   rL   )ri   zCallable[_GetP, _GetT]rU   zDCallable[[Callable[_P, _T]], _CallableWithGet[_P, _T, _GetP, _GetT]])rq   r9   rC   rB   rU   zPyTreeNodeRegistryEntry | Noner`   )rq   NonerC   rB   rU   z#dict[type, PyTreeNodeRegistryEntry])rq   ztype | NonerC   rB   rU   zDdict[type, PyTreeNodeRegistryEntry] | PyTreeNodeRegistryEntry | None)r;   r:   r=   r<   rq   type[Collection[T]]r?   ztype[PyTreeEntry]rC   rB   rU   r   )rq   
str | Noner?   type[PyTreeEntry] | NonerC   r   rU   z2Callable[[CustomTreeNodeType], CustomTreeNodeType])rq   r)   r?   r   rC   rB   rU   r)   )rq   zCustomTreeNodeType | str | Noner?   r   rC   r   rU   zGCustomTreeNodeType | Callable[[CustomTreeNodeType], CustomTreeNodeType])rq   r9   rC   rB   rU   r8   )r   r   rC   rB   rU   zGenerator[None])r   zIterable[tuple[KT, VT]]rU   zlist[tuple[KT, VT]])r>   r   rU   ztuple[tuple[()], None])r>   r   r   zIterable[Any]rU   r   )r   tuple[T, ...]rU   ztuple[tuple[T, ...], None])r>   r   r   Iterable[T]rU   r   )r   list[T]rU   ztuple[list[T], None])r>   r   r   r   rU   r   )r   dict[KT, VT]rU   /tuple[tuple[VT, ...], list[KT], tuple[KT, ...]])r   list[KT]r}   Iterable[VT]rU   r   )r   OrderedDict[KT, VT]rU   r   )r   r   r}   r   rU   r   )r   defaultdict[KT, VT]rU   zOtuple[tuple[VT, ...], tuple[Callable[[], VT] | None, list[KT]], tuple[KT, ...]])r   z!tuple[Callable[[], VT], list[KT]]r}   r   rU   r   )r   deque[T]rU   ztuple[deque[T], int | None])r   z
int | Noner   r   rU   r   )r   NamedTuple[T]rU   z)tuple[tuple[T, ...], type[NamedTuple[T]]])rq   ztype[NamedTuple[T]]r   r   rU   r   )r   StructSequence[T]rU   z-tuple[tuple[T, ...], type[StructSequence[T]]])rq   ztype[StructSequence[T]]r   r   rU   r   )vrG   
__future__r   
contextlibdataclassesrw   rI   collectionsr   r   r   r   operatorr   r	   	threadingr
   typingr   r   r   r   r   r   r   r   	optree._Cr~   optree.accessorsr   r   r   r   r   r   optree.typingr   r   r   r   r   optree.utilsr   r   r    builtinscollections.abcr!   r"   r#   r$   r%   r&   r'   r(   r9   r)   __all__rJ   SLOTS	dataclassr8   rP   rV   rH   rW   typing_extensionsrX   rY   rZ   r[   r\   r^   rn   rr   r+   r,   r-   contextmanagerr.   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   NONEr   TUPLEr   LISTr   DICT
NAMEDTUPLEORDEREDDICTDEFAULTDICTDEQUESTRUCTSEQUENCEr|   r   r   rL   rM   rN   <module>r     s   - #    
 C C -  a a a   a ` = = ??PP !!5T.=QR ++w6$B KDtTKUKgaj  L 
$ $ *+ C +  +	4B	BgEGE&72r5%#78 &	 

 	)	) 	)
 $) 
) 
. 	.	. 	.
 ). 
. h 	h	h 	h
 JhV 

"# *3] !] %	]	] '] ] ] $]@ h 
= 15 =	= .	=
 = 8= 
= 
	 .	
   
 ,0k 15 k	(k .	k
 k Mk\28j +; +;\82$
(	$		$	$(	$		$	$/	8		8	8G/GG 	G	8		8	8Y/YY 	Y*
	  	 	J'T
#__ 
"% 	
!%__ 	
!$__ ''"" ($## ($## 
"% ++&&s@N J @F *A#% 	* & 1H*, 			1 -rM   