
    MZd/                        U d dl mZ 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Z G d de      Zd	 Z G d
 d      Zd Z e       Zded<   dgZd ZefdZ G d d      Zd Z G d de      Zd Zd Zy)    )annotations)warnN   )orderingambiguitiessuper_signatureAmbiguityWarning)expand_tuplesc                      e Zd ZdZy)MDNotImplementedErrorz- A NotImplementedError for multiple dispatch N)__name__
__module____qualname____doc__     C/usr/lib/python3/dist-packages/sympy/multipledispatch/dispatcher.pyr   r   
   s    7r   r   c                L    t        t        | j                  |      t               y)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     	joo{	35EFr   c                      e Zd ZdZd Zd Zy)RaiseNotImplementedErrorz*Raise ``NotImplementedError`` when called.c                    || _         y N)r   )selfr   s     r   __init__z!RaiseNotImplementedError.__init__$   s	    $r   c                    t        d |D              }t        d| j                  j                  dt	        |      d      )Nc              3  2   K   | ]  }t        |        y wr   )type).0as     r   	<genexpr>z4RaiseNotImplementedError.__call__.<locals>.<genexpr>(   s     ,!d1g,s   zAmbiguous signature for : <>)tupleNotImplementedErrorr   r   str_signature)r   argskwargstypess       r   __call__z!RaiseNotImplementedError.__call__'   s8    ,t,,!OO  -"6
 	r   N)r   r   r   r   r   r-   r   r   r   r   r   !   s    4%r   r   c                    |D ]O  }t        t        |            }t        t        |            dk(  r/| j	                  |t        |       t               Q y)a  
    If super signature for ambiguous types is duplicate types, ignore it.
    Else, register instance of ``RaiseNotImplementedError`` for ambiguous types.

    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
        ambiguity_warn
    r   on_ambiguityN)r'   r   lensetaddr   #ambiguity_register_error_ignore_dup)r   r   amb	signatures       r   r4   r4   .   sU       
/#./	s9~!#/
;< 	 	
	
r   zset[Dispatcher]_unresolved_dispatchersTc                     dt         d<   y )NFr   )_resolver   r   r   halt_orderingr:   N   s    HQKr   c                ~    dt         d<   t        r.t        j                         }|j                  |        t        r-y y )NTr   r/   )r9   r7   popreorder)r0   r   s     r   restart_orderingr>   R   s5    HQK
!,002
5 "
!r   c                      e Zd ZdZdZddZd Zed        Zed        Z	e
f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)
Dispatcheraj   Dispatch methods based on type signature

    Use ``dispatch`` to add implementations

    Examples
    --------

    >>> from sympy.multipledispatch import dispatch
    >>> @dispatch(int)
    ... def f(x):
    ...     return x + 1

    >>> @dispatch(float)
    ... def f(x): # noqa: F811
    ...     return x - 1

    >>> f(3)
    4
    >>> f(3.0)
    2.0
    )r   r   funcsr   _cachedocNc                X    |x| _         | _        i | _        i | _        g | _        || _        y r   )r   r   rA   rB   r   rC   )r   r   rC   s      r   r   zDispatcher.__init__q   s,    $((	DM
r   c                      fd}|S )a#   Register dispatcher with new implementation

        >>> from sympy.multipledispatch.dispatcher import Dispatcher
        >>> 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   )r3   )funcr+   r   r,   s    r   _zDispatcher.register.<locals>._   s    DHHUD+F+Kr   r   )r   r,   r+   rH   s   ``` r   registerzDispatcher.registerx   s    6	 r   c                    t        t        d      r/t        j                  |      }|j                  j	                         S y )Nr6   )hasattrinspectr6   
parametersvaluesclsrG   sigs      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              s|S yy)z; Get annotations of function positional parameters
        c              3  j   K   | ]*  }|j                   j                  j                  fv r| , y wr   )kindPOSITIONAL_ONLYPOSITIONAL_OR_KEYWORD)r"   param	Parameters     r   r$   z2Dispatcher.get_func_annotations.<locals>.<genexpr>   s;      9 00 6688  9s   03c              3  4   K   | ]  }|j                     y wr   )
annotation)r"   rX   s     r   r$   z2Dispatcher.get_func_annotations.<locals>.<genexpr>   s       %    %   c              3  :   K   | ]  }|j                   u   y wr   )empty)r"   annrY   s     r   r$   z2Dispatcher.get_func_annotations.<locals>.<genexpr>   s     E#sioo-Es   N)rR   rL   rY   r'   any)rP   rG   paramsr   rY   s       @r   get_func_annotationszDispatcher.get_func_annotations   sk     $$T*))I9 9F
    %# % %K EEE"" F r   c           	        |s| j                  |      }|r|}t        d |D              r$t        |      D ]  }| j                  |||        y|D ]H  }t	        |t
              rdj                  d |D              }t        d|d|d| j                         || j                  |<   | j                  |       | j                  j                          y)	a   Add new types/method pair to dispatcher

        >>> from sympy.multipledispatch import 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   )
isinstancer'   )r"   typs     r   r$   z!Dispatcher.add.<locals>.<genexpr>   s     ;#z#u%;s   N, c              3  j   K   | ]+  }t        |t              r|j                  n
t        |       - y wr   )re   r!   r   str)r"   cs     r   r$   z!Dispatcher.add.<locals>.<genexpr>   s3      $D45 3=Q2EAJJ),Q%0 $Ds   13zTried to dispatch on non-type: z
In signature: <z>
In function: r/   )rb   r`   r
   r3   re   r!   join	TypeErrorr   rA   r=   rB   clear)r   r6   rG   r0   r   typsrf   str_sigs           r   r3   zDispatcher.add   s    ( 33D9K'	 ;;;%i0 3t\23 	;Cc4()) $D9B$D D "%gtyy!: ; ;		; !%

9,/r   c                    t         d   r<t        | j                        | _        t        | j                        }|r
 || |       y y t        j                  |        y )Nr   )r9   r   rA   r   r7   r3   )r   r0   r5   s      r   r=   zDispatcher.reorder   sI    A;$TZZ0DMdjj)CT3'  $''-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 r%   r&   zMatching functions for z(> found, but none completed successfully)r'   r!   rB   KeyErrordispatchr(   r   r)   r   dispatch_iternext)r   r*   r+   argr,   rG   rA   s          r   r-   zDispatcher.__call__   s#   D1StCy12	&;;u%D	K((( 2  	& 4==%(D)YYe 467 7 "&DKK	& % 
	K&D&&.EK 000, 
 &)-M%4H'J K K
	KsE   <A B ABB(D >C
D 
	CD C*D c                     d| j                   z  S )Nz<dispatched %s>)r   r   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)a`   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 sympy.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:
            ``sympy.multipledispatch.conflict`` - module to determine resolution order
        N)rA   rv   ru   StopIterationr   r,   s     r   rt   zDispatcher.dispatch  sO    , DJJ::e$$	***E233 		s   7 	AAc              '     K   t        |      }| j                  D ]?  }t        |      |k(  st        t        t        ||            s-| j
                  |   }| A y wr   )r1   r   allmap
issubclassrA   )r   r,   nr6   results        r   ru   zDispatcher.dispatch_iter#  sQ     J 	I9~"s3z5)+L'MI.	s   )AAA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   DeprecationWarningrt   r}   s     r   resolvezDispatcher.resolve*  s%     	<	! t}}e$$r   c                4    | j                   | j                  dS )Nr   rA   r   ry   s    r   __getstate__zDispatcher.__getstate__5  s    		% 	%r   c                n    |d   | _         |d   | _        t        | j                        | _        i | _        y )Nr   rA   )r   rA   r   rB   )r   ds     r   __setstate__zDispatcher.__setstate__9  s/    fI	wZ
 ,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: %szInputs: <%s>
-
zOther signatures:
    z
    

)
r   rC   appendr   rA   r   r)   r1   striprk   )r   docsotherrQ   rG   ss         r   r   zDispatcher.__doc__?  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   )rt   r   r!   r   )r   r*   s     r   _helpzDispatcher._helpV  s    t}}c$o.666r   c                4    t         | j                  |        y)z: Print docstring for the function corresponding to inputs N)printr   r   r*   r+   s      r   helpzDispatcher.helpY  s    jdjj$ r   c                l     | j                   t        t        |       }|st        d      t	        |      S )NzNo function found)rt   r   r!   rl   source)r   r*   rG   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 inputs N)r   r   r   s      r   r   zDispatcher.sourcec  s    ldllD!"r   r   )r   r   r   r   	__slots__r   rI   classmethodrR   rb   r   r3   r=   r-   rz   __repr__rt   ru   r   r   r   propertyr   r   r   r   r   r   r   r@   r@   Y   s    * II@ + +
 # #& 1? *X $2 .K4-H<	%% ! !,7!#r   r@   c                f    dt        j                  |       z  }|t        j                  |       z   }|S )Nz
File: %s

)rL   getsourcefile	getsource)rG   r   s     r   r   r   h  s1    ..t44A	Gd##AHr   c                  ,    e Zd ZdZed        Zd Zd Zy)MethodDispatcherzP Dispatch methods based on type signature

    See Also:
        Dispatcher
    c                    t        t        d      rDt        j                  |      }t        j                  |j
                  j                         dd       S y )Nr6   r   )rK   rL   r6   itlislicerM   rN   rO   s      r   rR   z MethodDispatcher.get_func_paramsu  sA    7K(##D)C::cnn335q$?? )r   c                "    || _         || _        | S r   )objrP   )r   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 )Nrr   r%   r&   )r'   r!   rt   r(   r   r)   r   )r   r*   r+   rw   r,   rG   s         r   r-   zMethodDispatcher.__call__  so    D1StCy12t}}e$%'+yy-2F'H I IDHH.t.v.. 2s   A/N)r   r   r   r   r   rR   r   r-   r   r   r   r   r   n  s'     @ @

/r   r   c                2    dj                  d | D              S )z String representation of type signature

    >>> from sympy.multipledispatch.dispatcher import str_signature
    >>> str_signature((int, float))
    'int, float'
    rg   c              3  4   K   | ]  }|j                     y wr   )r   )r"   rP   s     r   r$   z str_signature.<locals>.<genexpr>  s     1cS\\1r\   )rk   )rQ   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 warnings z.
Ambiguities exist in dispatched function %s

z;The following signatures may result in ambiguous behavior:
	rg   c              3  >   K   | ]  }d t        |      z   dz     yw)[]N)r)   )r"   r   s     r   r$   zwarning_text.<locals>.<genexpr>  s     AqcM!,,s2As   r   z,

Consider making the following additions:

r   z
@dispatch(z)
def %s(...))rk   r)   r   )r   r5   textpairr   s        r   r   r     s    >$GDJJD IIIADAABDHI 	II 	>>DFKK<?A78 &oa6H(II+d23 A B BDKAs   $A7
)
__future__r   warningsr   rL   conflictr   r   r   r	   utilsr
   	itertoolsr   r(   r   r   r   r4   r2   r7   __annotations__r9   r:   r>   r@   r   r   r)   r   r   r   r   <module>r      s    "   N N   8/ 8G" 
8 ,/5  06 #1 6L# L#^/z /62
r   