o
    2h^L                     @  s  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ZIe(dZJe(dZKe(dZLe(dZMe0dZNe(de!de f dZOeeI ZPdeHd< e&e ZQdeHd< e,G dd de'eI ZReSe)eTeUf ZVzdd lmWZW W n eXy   dWd$d%ZWY nw G d&d' d'e%eI ZYG d(d) d)ZZG d*d+ d+e'eI Z[G d,d- d-e'eI Z\dXd0d1Z]e]e7j^dYd5d6Z^e]e7j_dZd8d9Z_e]e7j`d[d<d=Z`e]e7jad\d@dAZae(dBdCdDZbG dEdF dFeSZce*G dGdH dHeebdf ecdIZdedZedeHdJ< [ce]e7jfdYdKdLZfe]e7jgdZdMdNZge7jhZhdOeHdP< e]e7jid[dQdRZieSeSejjjkZldSeHdT< e]e7jmd\dUdVZm[WdS )]z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UnflattenFuncr/   r+   r*   r)   r'   r0   r,   r-   r1   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"   r2   rB   rC   rD   rE   rF   rG   rH   .)boundr6   r7   c                   @  s(   e Zd ZdZdddZedddZdS )r5   z0The abstract base class for custom pytree nodes.returnQtuple[Children[T], MetaData] | tuple[Children[T], MetaData, Iterable[Any] | None]c                C     dS )z:Flatten the custom pytree node into children and metadata.N selfrS   rS   H/var/www/html/chatgem/venv/lib/python3.10/site-packages/optree/typing.pytree_flatten       zCustomTreeNode.tree_flattenmetadatar7   childrenChildren[T]r!   c                C  rR   )z@Unflatten the children and metadata into the custom pytree node.NrS   )clsrY   rZ   rS   rS   rV   tree_unflatten   rX   zCustomTreeNode.tree_unflattenN)rP   rQ   )rY   r7   rZ   r[   rP   r!   )__name__
__module____qualname____doc__rW   classmethodr]   rS   rS   rS   rV   r5      s
    
r5   )	_tp_cachefuncCallable[P, T]rP   c                  s(   t  t d	 fdd}|S )
NargsP.argskwargsP.kwargsrP   rB   c                    s2   z | i |W S  t y   | i | Y S w N	TypeErrorrf   rh   cachedrd   rS   rV   inner   s
   z_tp_cache.<locals>.innerrf   rg   rh   ri   rP   rB   )	functools	lru_cachewraps)rd   rp   rS   rn   rV   rc      s   
rc   c                   @  s   e Zd ZU dZdZded< e Zded< e	 Z
ded< ed;ddZd<ddZd=ddZd>ddZd?ddZd@d!d"ZdAd$d%ZdBd'd(ZdCd)d*ZdCd+d,ZdDdEd0d1ZdFd3d4ZdGd6d7ZdHd9d:Zd-S )Ir3   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__itemetype[T] | TypeAliasType | tuple[type[T] | TypeAliasType] | tuple[type[T] | TypeAliasType, str | None]rP   r#   c              	   C  s  t |ts	|df}t|dkr|d df}nt|dkr't| j d|d|\}}|dur?t |ts?t| j d|dt |trxt|tu rx| j	# z|| j
v r^|W W  d   S W n	 tyh   Y nw W d   n1 ssw   Y  |durt|}nUt |trt| j d|j d}nCt |tr|jd	kr|j}nz|j d|j }W n ty   |j d|j }Y nw t| j d| d}nt| j d|d}t|t|d
f t| tt|f t| t| f }| j	 ||f| j
|< W d   |S 1 sw   Y  |S )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   r^   str
_UnionTyper   r   rx   rw   r   r   typer_   r`   AttributeErrorrI   rJ   rK   r   rM   r5   )r\   ry   paramnamerecurse_reftypenamepytree_aliasrS   rS   rV   __class_getitem__   st   







	
zPyTree.__class_getitem__r   c                C     t d)zProhibit instantiation.z*Cannot instantiate special typing classes.rk   r\   rS   rS   rV   __new__     zPyTree.__new__rf   r   rh   c                O  r   Prohibit subclassing.z'Cannot subclass special typing classes.rk   r\   rf   rh   rS   rS   rV   __init_subclass__  r   zPyTree.__init_subclass__keyPyTree[T] | Tc                C     t z!Emulate collection-like behavior.NotImplementedErrorrU   r   rS   rS   rV   __getitem__     zPyTree.__getitem__r   r   c                C  r   )z Emulate dataclass-like behavior.r   )rU   r   rS   rS   rV   __getattr__!  r   zPyTree.__getattr__Any | Tboolc                C  r   r   r   r   rS   rS   rV   __contains__%  r   zPyTree.__contains__intc                C  r   r   r   rT   rS   rS   rV   __len__)  r   zPyTree.__len__Iterator[PyTree[T] | T | Any]c                C  r   r   r   rT   rS   rS   rV   __iter__-  r   zPyTree.__iter__c                C  r   zEmulate sequence-like behavior.r   r   rS   rS   rV   index1  r   zPyTree.indexc                C  r   r   r   r   rS   rS   rV   count5  r   zPyTree.countNdefaultT | Nonec                C  r   zEmulate mapping-like behavior.r   )rU   r   r   rS   rS   rV   get9  r   z
PyTree.getKeysView[Any]c                C  r   r   r   rT   rS   rS   rV   keys=  r   zPyTree.keysValuesView[PyTree[T] | T]c                C  r   r   r   rT   rS   rS   rV   valuesA  r   zPyTree.valuesItemsView[Any, PyTree[T] | T]c                C  r   r   r   rT   rS   rS   rV   itemsE  r   zPyTree.items)ry   rz   rP   r#   rP   r   rf   r   rh   r   rP   r   )r   r   rP   r   )r   r   rP   r   )r   r   rP   r   )rP   r   )rP   r   )r   r   rP   r   rj   )r   r   r   r   rP   r   )rP   r   )rP   r   )rP   r   )r^   r_   r`   ra   rv   __annotations__r$   rw   	threadingLockrx   rc   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rS   rS   rS   rV   r3      s*   
 

?









r3   c                   @  s(   e Zd ZdZeddd	ZdddZdS )r4   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')]]
    r   r   r   type | TypeAliasTyperP   r#   c                C  s,   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   r^   r3   )r\   r   r   rS   rS   rV   r   Y  s   
zPyTreeTypeVar.__new__rf   r   rh   r   c                O  r   r   rk   r   rS   rS   rV   r   `  r   zPyTreeTypeVar.__init_subclass__N)r   r   r   r   rP   r#   r   )r^   r_   r`   ra   rc   r   r   rS   rS   rS   rV   r4   K  s
    r4   c                   @  s    e Zd ZdZejd	ddZdS )
r8   z*The type stub class for flatten functions.	containerCollection[T]rP   rQ   c                C  rR   )z1Flatten the container into children and metadata.NrS   )rU   r   rS   rS   rV   __call__h  rX   zFlattenFunc.__call__N)r   r   rP   rQ   r^   r_   r`   ra   abcabstractmethodr   rS   rS   rS   rV   r8   e      r8   c                   @  s    e Zd ZdZejddd	Zd
S )r9   z,The type stub class for unflatten functions.rY   r7   rZ   r[   rP   r   c                C  rR   )z<Unflatten the children and metadata back into the container.NrS   )rU   rY   rZ   rS   rS   rV   r   t  rX   zUnflattenFunc.__call__N)rY   r7   rZ   r[   rP   r   r   rS   rS   rS   rV   r9   q  r   r9   cxx_implementation*Callable[[Callable[P, T]], Callable[P, T]]c                  s   d fd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
    python_implementationre   rP   c                  s(   t | d	 fdd} |_| |_|S )
Nrf   rg   rh   ri   rP   rB   c                    s    | i |S rj   rS   rm   r   rS   rV   wrapped  s   z1_override_with_.<locals>.wrapper.<locals>.wrappedrq   )rr   rt   __cxx_implementation____python_implementation__)r   r   r   rS   rV   wrapper  s
   z _override_with_.<locals>.wrapperN)r   re   rP   re   rS   )r   r   rS   r   rV   _override_with_y  s   
r   objobject | typer   c                C     t | tr| nt| }t|S )zSReturn whether the object is an instance of namedtuple or a subclass of namedtuple.)r   r   r;   r   r\   rS   rS   rV   r:        r:   objectc                C     t t| S )z7Return whether the object is an instance of namedtuple.)r;   r   r   rS   rS   rV   r<        r<   r\   r   c                C  sZ   t | to,t| to,t t| ddto,tdd | jD o,tt| ddo,tt| ddS )z5Return whether the class is a subclass of namedtuple._fieldsNc                 s  s    | ]	}t |tu V  qd S rj   )r   r   ).0fieldrS   rS   rV   	<genexpr>  s    z&is_namedtuple_class.<locals>.<genexpr>_make_asdict)r   r   
issubclassr   getattrallr   callabler   rS   rS   rV   r;     s   
r;   tuple | type[tuple]tuple[str, ...]c                C  sR   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   rS   rS   rV   r=     s   
r=   _T_coT)	covariantc                   @  s$   e Zd ZdZdddZdd
dZdS )StructSequenceMetaz-The metaclass for PyStructSequence stub type.subclassr   rP   r   c                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\   r   rS   rS   rV   __subclasscheck__  s   z$StructSequenceMeta.__subclasscheck__instancer   c                C  r   )zReturn whether the object is a PyStructSequence instance.

        >>> import sys
        >>> isinstance(sys.float_info, StructSequence)
        True
        >>> isinstance((1, 2), StructSequence)
        False
        )r@   )r\   r   rS   rS   rV   __instancecheck__  s   	z$StructSequenceMeta.__instancecheck__N)r   r   rP   r   )r   r   rP   r   )r^   r_   r`   ra   r   r   rS   rS   rS   rV   r     s    
r   c                   @  sL   e Zd ZU dZdZded< ded< ded< ded< dddZddddZdS )rN   z<A generic type stub for CPython's ``PyStructSequence`` type.rS   ru   rv   zFinal[ClassVar[int]]n_fieldsn_sequence_fieldsn_unnamed_fieldsrP   r   c                C  r   )r   z4type 'StructSequence' is not an acceptable base typerk   r   rS   rS   rV   r     r   z StructSequence.__init_subclass__.sequenceIterable[_T_co]r   dict[str, Any]r!   c                C  r   )z.Create a new :class:`StructSequence` instance.r   )r\   r   r   rS   rS   rV   r     r   zStructSequence.__new__Nr   ).)r   r   r   r   rP   r!   )r^   r_   r`   ra   rv   r   r   r   rS   rS   rS   rV   rN     s   
 
rN   )	metaclass	structseqc                C  r   )z\Return whether the object is an instance of PyStructSequence or a class of PyStructSequence.)r   r   r?   r   rS   rS   rV   r>     r   r>   c                C  r   )z=Return whether the object is an instance of PyStructSequence.)r?   r   r   rS   rS   rV   r@     r   r@   r   Py_TPFLAGS_BASETYPEc             	   C  s   t | trL| jtfkrLt t| ddtrLt t| ddtrLt t| ddtrLt dkrDztj	d| fd W d	S  t
tfyC   Y dS w t| jt@  S d	S )
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   rS   rS   rV   r?     s$   r?   z type[types.MemberDescriptorType]StructSequenceFieldTypec                C  s   t | tr| }t|std|dnt| }t|s$td| dt dkr=dd t| D }t||j	d}ndd	 t| D }t
|d
|j S )z-Return the field names of a PyStructSequence.z&Expected a PyStructSequence type, got r}   z3Expected an instance of PyStructSequence type, got r   c                 S  s"   i | ]\}}t |tr||jqS rS   )r   r   r   r   r   memberrS   rS   rV   
<dictcomp>7  s    z$structseq_fields.<locals>.<dictcomp>)r   c                 S  s   g | ]\}}t |tr|qS rS   )r   r   r   rS   rS   rV   
<listcomp>>  s    z$structseq_fields.<locals>.<listcomp>N)r   r   r?   rl   r   r   varsr   sortedr   r   r   )r   r\   indices_by_namefieldsrS   rS   rV   rA   *  s"   


rA   )rd   re   rP   re   )r   re   rP   r   )r   r   rP   r   )r   r   rP   r   )r\   r   rP   r   )r   r   rP   r   )nra   
__future__r   r   rr   r   sysr   r   r   r   rK   r   rJ   r   rI   collectionsr   r   rL   r   rM   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.   r/   r0   r1   __all__r2   r   rB   rC   rD   rE   rF   rG   rH   r6   r7   r5   r   r   r   r   rc   ImportErrorr3   r4   r8   r9   r   r:   r<   r;   r=   r   r   rN   r   r>   r@   r   r?   version_infomajorr   rA   rS   rS   rS   rV   <module>   s   (<
 42 
"