
    0VhL                    z   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ZddlZddl	m
Z ddl	mZ ddl	mZ ddlmZ ddl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 m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z, ddl-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl6m8Z8m9Z9 ddl:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZE g dZFe9ZGdeHd<    e(d      ZI e(d      ZJ e(d      ZK e(d      ZL e(d      ZM e0d      ZN e(de!de f         ZOeeI   ZPdeHd<   e&e   ZQdeHd<   e, G d de'eI                ZR eSe)eTeUf         ZV	 dd lmWZW  G d" d#e%eI         ZY G d$ d%      ZZ G d& d'e'eI         Z[ G d( d)e'eI         Z\	 	 	 	 dAd*Z] e]e7j                        dBd+       Z^ e]e7j                        dCd,       Z_ e]e7j                        dDd-       Z` e]e7j                        dEd.       Za e(d/d01      Zb G d2 d3eS      Zce* G d4 d5eebdf   ec6             ZdedZedeHd7<   [c e]e7j                        dBd8       Zf e]e7j                        dCd9       Zge7j                  Zhd:eHd;<    e]e7j                        dDd<       Zi eS eSej                        j                        Zld=eHd><    e]e7j                        dEd?       Zm[Wy# eX$ r d@d!ZWY ~w xY w)FzTyping utilities for OpTree.    )annotationsN)dict)list)tuple)OrderedDict)defaultdict)deque)
CollectionHashable	ItemsViewIterableIteratorKeysViewSequence
ValuesView)AnyCallableClassVarFinal
ForwardRefGenericOptionalProtocolTypeVarUnionfinal
get_originruntime_checkable)
NamedTupleNever	ParamSpecSelf	TypeAliasTypeAliasType)WeakKeyDictionary)
PyTreeKind
PyTreeSpec)	AutoEntryDataclassEntryFlattenedEntryGetAttrEntryGetItemEntryMappingEntryNamedTupleEntryPyTreeAccessorPyTreeEntrySequenceEntryStructSequenceEntry).r'   	PyTreeDefr&   PyTreePyTreeTypeVarCustomTreeNodeChildrenMetaDataFlattenFuncUnflattenFuncr0   r,   r+   r*   r(   r1   r-   r.   r2   r)   r/   is_namedtupleis_namedtuple_classis_namedtuple_instancenamedtuple_fieldsis_structseqis_structseq_classis_structseq_instancestructseq_fieldsTSUKTVTPFr   r   TupleListDictr   r   DefaultDictDequeStructSequencer#   r3   rC   rD   rE   rF   rG   rH   rI   .)boundr7   r8   c                  .    e Zd ZdZ	 	 ddZedd       Zy)r6   z0The abstract base class for custom pytree nodes.c                    y)z:Flatten the custom pytree node into children and metadata.N selfs    =/home/dcms/DCMS/lib/python3.12/site-packages/optree/typing.pytree_flattenzCustomTreeNode.tree_flatten           c                    y)z@Unflatten the children and metadata into the custom pytree node.NrS   )clsmetadatachildrens      rV   tree_unflattenzCustomTreeNode.tree_unflatten   rX   rY   N)returnQtuple[Children[T], MetaData] | tuple[Children[T], MetaData, Iterable[Any] | None])r\   r8   r]   Children[T]r_   r"   )__name__
__module____qualname____doc__rW   classmethodr^   rS   rY   rV   r6   r6      s,    :
I
	;
I O OrY   r6   )	_tp_cachec               r     t        j                         t        j                         d fd       }|S )Nc                 D    	  | i |S # t         $ r  | i |cY S w xY wN	TypeError)argskwargscachedfuncs     rV   innerz_tp_cache.<locals>.inner   s7    -t.v.. -T,V,,-s    rm   zP.argsrn   zP.kwargsr_   rC   )	functools	lru_cachewraps)rp   rq   ro   s   ` @rV   rg   rg      s5    $$T*			- 
	- rY   c                      e Zd ZU dZdZded<    e       Zded<    ej                         Z
ded<   e	 	 	 	 dd	       Zdd
ZddZddZddZddZddZddZd dZd dZd!d"dZd#dZd$dZd%dZy)&r4   a  Generic PyTree type.

    >>> import torch
    >>> TensorTree = PyTree[torch.Tensor]
    >>> TensorTree  # doctest: +IGNORE_WHITESPACE
    typing.Union[torch.Tensor,
                 tuple[ForwardRef('PyTree[torch.Tensor]'), ...],
                 list[ForwardRef('PyTree[torch.Tensor]')],
                 dict[typing.Any, ForwardRef('PyTree[torch.Tensor]')],
                 collections.deque[ForwardRef('PyTree[torch.Tensor]')],
                 optree.typing.CustomTreeNode[ForwardRef('PyTree[torch.Tensor]')]]
    rS   ClassVar[tuple[()]]	__slots__zSClassVar[WeakKeyDictionary[TypeAliasType, tuple[type | TypeAliasType, str | None]]]__instances__zClassVar[threading.Lock]__instance_lock__c                   t        |t              s|df}t        |      dk(  r|d   df}n)t        |      dk7  rt        | j                   d|d      |\  }}|+t        |t
              st        | j                   d|d      t        |t              rAt        |      t        u r0| j                  5  	 || j                  v r|cddd       S 	 ddd       |t        |      }nt        |t              r&t        | j                   d|j                   d      }nt        |t              rT|j                  d	k(  r|j                  }n	 |j                   d|j                   }t        | j                   d| d      }nt        | j                   d|d      }t        |t"        |d
f   t$        |   t&        t(        |f   t*        |   t,        |   f   }| j                  5  ||f| j                  |<   ddd       |S # t        $ r Y 9w xY w# 1 sw Y   ?xY w# t         $ r |j                   d|j                   }Y w xY w# 1 sw Y   |S xY w)z.Instantiate a PyTree type with the given type.N   r      zS[...] only supports a tuple of 2 items, a parameter and a string of type name, got .[]builtins.)
isinstancer   lenrl   rb   str
_UnionTyper   r   rz   ry   r   r   typerc   rd   AttributeErrorrJ   rK   rL   r   rN   r6   )r[   itemparamnamerecurse_reftypenamepytree_aliass          rV   __class_getitem__zPyTree.__class_getitem__   sy    $&$<Dt9>GT?DY!^<<. !>>BXQH  tJtS$9<<. !>>BXQH 
 eZ(Z->%-G&&  1 11$ 1 $T*Kw'$~Qu~~6Fa%HIKt$:- --F"'"2"2!31U5G5G4HIH %~Qxj%BCK$~Quiq%ABK+s"#k!"+;')
 "" 	</4dmCl+	<= ! 	 " & F"'"2"2!31U^^4DEHF	<sN   3H5G<HH  I<	H	HH		HH$I ?I Ic                   t        d      )zProhibit instantiation.z*Cannot instantiate special typing classes.rk   r[   s    rV   __new__zPyTree.__new__  s    DEErY   c                   t        d      Prohibit subclassing.z'Cannot subclass special typing classes.rk   r[   rm   rn   s      rV   __init_subclass__zPyTree.__init_subclass__      ABBrY   c                   t         z!Emulate collection-like behavior.NotImplementedErrorrU   keys     rV   __getitem__zPyTree.__getitem__      !!rY   c                   t         )z Emulate dataclass-like behavior.r   )rU   r   s     rV   __getattr__zPyTree.__getattr__!  r   rY   c                   t         r   r   r   s     rV   __contains__zPyTree.__contains__%  r   rY   c                   t         r   r   rT   s    rV   __len__zPyTree.__len__)  r   rY   c                   t         r   r   rT   s    rV   __iter__zPyTree.__iter__-  r   rY   c                   t         zEmulate sequence-like behavior.r   r   s     rV   indexzPyTree.index1  r   rY   c                   t         r   r   r   s     rV   countzPyTree.count5  r   rY   Nc                   t         zEmulate mapping-like behavior.r   )rU   r   defaults      rV   getz
PyTree.get9  r   rY   c                   t         r   r   rT   s    rV   keyszPyTree.keys=  r   rY   c                   t         r   r   rT   s    rV   valueszPyTree.valuesA  r   rY   c                   t         r   r   rT   s    rV   itemszPyTree.itemsE  r   rY   )r   zetype[T] | TypeAliasType | tuple[type[T] | TypeAliasType] | tuple[type[T] | TypeAliasType, str | None]r_   r$   r_   r    rm   r   rn   r   r_   r    )r   r   r_   PyTree[T] | T)r   r   r_   r   )r   Any | Tr_   bool)r_   int)r_   zIterator[PyTree[T] | T | Any])r   r   r_   r   rj   )r   T | Noner   r   r_   r   )r_   zKeysView[Any])r_   zValuesView[PyTree[T] | T])r_   zItemsView[Any, PyTree[T] | T])rb   rc   rd   re   rx   __annotations__r%   ry   	threadingLockrz   rg   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rS   rY   rV   r4   r4      s     &(I"' 	    3A)..2B/B=9= 
= =~FC"""""""""""rY   r4   c                  *    e Zd ZdZedd       ZddZy)r5   a  Type variable for PyTree.

    >>> import torch
    >>> TensorTree = PyTreeTypeVar('TensorTree', torch.Tensor)
    >>> TensorTree  # doctest: +IGNORE_WHITESPACE
    typing.Union[torch.Tensor,
                 tuple[ForwardRef('TensorTree'), ...],
                 list[ForwardRef('TensorTree')],
                 dict[typing.Any, ForwardRef('TensorTree')],
                 collections.deque[ForwardRef('TensorTree')],
                 optree.typing.CustomTreeNode[ForwardRef('TensorTree')]]
    c               n    t        |t              st        | j                   d|d      t        ||f   S )zEInstantiate a PyTree type variable with the given name and parameter.z* only supports a string of type name, got r~   )r   r   rl   rb   r4   )r[   r   r   s      rV   r   zPyTreeTypeVar.__new__Y  s=     $$s||n,VW[V^^_`aaeTk""rY   c                   t        d      r   rk   r   s      rV   r   zPyTreeTypeVar.__init_subclass__`  r   rY   N)r   r   r   ztype | TypeAliasTyper_   r$   r   )rb   rc   rd   re   rg   r   r   rS   rY   rV   r5   r5   K  s!     # #CrY   r5   c                  >    e Zd ZdZej
                  	 	 	 	 dd       Zy)r9   z*The type stub class for flatten functions.c                    y)z1Flatten the container into children and metadata.NrS   )rU   	containers     rV   __call__zFlattenFunc.__call__h  rX   rY   N)r   Collection[T]r_   r`   rb   rc   rd   re   abcabstractmethodr   rS   rY   rV   r9   r9   e  s4    4@ @ 
[	@ @rY   r9   c                  6    e Zd ZdZej
                  dd       Zy)r:   z,The type stub class for unflatten functions.c                    y)z<Unflatten the children and metadata back into the container.NrS   )rU   r\   r]   s      rV   r   zUnflattenFunc.__call__t  rX   rY   N)r\   r8   r]   ra   r_   r   r   rS   rY   rV   r:   r:   q  s    6K KrY   r:   c                    d fd}|S )a^  Decorator to override the Python implementation with the C++ implementation.

    >>> @_override_with_(any)
    ... def my_any(iterable):
    ...     for elem in iterable:
    ...         if elem:
    ...             return True
    ...     return False
    ...
    >>> my_any([False, False, True, False, False, True])  # run at C speed
    True
    c               `    t        j                  |       dfd       }|_        | |_        |S )Nc                      | i |S rj   rS   )rm   rn   cxx_implementations     rV   wrappedz1_override_with_.<locals>.wrapper.<locals>.wrapped  s    %t6v66rY   rr   )rs   ru   __cxx_implementation____python_implementation__)python_implementationr   r   s     rV   wrapperz _override_with_.<locals>.wrapper  s6    	.	/	7 
0	7 *<&,A)rY   )r   Callable[P, T]r_   r   rS   )r   r   s   ` rV   _override_with_r   y  s    " NrY   c               R    t        | t              r| n
t        |       }t        |      S )zSReturn whether the object is an instance of namedtuple or a subclass of namedtuple.)r   r   r<   objr[   s     rV   r;   r;     s#     C&#DICs##rY   c               *    t        t        |             S )z7Return whether the object is an instance of namedtuple.)r<   r   r   s    rV   r=   r=     s     tCy))rY   c                  t        | t              xr{ t        | t              xri t        t	        | dd      t              xrL t        d | j                  D              xr. t        t	        | dd            xr t        t	        | dd            S )z5Return whether the class is a subclass of namedtuple._fieldsNc              3  >   K   | ]  }t        |      t        u   y wrj   )r   r   ).0fields     rV   	<genexpr>z&is_namedtuple_class.<locals>.<genexpr>  s     <uUs"<s   _make_asdict)r   r   
issubclassr   getattrallr   callabler   s    rV   r<   r<     s     	3 	4sE"	4wsIt4e<	4 <<<		4
 WS'401	4 WS)T23rY   c                   t        | t              r(| }t        |      st        d|d      |j                  S t        |       }t        |      st        d| d      |j                  S )z'Return the field names of a namedtuple.z,Expected a collections.namedtuple type, got r~   z9Expected an instance of collections.namedtuple type, got )r   r   r<   rl   r   r   s     rV   r>   r>     sr     #t"3'J3'QRSTT
 ;; 3i"3'WX[W^^_`aa;;rY   _T_coT)	covariantc                       e Zd ZdZddZddZy)StructSequenceMetaz-The metaclass for PyStructSequence stub type.c                   t        |      S )ad  Return whether the class is a PyStructSequence type.

        >>> import time
        >>> issubclass(time.struct_time, StructSequence)
        True
        >>> class MyTuple(tuple):
        ...     n_fields = 2
        ...     n_sequence_fields = 2
        ...     n_unnamed_fields = 0
        >>> issubclass(MyTuple, StructSequence)
        False
        )r@   )r[   subclasss     rV   __subclasscheck__z$StructSequenceMeta.__subclasscheck__  s     "(++rY   c                   t        |      S )zReturn whether the object is a PyStructSequence instance.

        >>> import sys
        >>> isinstance(sys.float_info, StructSequence)
        True
        >>> isinstance((1, 2), StructSequence)
        False
        )rA   )r[   instances     rV   __instancecheck__z$StructSequenceMeta.__instancecheck__  s     %X..rY   N)r   r   r_   r   )r   r   r_   r   )rb   rc   rd   re   r   r   rS   rY   rV   r   r     s    7,	/rY   r   c                  P    e Zd ZU dZdZded<   ded<   ded<   ded<   dd	Zddd
Zy)rO   z<A generic type stub for CPython's ``PyStructSequence`` type.rS   rw   rx   zFinal[ClassVar[int]]n_fieldsn_sequence_fieldsn_unnamed_fieldsc                   t        d      )r   z4type 'StructSequence' is not an acceptable base typerk   r   s    rV   r   z StructSequence.__init_subclass__  s    NOOrY   c                   t         )z.Create a new :class:`StructSequence` instance.r   )r[   sequencer   s      rV   r   zStructSequence.__new__  r   rY   Nr   ).)r   zIterable[_T_co]r   zdict[str, Any]r_   r"   )rb   rc   rd   re   rx   r   r   r   rS   rY   rV   rO   rO     s-    F%'I"'""++**P
"rY   rO   )	metaclass	structseqc               R    t        | t              r| n
t        |       }t        |      S )z\Return whether the object is an instance of PyStructSequence or a class of PyStructSequence.)r   r   r@   r   s     rV   r?   r?     s#     C&#DICc""rY   c               *    t        t        |             S )z=Return whether the object is an instance of PyStructSequence.)r@   r   r   s    rV   rA   rA     s     d3i((rY   r   Py_TPFLAGS_BASETYPEc                  t        | t              r| j                  t        fk(  rt        t	        | dd      t
              rt        t	        | dd      t
              rit        t	        | dd      t
              rNt        j                         dk(  r	 t        j                  d| f       y	t        | j                  t        z         S y	# t        t        f$ r Y yw xY w)
z8Return whether the class is a class of PyStructSequence.r   Nr   r   PyPyr   )basesTF)r   r   	__bases__r   r   r   platformr   types	new_classAssertionErrorrl   r   	__flags__r   r   s    rV   r@   r@     s     	3MMeX%wsJ5s;ws$7>Dws$6=sC ))+v5
3&9 (;;<<<	 #I. s   C CCz type[types.MemberDescriptorType]StructSequenceFieldTypec               L   t        | t              r| }t        |      s4t        d|d      t        |       }t        |      st        d| d      t	        j
                         dk(  r^t        |      j                         D ci c]"  \  }}t        |t              r||j                  $ }}}t        ||j                        }n;t        |      j                         D cg c]  \  }}t        |t              r| }}}t        |d|j                         S c c}}w c c}}w )z-Return the field names of a PyStructSequence.z&Expected a PyStructSequence type, got r~   z3Expected an instance of PyStructSequence type, got r  )r   N)r   r   r@   rl   r  r   varsr   r
  r   sortedr   r   r   )r   r[   r   memberindices_by_namefieldss         rV   rB   rB   *  s    #t!#&DSG1MNN3i!#&QRUQXXYZ[[%%'61 !%S	 1
f&"9: &,,
 

 _-@-@A !%S	 1
f&"9: 
 

 /#//011

s   'D#D )rp   r   r_   r   )r   r   r_   z*Callable[[Callable[P, T]], Callable[P, T]])r   zobject | typer_   r   )r   objectr_   r   )r[   r   r_   r   )r   ztuple | type[tuple]r_   ztuple[str, ...])nre   
__future__r   r   rs   r  sysr   r  r   r   rL   r   rK   r   rJ   collectionsr   r   rM   r	   rN   collections.abcr
   r   r   r   r   r   r   r   typingr   r   r   r   r   r   r   r   r   r   r   r   r   typing_extensionsr   r    r!   r"   r#   r$   weakrefr%   	optree._C_Cr&   r'   optree.accessorsr(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   __all__r3   r   rC   rD   rE   rF   rG   rH   rI   r7   r8   r6   r   r   r   r   rg   ImportErrorr4   r5   r9   r:   r   r;   r=   r<   r>   r   r   rO   r   r?   rA   r   r@   version_infomajorr
  rB   rS   rY   rV   <module>r      s.   # " 
   
   ! ! # # 2 &	 	 	     &  ,   /d "	9 !CLCLCLT]T]cNCxS)* qk) !x() ( OXa[ O O( %S/"
 "I"WQZ I"ZC C4	@(1+ 	@KHQK K& 0< !!"$ #$ **+* ,*
 ''(
 )
 %%&
 '
 	4(/ /D "U5#:&2D " "& &	9 % !# "# ))*) +) 11 S 1 &&' (. =AcFVFVAWA]A]<^ 9 ^ $$%2 &26 q  s   5J- -	J:9J: