ó
€k[c           @   s  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 d e f d „  ƒ  YZ d	 „  Z d
 „  Z e d „ Z d „  Z d „  Z d e f d „  ƒ  YZ d „  Z d e f d „  ƒ  YZ d „  Z d „  Z d S(   iÿÿÿÿ(   t   warnNi   (   t   orderingt   ambiguitiest   super_signaturet   AmbiguityWarning(   t   expand_tuples(   t   Variadict
   isvariadict   MDNotImplementedErrorc           B   s   e  Z d  Z RS(   s-    A NotImplementedError for multiple dispatch (   t   __name__t
   __module__t   __doc__(    (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyR   	   s   c         C   s   t  t |  j | ƒ t ƒ d S(   sC   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    t   warning_textt   nameR   (   t
   dispatcherR   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   ambiguity_warn   s    c           C   s   t  d t ƒ d S(   s:   Deprecated interface to temporarily disable ordering.
    s=   halt_ordering is deprecated, you can safely remove this call.N(   R    t   DeprecationWarning(    (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   halt_ordering   s    c         C   s   t  d t ƒ d S(   s9   Deprecated interface to temporarily resume ordering.
    s   restart_ordering is deprecated, if you would like to eagerly orderthe dispatchers, you should call the ``reorder()`` method on each dispatcher.N(   R    R   (   t   on_ambiguity(    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   restart_ordering'   s    c         c   sœ   t  | ƒ } t | ƒ } x} |  D]5 } t | | ƒ } | Vt | ƒ s t | ƒ } q q Wy t | ƒ } Wn( t k
 r’ t | ƒ sŠ t ‚ t Vn Xt Vd S(   sj  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
    N(   t   itert   nextt
   issubclassR   t   StopIterationt   AssertionErrort   Truet   False(   t   typest   full_signaturet   sigitert   sigt   typt   matches(    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   variadic_signature_matches_iter2   s    	c         C   s   | s t  ‚ t t |  | ƒ ƒ S(   N(   R   t   allR!   (   R   R   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   variadic_signature_matches\   s    t
   Dispatcherc           B   sã   e  Z d  Z d Z d d „ Z d „  Z e d	 „  ƒ Z e d
 „  ƒ Z	 d „  Z
 e d „  ƒ Z e 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 RS(   sW   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   t   funcst	   _orderingt   _cachet   docc         C   s/   | |  _  |  _ i  |  _ | |  _ i  |  _ d  S(   N(   R   R	   R%   R(   R'   (   t   selfR   R(   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   __init__z   s    		c            s   ‡  ‡ ‡ f d †  } | S(   sÞ   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            s   ˆ j  ˆ |  ˆ   |  S(   N(   t   add(   t   func(   t   kwargsR)   R   (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   _›   s    (    (   R)   R   R-   R.   (    (   R-   R)   R   s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   register   s    c         C   s/   t  t d ƒ r+ t j | ƒ } | j j ƒ  Sd  S(   Nt	   signature(   t   hasattrt   inspectR0   t
   parameterst   values(   t   clsR,   R   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   get_func_params    s    c            sq   |  j  | ƒ } | rm t j ‰  ‡  f d †  | Dƒ } t d „  | Dƒ ƒ } t ‡  f d †  | Dƒ ƒ rm | Sn  d S(   s;    get annotations of function positional parameters
        c         3   s0   |  ]& } | j  ˆ  j ˆ  j f k r | Vq d  S(   N(   t   kindt   POSITIONAL_ONLYt   POSITIONAL_OR_KEYWORD(   t   .0t   param(   t	   Parameter(    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pys	   <genexpr>®   s    c         s   s   |  ] } | j  Vq d  S(   N(   t
   annotation(   R:   R;   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pys	   <genexpr>´   s   c         3   s   |  ] } | ˆ  j  k	 Vq d  S(   N(   t   empty(   R:   t   ann(   R<   (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pys	   <genexpr>·   s    N(   R6   R2   R<   t   tupleR"   (   R5   R,   t   paramst   annotations(    (   R<   s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   get_func_annotations¦   s    	c   	      C   s–  | s' |  j  | ƒ } | r' | } q' n  t d „  | Dƒ ƒ rh x$ t | ƒ D] } |  j | | ƒ qJ Wd Sg  } xã t | d d ƒD]Ï \ } } t | t t f ƒ sÚ d j d „  | Dƒ ƒ } t	 d | | |  j
 f ƒ ‚ n  t | t ƒ rC| t | ƒ k r
t	 d ƒ ‚ n  t | ƒ d k r+t	 d	 ƒ ‚ n  | j t | d
 ƒ q | j | ƒ q W| |  j t | ƒ <|  j j ƒ  y
 |  ` Wn t k
 r‘n Xd S(   sL   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         s   s   |  ] } t  | t ƒ Vq d  S(   N(   t
   isinstanceR@   (   R:   R   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pys	   <genexpr>Ó   s    Nt   starti   s   , c         s   s3   |  ]) } t  | t ƒ r! | j n	 t | ƒ Vq d  S(   N(   RD   t   typeR	   t   str(   R:   t   c(    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pys	   <genexpr>Ü   s   sD   Tried to dispatch on non-type: %s
In signature: <%s>
In function: %ss+   Variadic signature must be the last elements   Variadic signature must contain exactly one element. To use a variadic union type place the desired types inside of a tuple, e.g., [(int, str)]i    (   RC   t   anyR   R+   t	   enumerateRD   RF   t   listt   joint	   TypeErrorR   t   lent   appendR   R%   R@   R'   t   clearR&   t   AttributeError(	   R)   R0   R,   RB   t   typst   new_signaturet   indexR   t   str_sig(    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyR+   º   s<    
c         C   s*   y |  j  SWn t k
 r% |  j ƒ  SXd  S(   N(   R&   RQ   t   reorder(   R)   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyR   ü   s    c         C   s?   t  |  j ƒ |  _ } t |  j ƒ } | r; | |  | ƒ n  | S(   N(   R   R%   R&   R   (   R)   R   t   odt   amb(    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyRV     s
    c         O   s%  t  g  | D] } t | ƒ ^ q
 ƒ } y |  j | } WnU t k
 r |  j | Œ  } | s} t d |  j t | ƒ f ƒ ‚ n  | |  j | <n Xy | | | Ž  SWn t k
 r |  j	 | Œ  } t
 | ƒ x3 | D]+ } y | | | Ž  SWqÏ t k
 rù qÏ XqÏ Wt d |  j t | ƒ f ƒ ‚ n Xd  S(   Ns%   Could not find signature for %s: <%s>sF   Matching functions for %s: <%s> found, but none completed successfully(   R@   RF   R'   t   KeyErrort   dispatcht   NotImplementedErrorR   t   str_signatureR   t   dispatch_iterR   (   R)   t   argsR-   t   argR   R,   R%   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   __call__
  s.    %
c         C   s   d |  j  S(   Ns   <dispatched %s>(   R   (   R)   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   __str__(  s    c         G   sJ   | |  j  k r |  j  | Sy t |  j | Œ  ƒ SWn t k
 rE d SXd S(   sQ  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(   R%   R   R]   R   t   None(   R)   R   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyRZ   ,  s    c         g   s¦   t  | ƒ } x“ |  j D]ˆ } t  | ƒ | k r[ t t t | | ƒ ƒ r[ |  j | } | Vq t  | ƒ r t | d ƒ r t | | ƒ rž |  j | } | Vqž q q Wd  S(   Niÿÿÿÿ(   RN   R   R"   t   mapR   R%   R   R#   (   R)   R   t   nR0   t   result(    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyR]   J  s    *c         C   s   t  d t ƒ |  j | Œ  S(   s“    Deterimine appropriate implementation for this type signature

        .. deprecated:: 0.4.4
            Use ``dispatch(*types)`` instead
        s-   resolve() is deprecated, use dispatch(*types)(   R    R   RZ   (   R)   R   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   resolveV  s    c         C   s   i |  j  d 6|  j d 6S(   NR   R%   (   R   R%   (   R)   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   __getstate__a  s    c         C   s<   | d |  _  | d |  _ t |  j ƒ |  _ t ƒ  |  _ d  S(   NR   R%   (   R   R%   R   R&   t   dictR'   (   R)   t   d(    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   __setstate__e  s    c         C   s÷   d |  j  g } |  j r, | j |  j ƒ n  g  } x’ |  j d  d  d … D]z } |  j | } | j r° d t | ƒ } | d t | ƒ d 7} | | j j ƒ  7} | j | ƒ qI | j t | ƒ ƒ qI W| rê | j d d j	 | ƒ ƒ n  d j	 | ƒ S(	   Ns   Multiply dispatched method: %siÿÿÿÿs   Inputs: <%s>
t   -s   
s   Other signatures:
    s   
    s   

(
   R   R(   RO   R   R%   R   R\   RN   t   stripRL   (   R)   t   docst   otherR   R,   t   s(    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyR   k  s    		c         G   s   |  j  t t | ƒ Œ  j S(   N(   RZ   Rc   RF   R   (   R)   R^   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   _help‚  s    c         O   s   |  j  | Œ  GHd S(   s:    Print docstring for the function corresponding to inputs N(   Rp   (   R)   R^   R-   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   help…  s    c         G   s7   |  j  t t | ƒ Œ  } | s- t d ƒ ‚ n  t | ƒ S(   Ns   No function found(   RZ   Rc   RF   RM   t   source(   R)   R^   R,   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   _source‰  s    c         O   s   |  j  | Œ  GHd S(   s<    Print source code for the function corresponding to inputs N(   Rs   (   R)   R^   R-   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyRr     s    (   R	   R   R%   R&   R'   R(   N(   R	   R
   R   t	   __slots__Rb   R*   R/   t   classmethodR6   RC   R+   t   propertyR   R   RV   R`   Ra   t   __repr__RZ   R]   Rf   Rg   Rj   Rp   Rq   Rs   Rr   (    (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyR$   b   s,   		B										c         C   s*   d t  j |  ƒ } | t  j |  ƒ } | S(   Ns
   File: %s

(   R2   t   getsourcefilet	   getsource(   R,   Ro   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyRr   ”  s    t   MethodDispatcherc           B   s5   e  Z d  Z d Z e d „  ƒ Z d „  Z d „  Z RS(   sP    Dispatch methods based on type signature

    See Also:
        Dispatcher
    t   objR5   c         C   s>   t  t d ƒ r: t j | ƒ } t j | j j ƒ  d d  ƒ Sd  S(   NR0   i   (   R1   R2   R0   t   itlt   isliceR3   R4   Rb   (   R5   R,   R   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyR6   ¢  s    c         C   s   | |  _  | |  _ |  S(   N(   R{   R5   (   R)   t   instancet   owner(    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   __get__¨  s    		c         O   so   t  g  | D] } t | ƒ ^ q
 ƒ } |  j | Œ  } | s\ t d |  j t | ƒ f ƒ ‚ n  | |  j | | Ž S(   Ns%   Could not find signature for %s: <%s>(   R@   RF   RZ   R[   R   R\   R{   (   R)   R^   R-   R_   R   R,   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyR`   ­  s    %(   R{   R5   (   R	   R
   R   Rt   Ru   R6   R€   R`   (    (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyRz   š  s
   	c         C   s   d j  d „  |  Dƒ ƒ S(   sc    String representation of type signature

    >>> str_signature((int, float))
    'int, float'
    s   , c         s   s   |  ] } | j  Vq d  S(   N(   R	   (   R:   R5   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pys	   <genexpr>¼  s    (   RL   (   R   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyR\   ¶  s    c         C   s–   d |  } | d 7} x3 | D]+ } | d d j  d „  | Dƒ ƒ d 7} q W| d 7} | d j  g  | D]$ } d	 t t | ƒ ƒ d
 |  ^ qd ƒ 7} | S(   s!    The text for ambiguity warnings s.   
Ambiguities exist in dispatched function %s

s;   The following signatures may result in ambiguous behavior:
s   	s   , c         s   s#   |  ] } d  t  | ƒ d Vq d S(   t   [t   ]N(   R\   (   R:   Ro   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pys	   <genexpr>Å  s    s   
s,   

Consider making the following additions:

s   

s
   @dispatch(s   )
def %s(...)(   RL   R\   R   (   R   RX   t   textt   pairRo   (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyR   ¿  s    

&
2(   t   warningsR    R2   t   conflictR   R   R   R   t   utilsR   t   variadicR   R   t	   itertoolsR|   R[   R   R   R   R   R!   R#   t   objectR$   Rr   Rz   R\   R   (    (    (    s:   lib/python2.7/site-packages/multipledispatch/dispatcher.pyt   <module>   s"   "				*	ÿ 3			