
    H&h4                         d dl m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mZ d dlZ G d de      Zd	 Zd
 ZefdZd Zd Z G d de      Zd Z G d de      Zd Zd Zy)    )warnN   )orderingambiguitiessuper_signatureAmbiguityWarning)expand_tuples)Variadic
isvariadicc                       e Zd ZdZy)MDNotImplementedErrorz+A NotImplementedError for multiple dispatchN)__name__
__module____qualname____doc__     j/mounts/lovelace/software/anaconda3/envs/py312/lib/python3.12/site-packages/multipledispatch/dispatcher.pyr   r   	   s    5r   r   c                 L    t        t        | j                  |      t               y)aB  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   warning_textnamer   )
dispatcherr   s     r   ambiguity_warnr      s     	joo{	35EFr   c                  $    t        dt               y)z5Deprecated interface to temporarily disable ordering.z=halt_ordering is deprecated, you can safely remove this call.Nr   DeprecationWarningr   r   r   halt_orderingr      s    Gr   c                 $    t        dt               y)z4Deprecated interface to temporarily resume ordering.zrestart_ordering is deprecated, if you would like to eagerly orderthe dispatchers, you should call the ``reorder()`` method on each dispatcher.Nr   )on_ambiguitys    r   restart_orderingr    &   s    	 		r   c              #      K   t        |      }t        |      }| D ])  }t        ||      }| t        |      rt        |      }+ 	 t        |      }d y# t        $ r t        |      sJ d Y yw xY ww)aj  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
    FTN)iternext
issubclassr   StopIteration)typesfull_signaturesigitersigtypmatchess         r   variadic_signature_matches_iterr,   0   s     * >"G
w-C S#&# w-C	w-C K  	c?"J	s.   7A8A8A A8A52A84A55A8c                 4    |sJ t        t        | |            S N)allr,   )r&   r'   s     r   variadic_signature_matchesr0   Z   s    .unEFFr   c                       e Zd ZdZdZddZd Zed        Zed        Z	d Z
ed	        Zefd
Zd Zd ZeZd Zd Zd Zd Zd Zed        Zd Zd Zd Zd Zy)
DispatcheraV  Dispatch methods based on type signature

    Use ``dispatch`` to add implementations

    Examples
    --------

    >>> 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                 J    |x| _         | _        i | _        || _        i | _        y r.   )r   r   r3   r6   r5   )selfr   r6   s      r   __init__zDispatcher.__init__y   s%    $((	DM
r   c                       fd}|S )a  register dispatcher with new implementation

        >>> 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                 0     j                   | fi  | S r.   )add)funckwargsr8   r&   s    r   _dfz Dispatcher.register.<locals>._df   s    DHHUD+F+Kr   r   )r8   r&   r>   r?   s   ``` r   registerzDispatcher.register   s    6	 
r   c                     t        t        d      r/t        j                  |      }|j                  j	                         S y )N	signature)hasattrinspectrB   
parametersvaluesclsr=   r)   s      r   get_func_paramszDispatcher.get_func_params   s4    7K(##D)C>>((** )r   c                     | j                  |      }|rDt        j                  fd|D        }t        d |D              }t	        fd|D              r|S yy)z1get annotations of function positional parametersc              3   j   K   | ]*  }|j                   j                  j                  fv r| , y wr.   )kindPOSITIONAL_ONLYPOSITIONAL_OR_KEYWORD).0param	Parameters     r   	<genexpr>z2Dispatcher.get_func_annotations.<locals>.<genexpr>   s:      ::--y/N/NOP s   03c              3   4   K   | ]  }|j                     y wr.   )
annotation)rO   rP   s     r   rR   z2Dispatcher.get_func_annotations.<locals>.<genexpr>   s     EU 0 0E   c              3   :   K   | ]  }|j                   u  y wr.   )empty)rO   annrQ   s     r   rR   z2Dispatcher.get_func_annotations.<locals>.<genexpr>   s     E#3ioo-Es   N)rI   rD   rQ   tupler/   )rH   r=   paramsannotationsrQ   s       @r   get_func_annotationszDispatcher.get_func_annotations   sc     $$T*))I#F  EfEEKEEE"" F r   c           	         |s| j                  |      }|r|}t        d |D              r#t        |      D ]  }| j                  ||        yg }t	        |d      D ]  \  }}t        |t        t        f      s6dj                  d |D              }t        d|d|d	| j                        t        |t              rN|t        |      k7  rt        d
      t        |      dk7  rt        d      |j                  t        |d             |j                  |        || j                  t        |      <   | j                   j#                          	 | `y# t&        $ r Y yw xY w)aK  Add new types/method pair to dispatcher

        >>> 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              3   <   K   | ]  }t        |t                y wr.   )
isinstancerY   )rO   r*   s     r   rR   z!Dispatcher.add.<locals>.<genexpr>   s     ;#z#u%;s   Nr   )start, c              3   j   K   | ]+  }t        |t              r|j                  n
t        |       - y wr.   )r_   typer   str)rO   cs     r   rR   z!Dispatcher.add.<locals>.<genexpr>   s+      $FG*Q"5AJJ3q6A$s   13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   )r\   anyr	   r<   	enumerater_   rc   listjoin	TypeErrorr   lenappendr
   r3   rY   r5   clearr4   AttributeError)	r8   rB   r=   r[   typsnew_signatureindexr*   str_sigs	            r   r<   zDispatcher.add   sh   & 33D9K'	 ;;;%i0 %t$%#IQ7 	*JE3cD$<0)) $KT$    *-gtyyB  #t$C	N*#$QRRs8q=#@ 
 $$Xc!f%56$$S)1	*4 ,0

5'(	 		s   E 	E! E!c                 Z    	 | j                   S # t        $ r | j                         cY S w xY wr.   )r4   rn   reorderr8   s    r   r   zDispatcher.ordering   s,    	">>! 	"<<>!	"s    **c                 ~    t        | j                        x| _        }t        | j                        }|r	 || |       |S r.   )r   r3   r4   r   )r8   r   odambs       r   rt   zDispatcher.reorder  s7    &tzz22$**%s#	r   c           	         t        |D cg c]  }t        |       c}      }	 | j                  |   }	  ||i |S c c}w # t        $ rH  | j                  | }|s%t        d| j                  dt        |      d      || j                  |<   Y ^w xY w# t        $ rb  | j                  | }t        |       |D ]  }	  ||i |c cY S # t        $ r Y w xY w t        d| j                  dt        |      d      w xY w)NCould not find signature for : <>zMatching functions for z(> found, but none completed successfully)rY   rc   r5   KeyErrordispatchNotImplementedErrorr   str_signaturer   dispatch_iterr#   )r8   argsr>   argr&   r=   r3   s          r   __call__zDispatcher.__call__
  s    D1StCy12		&;;u%D	((( 2  	& 4==%(D)yy-"68  "&DKK	& % 	&D&&.EK 000,  & II!%(	 	sE   <A B ABB(D >C
D 
	CD C*D c                      d| j                   z  S )Nz<dispatched %s>)r   ru   s    r   __str__zDispatcher.__str__+  s     499,,r   c                     || j                   v r| j                   |   S 	 t         | j                  |       S # t        $ r Y yw xY w)aQ  Deterimine 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.

        >>> 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)r3   r#   r   r%   r8   r&   s     r   r~   zDispatcher.dispatch0  sO    , DJJ::e$$	***E233 		s   7 	AAc              '   2  K   t        |      }| j                  D ]y  }t        |      |k(  r.t        t        t        ||            r| j
                  |   }| ?t        |      sKt        |d         sZt        ||      sg| j
                  |   }| { y w)N)rk   r   r/   mapr$   r3   r   r0   )r8   r&   nrB   results        r   r   zDispatcher.dispatch_iterN  s     J 	!I9~"s3z5)+L'MI.YJy}$=-eY?!ZZ	2F L	!s   A"B%B4BBc                 @    t        dt                | j                  | S )zDeterimine appropriate implementation for this type signature

        .. deprecated:: 0.4.4
            Use ``dispatch(*types)`` instead
        z-resolve() is deprecated, use dispatch(*types))r   r   r~   r   s     r   resolvezDispatcher.resolveY  s!     	<>PQt}}e$$r   c                 4    | j                   | j                  dS )Nr   r3   r   ru   s    r   __getstate__zDispatcher.__getstate__c  s    		DJJ77r   c                 ~    |d   | _         |d   | _        t        | j                        | _        t	               | _        y )Nr   r3   )r   r3   r   r4   dictr5   )r8   ds     r   __setstate__zDispatcher.__setstate__f  s1    fI	wZ
!$**-fr   c                    d| j                   z  g}| j                  r|j                  | j                         g }| j                  d d d   D ]  }| j                  |   }|j
                  rQdt        |      z  }|dt        |      z  dz   z  }||j
                  j                         z  }|j                  |       o|j                  t        |              |r#|j                  ddj                  |      z          dj                  |      S )	NzMultiply dispatched method: %sr   zInputs: <%s>
-
zOther signatures:
    z
    

)
r   r6   rl   r   r3   r   r   rk   stripri   )r8   docsotherr)   r=   ss         r   r   zDispatcher.__doc__l  s    0499<=88KK!==2& 	1C::c?D||$}S'99S3q6\D((T\\''))A]3/0	1 KK1HMM%4HHI{{4  r   c                 P     | j                   t        t        |       j                  S r.   )r~   r   rc   r   )r8   r   s     r   _helpzDispatcher._help  s    t}}c$o.666r   c                 4    t         | j                  |        y)z8Print docstring for the function corresponding to inputsN)printr   r8   r   r>   s      r   helpzDispatcher.help  s    jdjj$ r   c                 l     | j                   t        t        |       }|st        d      t	        |      S )NzNo function found)r~   r   rc   rj   source)r8   r   r=   s      r   _sourcezDispatcher._source  s1    t}}c$o./00d|r   c                 4    t         | j                  |        y)z:Print source code for the function corresponding to inputsN)r   r   r   s      r   r   zDispatcher.source  s    ldllD!"r   r.   )r   r   r   r   	__slots__r9   r@   classmethodrI   r\   r<   propertyr   r   rt   r   r   __repr__r~   r   r   r   r   r   r   r   r   r   r   r   r2   r2   `   s    , JIB + +
 # #$@D " " $2 B- H<	!%8 ! !,7!#r   r2   c                 f    dt        j                  |       z  }|t        j                  |       z   }|S )Nz
File: %s

)rD   getsourcefile	getsource)r=   r   s     r   r   r     s1    ..t44A	Gd##AHr   c                   0    e Zd ZdZdZed        Zd Zd Zy)MethodDispatcherzODispatch methods based on type signature

    See Also:
        Dispatcher
    objrH   c                     t        t        d      rDt        j                  |      }t        j                  |j
                  j                         dd       S y )NrB   r   )rC   rD   rB   itlislicerE   rF   rG   s      r   rI   z MethodDispatcher.get_func_params  sA    7K(##D)C::cnn335q$?? )r   c                 "    || _         || _        | S r.   r   )r8   instanceowners      r   __get__zMethodDispatcher.__get__  s    r   c                     t        |D cg c]  }t        |       c}      } | j                  | }|s%t        d| j                  dt        |      d       || j                  g|i |S c c}w )Nrz   r{   r|   )rY   rc   r~   r   r   r   r   )r8   r   r>   r   r&   r=   s         r   r   zMethodDispatcher.__call__  sn    D1StCy12t}}e$%99mE24  DHH.t.v.. 2s   A/N)	r   r   r   r   r   r   rI   r   r   r   r   r   r   r     s,     I@ @

/r   r   c                 2    dj                  d | D              S )zbString representation of type signature

    >>> str_signature((int, float))
    'int, float'
    ra   c              3   4   K   | ]  }|j                     y wr.   )r   )rO   rH   s     r   rR   z str_signature.<locals>.<genexpr>  s     1cS\\1rU   )ri   )r)   s    r   r   r     s     991S111r   c                     d| z  }|dz  }|D ]#  }|ddj                  d |D              z   dz   z  }% |dz  }|dj                  |D cg c]  }d	t        t        |            z   d
| z  z   ! c}      z  }|S c c}w )zThe text for ambiguity warningsz.
Ambiguities exist in dispatched function %s

z;The following signatures may result in ambiguous behavior:
	ra   c              3   >   K   | ]  }d t        |      z   dz     yw)[]N)r   )rO   r   s     r   rR   zwarning_text.<locals>.<genexpr>  s      L!}Q'7!7#!= Ls   r   z,

Consider making the following additions:

r   z
@dispatch(z)
def %s(...))ri   r   r   )r   rx   textpairr   s        r   r   r     s    >$GDJJD Ttyy Lt LLLtSST>>DFKK 	
 =);<<?ORV?VV	
 D K	
s   $A7
)warningsr   rD   conflictr   r   r   r   utilsr	   variadicr
   r   	itertoolsr   r   r   r   r   r    r,   r0   objectr2   r   r   r   r   r   r   r   <module>r      sr      N N   * 6/ 6G" #1 'TGr# r#j	/z />2r   