
    c4                         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dS )    )warnN   )orderingambiguitiessuper_signatureAmbiguityWarning)expand_tuples)Variadic
isvariadicc                       e Zd ZdZdS )MDNotImplementedErrorz- A NotImplementedError for multiple dispatch N)__name__
__module____qualname____doc__     ;lib/python3.11/site-packages/multipledispatch/dispatcher.pyr   r   	   s        7777r   r   c                 V    t          t          | j        |          t                     dS )aC   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'     	jo{	3	35EFFFFFr   c                  0    t          dt                     dS )z:Deprecated 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                 0    t          dt                     dS )z9Deprecated 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 ]4}t          ||          }|V  t          |          st          |          }5	 t          |          }dV  dS # t          $ r t          |          sJ dV  Y dS w xY 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,   2   s      * >""G
w--C  S#&&# 	  w--C	w--C KKKKK  	 	 	c??"""JJJJJJ	s   A. .BBc                 D    |sJ t          t          | |                    S N)allr,   )r&   r'   s     r   variadic_signature_matchesr0   \   s'    .unEEF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dS )
DispatcheraW   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                 L    |x| _         | _        i | _        || _        i | _        d S r.   )r   r   r3   r6   r5   )selfr   r6   s      r   __init__zDispatcher.__init__z   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                 &     j         | fi  | S r.   )add)funckwargsr8   r&   s    r   _zDispatcher.register.<locals>._   s$    DHUD++F+++Kr   r   )r8   r&   r>   r?   s   ``` r   registerzDispatcher.register   s/    4	 	 	 	 	 	 	 r   c                     t          t          d          r-t          j        |          }|j                                        S d S )N	signature)hasattrinspectrB   
parametersvaluesclsr=   r)   s      r   get_func_paramszDispatcher.get_func_params   sB    7K(( 	+#D))C>((***	+ 	+r   c                     |                      |          }|rPt          j        fd|D             }t          d |D                       }t	          fd|D                       r|S dS dS )z; get annotations of function positional parameters
        c              3   F   K   | ]}|j         j        j        fv |V  d S r.   )kindPOSITIONAL_ONLYPOSITIONAL_OR_KEYWORD).0param	Parameters     r   	<genexpr>z2Dispatcher.get_func_annotations.<locals>.<genexpr>   sS       9 9 0 6889e 9 9 9 9 9 9r   c              3   $   K   | ]}|j         V  d S r.   )
annotation)rO   rP   s     r   rR   z2Dispatcher.get_func_annotations.<locals>.<genexpr>   s9        %  %   %  %  %  %  %  %r   c              3   *   K   | ]}|j         uV  d S r.   )empty)rO   annrQ   s     r   rR   z2Dispatcher.get_func_annotations.<locals>.<genexpr>   s*      EE#3io-EEEEEEr   N)rI   rD   rQ   tupler/   )rH   r=   paramsannotationsrQ   s       @r   get_func_annotationszDispatcher.get_func_annotations   s     $$T** 	#)I9 9 9 9 9 9 9F
    %  %# %  %  % % %K EEEEEEEEE #""	# 	## #r   c           	      V   |s|                      |          }|r|}t          d |D                       r*t          |          D ]}|                     ||           dS g }t	          |d          D ]\  }}t          |t          t          f          s<d                    d |D                       }t          d|d|d	| j
                  t          |t                    rk|t          |          k    rt          d
          t          |          dk    rt          d          |                    t          |d                             |                    |           || j        t          |          <   | j                                         	 | `dS # t&          $ r Y dS w xY w)aL   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                    V  d S r.   )
isinstancerX   )rO   r*   s     r   rR   z!Dispatcher.add.<locals>.<genexpr>   s,      ;;#z#u%%;;;;;;r   Nr   )start, c              3   l   K   | ]/}t          |t                    r|j        nt          |          V  0d S r.   )r^   typer   str)rO   cs     r   rR   z!Dispatcher.add.<locals>.<genexpr>   s\       $D $D45 3=Q2E2E %0AJJ),Q$D $D $D $D $D $Dr   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^   rb   listjoin	TypeErrorr   lenappendr
   r3   rX   r5   clearr4   AttributeError)	r8   rB   r=   rZ   typsnew_signatureindexr*   str_sigs	            r   r<   zDispatcher.add   s   &  	(33D99K ('	 ;;;;;;; 	%i00 % %t$$$$F#IQ777 	* 	*JE3cD$<00 ;)) $D $D9B$D $D $D D Di "%gggtyy!: ; ; ; #t$$ *C	NN* #E   s88q= #@  
 $$Xc!f%56666$$S))))+/
5''(	 	 	 	DD	s   F 
F('F(c                 Z    	 | j         S # t          $ r |                                 cY S w xY wr.   )r4   rm   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   rs   zDispatcher.reorder  sF    &tz222$*%% 	$Ls###	r   c           	         t          d |D                       }	 | j        |         }nN# t          $ rA  | j        | }|s(t	          d| j        dt          |          d          || j        |<   Y nw xY w	  ||i |S # t          $ rc  | 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)Nc                 ,    g | ]}t          |          S r   rb   rO   args     r   
<listcomp>z'Dispatcher.__call__.<locals>.<listcomp>      111StCyy111r   Could not find signature for : <>zMatching functions for z(> found, but none completed successfully)
rX   r5   KeyErrordispatchNotImplementedErrorr   str_signaturer   dispatch_iterr#   )r8   argsr>   r&   r=   r3   s         r   __call__zDispatcher.__call__
  s   11D11122	&;u%DD 	& 	& 	& 4=%(D 7))YYYe 4 4 4 467 7 7 "&DK	&	4(((($ 	 	 	&D&.EKKK  400000000,   D &% III}U3333  	s@   ) AA43A48B   'C-(B4/C-4
C>C- C,C-c                     d| j         z  S )Nz<dispatched %s>)r   rt   s    r   __str__zDispatcher.__str__(  s     49,,r   c                     || j         v r| j         |         S 	 t           | j        |           S # t          $ r Y dS 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.dispatch,  s`    , DJ 	%:e$$	**E2333 	 	 	44	s   / 
==c              '   V  K   t          |          }| j        D ]}t          |          |k    r5t          t          t          ||                    r| j        |         }|V  Jt          |          r6t          |d                   r!t          ||          r| j        |         }|V  d S )N)rj   r   r/   mapr$   r3   r   r0   )r8   r&   nrB   results        r   r   zDispatcher.dispatch_iterJ  s      JJ 	! 	!I9~~" !s3z5)+L+L'M'M !I.Y !Jy}$=$= !-eY?? !!Z	2F LLL	! 	!r   c                 @    t          dt                      | j        | S )z Deterimine 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.resolveV  s-     	<	! 	! 	! t}e$$r   c                      | j         | j        dS )Nr   r3   r   rt   s    r   __getstate__zDispatcher.__getstate__a  s    	% % 	%r   c                     |d         | _         |d         | _        t          | j                  | _        t	                      | _        d S )Nr   r3   )r   r3   r   r4   dictr5   )r8   ds     r   __setstate__zDispatcher.__setstate__e  s8    fI	wZ
!$*--ffr   c                 ,   d| j         z  g}| j        r|                    | j                   g }| j        d d d         D ]}| j        |         }|j        r\dt          |          z  }|dt          |          z  dz   z  }||j                                        z  }|                    |           r|                    t          |                     |r+|                    dd	                    |          z              d	                    |          S )	NzMultiply dispatched method: %sr   zInputs: <%s>
-
zOther signatures:
    z
    

)
r   r6   rk   r   r3   r   r   rj   striprh   )r8   docsotherr)   r=   ss         r   r   zDispatcher.__doc__k  s   049<=8 	"KK!!!=2& 	1 	1C:c?D| 1$}S'9'99S3q66\D((T\'')))A]3//0000 	JKK1HMM%4H4HHIII{{4   r   c                 F     | j         t          t          |           j        S r.   )r   r   rb   r   )r8   r   s     r   _helpzDispatcher._help  s    t}c$oo.66r   c                 4    t           | j        |            dS )z: Print docstring for the function corresponding to inputs N)printr   r8   r   r>   s      r   helpzDispatcher.help  s    jdj$     r   c                 |     | j         t          t          |           }|st          d          t	          |          S )NzNo function found)r   r   rb   ri   source)r8   r   r=   s      r   _sourcezDispatcher._source  s;    t}c$oo. 	1/000d||r   c                 4    t           | j        |            dS )z< Print source code for the function corresponding to inputs N)r   r   r   s      r   r   zDispatcher.source  s    ldlD!"""""r   r.   )r   r   r   r   	__slots__r9   r@   classmethodrI   r[   r<   propertyr   r   rs   r   r   __repr__r   r   r   r   r   r   r   r   r   r   r   r   r2   r2   b   s        * JI     > + + [+
 # # [#&@ @ @D " " X" $2      <- - -H  <
! 
! 
!	% 	% 	%% % %   ! ! X!,7 7 7! ! !  # # # # #r   r2   c                 b    dt          j        |           z  }|t          j        |           z   }|S )Nz
File: %s

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

    See Also:
        Dispatcher
    objrH   c                     t          t          d          rAt          j        |          }t          j        |j                                        dd           S d S )NrB   r   )rC   rD   rB   itlislicerE   rF   rG   s      r   rI   z MethodDispatcher.get_func_params  sS    7K(( 	@#D))C:cn3355q$???	@ 	@r   c                 "    || _         || _        | S r.   r   )r8   instanceowners      r   __get__zMethodDispatcher.__get__  s    r   c                     t          d |D                       } | j        | }|s(t          d| j        dt	          |          d           || j        g|R i |S )Nc                 ,    g | ]}t          |          S r   rz   r{   s     r   r}   z-MethodDispatcher.__call__.<locals>.<listcomp>  r~   r   r   r   r   )rX   r   r   r   r   r   )r8   r   r>   r&   r=   s        r   r   zMethodDispatcher.__call__  s    11D11122t}e$ 	I%%'+yyy-2F2F2F2F'H I I ItDH.t...v...r   N)	r   r   r   r   r   r   rI   r   r   r   r   r   r   r     s_         
 I@ @ [@
  
/ / / / /r   r   c                 @    d                     d | D                       S )zc String representation of type signature

    >>> str_signature((int, float))
    'int, float'
    r`   c              3   $   K   | ]}|j         V  d S r.   )r   )rO   rH   s     r   rR   z str_signature.<locals>.<genexpr>  s$      11cS\111111r   rh   )r)   s    r   r   r     s%     9911S111111r   c                      d z  }|dz  }|D ]*}|dd                     d |D                       z   dz   z  }+|dz  }|d                      fd	|D                       z  }|S )
z! The text for ambiguity warnings z.
Ambiguities exist in dispatched function %s

z;The following signatures may result in ambiguous behavior:
	r`   c              3   @   K   | ]}d t          |          z   dz   V  dS )[]N)r   )rO   r   s     r   rR   zwarning_text.<locals>.<genexpr>  s4      AAqcM!,,,s2AAAAAAr   r   z,

Consider making the following additions:

r   c                 Z    g | ]'}d t          t          |                    z   dz  z   (S )z
@dispatch(z)
def %s(...))r   r   )rO   r   r   s     r   r}   z warning_text.<locals>.<listcomp>  sQ     A A A78 &oa6H6H(I(II+d23 A A Ar   r   )r   rw   textpairs   `   r   r   r     s    >$GDJJD I IIIAADAAAAABDHI 	I>>DFKK A A A A<?A A A B B BDKr   )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      s          N N N N N N N N N N N N             * * * * * * * *    8 8 8 8 8/ 8 8 8G G G"   #1    ' ' 'TG G Go# o# o# o# o# o# o# o#d	  / / / / /z / / /82 2 2
 
 
 
 
r   