
    ij                       d Z ddlm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 ddlmZ ddlmZ ddlmZ dd	lmZmZ erdd
lmZ ddgZ ej0                  e      5  ddlmZ edgz  Zddd        G d d      Z ej8                  ej:                         G d dej<                  ee                Zy# 1 sw Y   MxY w)z)PyTree integration with :mod:`functools`.    )annotationsN)TYPE_CHECKINGAnyCallableClassVar)Self)registry)GetAttrEntry)tree_reduce)CustomTreeNodeT)PyTreeEntrypartialreduce)Placeholderr   c                  f    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ZddZddZ	ddZ
y)_HashablePartialShimzzA shim object that delegates :meth:`__call__`, :meth:`__eq__`, and :meth:`__hash__` to a :func:`functools.partial` object.)argsfunckeywordspartial_funczClassVar[tuple[str, ...]]	__slots__Callable[..., Any]r   ztuple[Any, ...]r   zdict[str, Any]r   c                   || _         y Nr   )selfr   s     e/var/www/html/emotional.easysim.app/public_html/venv/lib/python3.12/site-packages/optree/functools.py__init__z_HashablePartialShim.__init__8   s
    /;    c               &     | j                   |i |S r   r   )r   r   kwargss      r   __call__z_HashablePartialShim.__call__;   s     t  $1&11r    c               r    t        |t              r| j                  |j                  k(  S | j                  |k(  S r   )
isinstancer   r   )r   others     r   __eq__z_HashablePartialShim.__eq__>   s5    e12$$(:(:::  E))r    c               ,    t        | j                        S r   )hashr   r   s    r   __hash__z_HashablePartialShim.__hash__C       D%%&&r    c               ,    t        | j                        S r   )reprr   r*   s    r   __repr__z_HashablePartialShim.__repr__F   r,   r    N)r   zfunctools.partialreturnNone)r   r   r"   r   r0   r   )r&   objectr0   bool)r0   intr0   str)__name__
__module____qualname____doc__r   __annotations__r   r#   r'   r+   r/    r    r   r   r   /   s>     E+WI(W

<2*
''r    r   )	namespacec                       e Zd ZU dZdZded<   ded<   ded<   d	ed
<   eZded<   d fdZddZ		 	 ddZ
e	 	 	 	 	 	 dd       Z xZS )r   a  A version of :func:`functools.partial` that works in pytrees.

    Use it for partial function evaluation in a way that is compatible with transformations,
    e.g., ``partial(func, *args, **kwargs)``.

    (You need to explicitly opt-in to this behavior because we did not want to give
    :func:`functools.partial` different semantics than normal function closures.)

    For example, here is a basic usage of :class:`partial` in a manner similar to
    :func:`functools.partial`:

    >>> import operator
    >>> import torch
    >>> add_one = partial(operator.add, torch.ones(()))
    >>> add_one(torch.tensor([[1, 2], [3, 4]]))
    tensor([[2., 3.],
            [4., 5.]])

    Pytree compatibility means that the resulting partial function can be passed as an argument
    within tree-map functions, which is not possible with a standard :func:`functools.partial`
    function:

    >>> def call_func_on_cuda(f, *args, **kwargs):
    ...     f, args, kwargs = tree_map(lambda t: t.cuda(), (f, args, kwargs))
    ...     return f(*args, **kwargs)
    ...
    >>> # doctest: +SKIP
    >>> tree_map(lambda t: t.cuda(), add_one)
    optree.functools.partial(<built-in function add>, tensor(1., device='cuda:0'))
    >>> call_func_on_cuda(add_one, torch.tensor([[1, 2], [3, 4]]))
    tensor([[2., 3.],
            [4., 5.]], device='cuda:0')

    Passing zero arguments to :class:`partial` effectively wraps the original function, making it a
    valid argument in tree-map functions:

    >>> # doctest: +SKIP
    >>> call_func_on_cuda(partial(torch.add), torch.tensor(1), torch.tensor(2))
    tensor(3, device='cuda:0')

    Had we passed :func:`operator.add` to ``call_func_on_cuda`` directly, it would have resulted in
    a :class:`TypeError` or :class:`AttributeError`.

    On Python 3.14+, :data:`functools.Placeholder` can be used to reserve positional argument slots:

    >>> from functools import Placeholder  # doctest: +SKIP
    >>> square = partial(pow, Placeholder, 2)  # doctest: +SKIP
    >>> square(5)
    25

    :data:`~functools.Placeholder` objects are treated as leaves in the pytree and their identity is
    preserved through flatten/unflatten round-trips.
    r<   zClassVar[tuple[()]]r   r   r   ztuple[T, ...]r   zdict[str, T]r   zClassVar[type[PyTreeEntry]]TREE_PATH_ENTRY_TYPEc               2   t        |t        j                        ri|}t        |      }t	        |d      rJ d       t        |   | |g|i |}|j                  |_        |j                  |_        |j                  |_	        |S t        |   | |g|i |S )z'Create a new :class:`partial` instance.r   z3shimmed function should not have a `func` attribute)
r%   	functoolsr   r   hasattrsuper__new__r   r   r   )clsr   r   r   original_funcout	__class__s         r   rD   zpartial.__new__   s     dI--. M'6DtV,c.cc,'/#t?d?h?C%**DI%**DI)22DMJwsD<4<8<<r    c               V   t        | j                        g}|j                  d | j                  D               |j                  d | j                  j                         D               | j                  j                   d| j                  j                   ddj                  |       dS )z@Return a string representation of the :class:`partial` instance.c              3  2   K   | ]  }t        |        y wr   )r.   ).0xs     r   	<genexpr>z#partial.__repr__.<locals>.<genexpr>   s     /DG/s   c              3  0   K   | ]  \  }}| d |  yw)=Nr<   )rK   kvs      r   rM   z#partial.__repr__.<locals>.<genexpr>   s     EVaqc1%LEs   .(z, ))
r.   r   extendr   r   itemsrH   r8   r9   join)r   r   s     r   r/   zpartial.__repr__   s    TYY /TYY//Et}}/B/B/DEE..++,Adnn.I.I-J!DIIVZOK\\]^^r    c               L    | j                   | j                  f| j                  dfS )zAFlatten the :class:`partial` instance into children and metadata.)r   r   )r   r   r   r*   s    r   __tree_flatten__zpartial.__tree_flatten__   s#     		4==)4996JJJr    c               $    |\  }} | |g|i |S )zEUnflatten the children and metadata into a :class:`partial` instance.r<   )rE   metadatachildrenr   r   s        r   __tree_unflatten__zpartial.__tree_unflatten__   s"     "h8/d/h//r    )r   r   r   r   r   r   r0   r   r5   )r0   zNtuple[tuple[tuple[T, ...], dict[str, T]], Callable[..., Any], tuple[str, str]])r[   r   r\   z"tuple[tuple[T, ...], dict[str, T]]r0   r   )r7   r8   r9   r:   r   r;   r
   r?   rD   r/   rY   classmethodr]   __classcell__)rH   s   @r   r   r   K   s    
4l &(I"'

8D5D=$_	K
	K 0$0 50
 
0 0r    )r:   
__future__r   
contextlibrA   typingr   r   r   r   typing_extensionsr   optreer	   optree.accessorsr
   
optree.opsr   r   optree.typingr   r   r   __all__suppressImportErrorr   r   register_pytree_node_class__GLOBAL_NAMESPACEr   r<   r    r   <module>rm      s    0 "   9 9 "  ) , + ,  Z% %G	' '8 %$$x/J/JKo01o0 Lo0I s   B44B=