o
    Zh"6                     @   s   d dl Z d dlZd dlmZ d dlmZ ddlmZm	Z	m
Z
mZ ddlmZ ddlmZmZ g dZG d	d
 d
eZdd Zededdd ZededefddZdd Zdd ZG dd dZdd ZG dd deZdd Zd d! ZdS )"    N)
deprecated)warn   )ambiguitiesAmbiguityWarningorderingsuper_signature)expand_tuples)
isvariadicVariadic)MDNotImplementedErrorambiguity_warnhalt_orderingrestart_orderingvariadic_signature_matches_itervariadic_signature_matches
DispatchersourceMethodDispatcherstr_signaturewarning_textc                   @   s   e Zd ZdZdS )r   z+A NotImplementedError for multiple dispatchN)__name__
__module____qualname____doc__ r   r   l/var/www/auris/lib/python3.10/site-packages/torch/fx/experimental/unification/multipledispatch/dispatcher.pyr      s    r   c                 C   s   t t| j|t dS )a@  Raise warning when ambiguity is detected
    Parameters
    ----------
    dispatcher : Dispatcher
        The dispatcher on which the ambiguity was detected
    ambiguities : set
        Set of type signature pairs that are ambiguous within this dispatcher
    See Also:
        Dispatcher.add
        warning_text
    N)r   r   namer   )
dispatcherr   r   r   r   r      s   r   z?`halt_ordering` is deprecated, you can safely remove this call.categoryc                   C      dS )z5Deprecated interface to temporarily disable ordering.Nr   r   r   r   r   r   .       r   z`restart_ordering` is deprecated, if you would like to eagerly order the dispatchers, you should call the `reorder()` method on each dispatcher.c                 C   r!   )z4Deprecated interface to temporarily resume ordering.Nr   )on_ambiguityr   r   r   r   6   r"   r   c                 c   sz    t |}t|}| D ]}t||}|V  t|st|}qzt|}W n ty7   t|s1J dV  Y dS w dV  dS )ag  Check if a set of input types matches a variadic signature.
    Notes
    -----
    The algorithm is as follows:
    Initialize the current signature to the first in the sequence
    For each type in `types`:
        If the current signature is variadic
            If the type matches the signature
                yield True
            Else
                Try to get the next signature
                If no signatures are left we can't possibly have a match
                    so yield False
        Else
            yield True if the type matches the current signature
            Get the next signature
    TFN)iternext
issubclassr
   StopIteration)typesfull_signatureZsigitersigtypmatchesr   r   r   r   ?   s    

r   c                 C   s   |sJ t t| |S N)allr   )r(   r)   r   r   r   r   f   s   r   c                   @   s   e Zd ZdZdZd,ddZdd Zedd	 Zed
d Z	dd Z
edd ZefddZdd Zdd ZeZdd Zdd Zededdd Zdd Zd d! Zed"d# Zd$d% Zd&d' Zd(d) Zd*d+ ZdS )-r   a~  Dispatch methods based on type signature
    Use ``dispatch`` to add implementations
    Examples
    --------
    >>> # xdoctest: +SKIP("bad import name")
    >>> from multipledispatch import dispatch
    >>> @dispatch(int)
    ... def f(x):
    ...     return x + 1
    >>> @dispatch(float)
    ... def f(x):
    ...     return x - 1
    >>> f(3)
    4
    >>> f(3.0)
    2.0
    )r   r   funcs	_ordering_cachedocNc                 C   s"   | | _ | _i | _|| _i | _d S r-   )r   r   r/   r2   r1   )selfr   r2   r   r   r   __init__   s   
zDispatcher.__init__c                    s    fdd}|S )a  register dispatcher with new implementation
        >>> # xdoctest: +SKIP
        >>> f = Dispatcher("f")
        >>> @f.register(int)
        ... def inc(x):
        ...     return x + 1
        >>> @f.register(float)
        ... def dec(x):
        ...     return x - 1
        >>> @f.register(list)
        ... @f.register(tuple)
        ... def reverse(x):
        ...     return x[::-1]
        >>> f(1)
        2
        >>> f(1.0)
        0.0
        >>> f([1, 2, 3])
        [3, 2, 1]
        c                    s   j | fi   | S r-   )add)funckwargsr3   r(   r   r   _df   s   z Dispatcher.register.<locals>._dfr   )r3   r(   r8   r9   r   r7   r   register   s   zDispatcher.registerc                 C   s"   t tdrt|}|j S d S )N	signature)hasattrinspectr;   
parametersvaluesclsr6   r*   r   r   r   get_func_params   s   


zDispatcher.get_func_paramsc                    sZ   |  |}|r)tj  fdd|D }tdd |D }t fdd|D r+|S dS dS )z1get annotations of function positional parametersc                 3   s&    | ]}|j  j jfv r|V  qd S r-   )kindPOSITIONAL_ONLYPOSITIONAL_OR_KEYWORD.0param	Parameterr   r   	<genexpr>   s    
z2Dispatcher.get_func_annotations.<locals>.<genexpr>c                 s       | ]}|j V  qd S r-   )
annotationrF   r   r   r   rK          c                 3   s    | ]}| j uV  qd S r-   )empty)rG   annrI   r   r   rK          N)rB   r=   rJ   tupler.   )rA   r6   paramsannotationsr   rI   r   get_func_annotations   s   

zDispatcher.get_func_annotationsc           	      C   s&  |s|  |}|r|}tdd |D r#t|D ]}| || qdS g }t|ddD ]K\}}t|ttfsNddd |D }t	d| d	| d
| j
 t|trq|t|kr]t	dt|dkrgt	d|t|d   q+|| q+|| jt|< | j  z| `W dS  ty   Y dS w )ax  Add new types/method pair to dispatcher
        >>> # xdoctest: +SKIP
        >>> D = Dispatcher("add")
        >>> D.add((int, int), lambda x, y: x + y)
        >>> D.add((float, float), lambda x, y: x + y)
        >>> D(1, 2)
        3
        >>> D(1, 2.0)
        Traceback (most recent call last):
        ...
        NotImplementedError: Could not find signature for add: <int, float>
        >>> # When ``add`` detects a warning it calls the ``on_ambiguity`` callback
        >>> # with a dispatcher/itself, and a set of ambiguous type signature pairs
        >>> # as inputs.  See ``ambiguity_warn`` for an example.
        c                 s   s    | ]}t |tV  qd S r-   )
isinstancerR   )rG   r+   r   r   r   rK      rQ   z!Dispatcher.add.<locals>.<genexpr>Nr   )start, c                 s   s(    | ]}t |tr|jnt|V  qd S r-   )rV   typer   str)rG   cr   r   r   rK      s    
zTried to dispatch on non-type: z
In signature: <z>
In function: z+Variadic signature must be the last elementzVariadic signature must contain exactly one element. To use a variadic union type place the desired types inside of a tuple, e.g., [(int, str)]r   )rU   anyr	   r5   	enumeraterV   rY   listjoin	TypeErrorr   lenappendr   r/   rR   r1   clearr0   AttributeError)	r3   r;   r6   rT   ZtypsZnew_signatureindexr+   Zstr_sigr   r   r   r5      sJ   




zDispatcher.addc                 C   s$   z| j W S  ty   |   Y S w r-   )r0   rd   reorderr3   r   r   r   r      s
   zDispatcher.orderingc                 C   s,   t | j | _}t| j}|r|| | |S r-   )r   r/   r0   r   )r3   r#   Zodambr   r   r   rf     s
   

zDispatcher.reorderc                 O   s  t dd |D }z| j| }W n- ty= } z!| j| }|s.td| j dt| d||| j|< W Y d }~nd }~ww z||i |W S  ty } z6| j| }t	| |D ]}z||i |W   W  Y d }~S  tyt   Y qYw td| j dt| d|d }~ww )Nc                 S      g | ]}t |qS r   rY   rG   argr   r   r   
<listcomp>      z'Dispatcher.__call__.<locals>.<listcomp>Could not find signature for : <>zMatching functions for z(> found, but none completed successfully)
rR   r1   KeyErrordispatchNotImplementedErrorr   r   r   dispatch_iterr%   )r3   argsr8   r(   r6   er/   r   r   r   __call__  sH   

 zDispatcher.__call__c                 C   s   d| j  dS )Nz<dispatched rq   r   rg   r   r   r   __str__'     zDispatcher.__str__c                 G   s:   || j v r
| j | S zt| j| W S  ty   Y dS w )ai  Determine appropriate implementation for this type signature
        This method is internal.  Users should call this object as a function.
        Implementation resolution occurs within the ``__call__`` method.
        >>> # xdoctest: +SKIP
        >>> from multipledispatch import dispatch
        >>> @dispatch(int)
        ... def inc(x):
        ...     return x + 1
        >>> implementation = inc.dispatch(int)
        >>> implementation(3)
        4
        >>> print(inc.dispatch(float))
        None
        See Also:
          ``multipledispatch.conflict`` - module to determine resolution order
        N)r/   r%   ru   r'   r3   r(   r   r   r   rs   ,  s   

zDispatcher.dispatchc                 g   sv    t |}| jD ]0}t ||kr!ttt||r!| j| }|V  qt |r8t|d r8t||r8| j| }|V  qd S )N)ra   r   r.   mapr&   r/   r
   r   )r3   r(   nr;   resultr   r   r   ru   F  s   



zDispatcher.dispatch_iterz1`resolve()` is deprecated, use `dispatch(*types)`r   c                 C   s
   | j | S )zDetermine appropriate implementation for this type signature
        .. deprecated:: 0.4.4
            Use ``dispatch(*types)`` instead
        )rs   r|   r   r   r   resolveQ  s   
zDispatcher.resolvec                 C   s   | j | jdS )Nr   r/   r   rg   r   r   r   __getstate__[  r{   zDispatcher.__getstate__c                 C   s*   |d | _ |d | _t| j| _i | _d S )Nr   r/   )r   r/   r   r0   r1   )r3   dr   r   r   __setstate__^  s   


zDispatcher.__setstate__c                 C   s   d| j  g}| jr|| j g }| jd d d D ]0}| j| }|jrCdt| d}|dt| d 7 }||j 7 }|| q|t| q|rW|dd	|  d		|S )
NzMultiply dispatched method: r}   z	Inputs: <z>
-
zOther signatures:
    z
    

)
r   r2   rb   r   r/   r   r   ra   stripr_   )r3   docsotherr*   r6   sr   r   r   r   d  s   

zDispatcher.__doc__c                 G   s   | j tt| jS r-   )rs   r~   rY   r   )r3   rv   r   r   r   _help{  s   zDispatcher._helpc                 O      t | j|  dS )z8Print docstring for the function corresponding to inputsN)printr   r3   rv   r8   r   r   r   help~     zDispatcher.helpc                 G   s$   | j tt| }|stdt|S )NzNo function found)rs   r~   rY   r`   r   )r3   rv   r6   r   r   r   _source  s   zDispatcher._sourcec                 O   r   )z:Print source code for the function corresponding to inputsN)r   r   r   r   r   r   r     r   zDispatcher.sourcer-   )r   r   r   r   	__slots__r4   r:   classmethodrB   rU   r5   propertyr   r   rf   rx   rz   __repr__rs   ru   r   FutureWarningr   r   r   r   r   r   r   r   r   r   r   r   l   s<    


@


r   c                 C   s$   dt |  d}|t |  }|S )NzFile: r   )r=   getsourcefile	getsource)r6   r   r   r   r   r     s   r   c                   @   s0   e Zd ZdZdZedd Zdd Zdd Zd	S )
r   zNDispatch methods based on type signature
    See Also:
        Dispatcher
    objrA   c                 C   s,   t tdrt|}t|j dd S d S )Nr;   r   )r<   r=   r;   itlislicer>   r?   r@   r   r   r   rB     s   

z MethodDispatcher.get_func_paramsc                 C   s   || _ || _| S r-   r   )r3   instanceownerr   r   r   __get__  s   zMethodDispatcher.__get__c                 O   sT   t dd |D }| j| }|std| j dt| d|| jg|R i |S )Nc                 S   ri   r   rj   rk   r   r   r   rm     rn   z-MethodDispatcher.__call__.<locals>.<listcomp>ro   rp   rq   )rR   rs   rt   r   r   r   )r3   rv   r8   r(   r6   r   r   r   rx     s   
zMethodDispatcher.__call__N)	r   r   r   r   r   r   rB   r   rx   r   r   r   r   r     s    
r   c                 C   s   d dd | D S )zaString representation of type signature
    >>> str_signature((int, float))
    'int, float'
    rX   c                 s   rL   r-   )r   )rG   rA   r   r   r   rK     rN   z str_signature.<locals>.<genexpr>r_   )r*   r   r   r   r     s   r   c                    sf   d  d}|d7 }|D ]}|dd dd |D  d 7 }q|d	7 }|d  fd
d|D 7 }|S )zThe text for ambiguity warningsz*
Ambiguities exist in dispatched function r   z;The following signatures may result in ambiguous behavior:
	rX   c                 s   s     | ]}d t | d V  qdS )[]N)r   rG   r   r   r   r   rK     s    zwarning_text.<locals>.<genexpr>r   z,

Consider making the following additions:

c                    s(   g | ]}d t t| d  d qS )z
@dispatch(z)
def z(...))r   r   r   ry   r   r   rm     s    z warning_text.<locals>.<listcomp>r   )r   rh   textpairr   ry   r   r     s   "
r   )r=   	itertoolsr   Ztyping_extensionsr   warningsr   conflictr   r   r   r   utilsr	   Zvariadicr
   r   __all__rt   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s:   
'  #