
    [c|t                     X   d dl mZmZ d dlZd dlZd dlmZmZ d dlm	Z	 d dl
mZ ddlmZ  eed          oej        d          d	k    Zd
Z eed          Zd Zd Zd Zd Zd2dZ G d de          Z G d de          Zd Zed3d            Z G d de          Zd Zd Zd Z d Z! G d de          Z"d Z#ed             Z$d  Z% G d! d"e          Z&d# Z'ere'Z(d$ Z'd%e'_)        d4d&Z*d4d'Z+d4d(Z,d4d)Z-d4d*Z.d4d+Z/d,e*_)        d-e+_)        d.e,_)        d/e-_)        d0e._)        dd1l0m1Z2 dS )5    )reducepartialN)
attrgetternot_)import_module
MethodType   )
no_defaultpypy_version_info   )identityapplythread_firstthread_lastmemoizecomposecompose_leftpipe
complementjuxtdocurryflipexceptsc                     | S )z< Identity function. Return x

    >>> identity(3)
    3
     )xs    /lib/python3.11/site-packages/toolz/functoolz.pyr   r      s	     H    c                  X    | st          d          | d         | dd         }} ||i |S )z Applies a function and returns the results

    >>> def double(x): return 2*x
    >>> def inc(x):    return x + 1
    >>> apply(double, 5)
    10

    >>> tuple(map(apply, [double, inc, double], [10, 500, 8000]))
    (20, 501, 16000)
    zfunc argument is requiredr   r
   N)	TypeError)func_and_argskwargsfuncargss       r   r   r      sG      53444q!=#4$D4    r    c                 *    d }t          |||           S )a@   Thread value through a sequence of functions/forms

    >>> def double(x): return 2*x
    >>> def inc(x):    return x + 1
    >>> thread_first(1, inc, double)
    4

    If the function expects more than one input you can specify those inputs
    in a tuple.  The value is used as the first input.

    >>> def add(x, y): return x + y
    >>> def pow(x, y): return x**y
    >>> thread_first(1, (add, 4), (pow, 2))  # pow(add(1, 4), 2)
    25

    So in general
        thread_first(x, f, (g, y, z))
    expands to
        g(f(x), y, z)

    See Also:
        thread_last
    c                     t          |          r ||           S t          |t                    r|d         |dd          }}| f|z   } || S d S Nr   r
   callable
isinstancetuplevalformr%   r&   s       r   evalform_frontz$thread_first.<locals>.evalform_frontF   sf    D>> 	499dE"" 	a$qrr($D6D=D4;	 	r    r   )r/   formsr1   s      r   r   r   .   s%    0   .%---r    c                 *    d }t          |||           S )a   Thread value through a sequence of functions/forms

    >>> def double(x): return 2*x
    >>> def inc(x):    return x + 1
    >>> thread_last(1, inc, double)
    4

    If the function expects more than one input you can specify those inputs
    in a tuple.  The value is used as the last input.

    >>> def add(x, y): return x + y
    >>> def pow(x, y): return x**y
    >>> thread_last(1, (add, 4), (pow, 2))  # pow(2, add(4, 1))
    32

    So in general
        thread_last(x, f, (g, y, z))
    expands to
        g(y, z, f(x))

    >>> def iseven(x):
    ...     return x % 2 == 0
    >>> list(thread_last([1, 2, 3], (map, inc), (filter, iseven)))
    [2, 4]

    See Also:
        thread_first
    c                     t          |          r ||           S t          |t                    r|d         |dd          }}|| fz   } || S d S r)   r*   r.   s       r   evalform_backz"thread_last.<locals>.evalform_backm   sf    D>> 	499dE"" 	a$qrr($D3&=D4;	 	r    r2   )r/   r3   r6   s      r   r   r   P   s%    :   -,,,r    c                 `    | t          t          ||||          S t          | ||||          S )a   Like @property, but returns ``classval`` when used as a class attribute

    >>> class MyClass(object):
    ...     '''The class docstring'''
    ...     @instanceproperty(classval=__doc__)
    ...     def __doc__(self):
    ...         return 'An object docstring'
    ...     @instanceproperty
    ...     def val(self):
    ...         return 42
    ...
    >>> MyClass.__doc__
    'The class docstring'
    >>> MyClass.val is None
    True
    >>> obj = MyClass()
    >>> obj.__doc__
    'An object docstring'
    >>> obj.val
    42
    N)fsetfdeldocclassvalfgetr8   r9   r:   r;   )r   instancepropertyInstancePropertyr<   s        r   r>   r>   w   sQ    ,  *'d3 (* * * 	*Dt%-/ / / /r    c                   ,    e Zd ZdZ	 	 ddZddZd ZdS )r?   z Like @property, but returns ``classval`` when used as a class attribute

    Should not be used directly.  Use ``instanceproperty`` instead.
    Nc                 R    || _         t                              | ||||           d S )N)r=   r8   r9   r:   )r;   property__init__)selfr=   r8   r9   r:   r;   s         r   rC   zInstanceProperty.__init__   s.     $T4SIIIIIr    c                 L    || j         S t                              | ||          S N)r;   rB   __get__)rD   objtypes      r   rG   zInstanceProperty.__get__   s*     	!= c4000r    c                 T    | j         | j        | j        | j        | j        f}t
          |fS rF   )r=   r8   r9   __doc__r;   r?   rD   states     r   
__reduce__zInstanceProperty.__reduce__   s'    DIty$,N&&r    NNNNNrF   )__name__
__module____qualname__rK   rC   rG   rN   r   r    r   r?   r?      sb          =AJ J J J
1 1 1 1
' ' ' ' 'r    r?   c                       e Zd ZdZd Zed             Zed             Zed             Zed             Z	ed             Z
d Zd	 Zd
 Zd Zd Zd ZddZd Zd Zd Zd ZdS )r   ak   Curry a callable function

    Enables partial application of arguments through calling a function with an
    incomplete set of arguments.

    >>> def mul(x, y):
    ...     return x * y
    >>> mul = curry(mul)

    >>> double = mul(2)
    >>> double(10)
    20

    Also supports keyword arguments

    >>> @curry                  # Can use curry as a decorator
    ... def f(x, y, a=10):
    ...     return a * (x + y)

    >>> add = f(a=1)
    >>> add(2, 3)
    5

    See Also:
        toolz.curried - namespace of curried functions
                        https://toolz.readthedocs.io/en/latest/curry.html
    c                    |st          d          |d         |dd          }}t          |          st          d          t          |d          rt          |d          rut          |d          ret          |j        t
                    rKi }|j        r|                    |j                   |                    |           |}|j        |z   }|j        }|rt          |g|R i || _
        nt          |g|R  | _
        t          |dd           | _        t          |d	d
          | _        t          |dd           | _        t          |dd           | _        d | _        d | _        d S )Nz/__init__() takes at least 2 arguments (1 given)r   r
   zInput must be callabler%   r&   keywordsrK   rP   z<curry>rQ   rR   )r"   r+   hasattrr,   r&   r-   rU   updater%   r   _partialgetattrrK   rP   rQ   rR   _sigspec_has_unknown_args)rD   r&   r$   r%   _kwargss        r   rC   zcurry.__init__   s    	OMNNN!Wd122hd~~ 	64555 D&!!	f%%	 j))	 49e,,		 G} .t}---NN6"""F9t#D9D 	1#D:4:::6::DMM#D04000DMtY55j)<<!$d;;#D.$??!%r    c                     | j         j        S rF   )rX   r%   rD   s    r   r%   z
curry.func       }!!r    c                    t          j        | j                  }| j        pd}| j        pi }t          | j        |||          du rt          d          t          |j        	                                          }d}|d t          |                   D ]}|j        |j        k    r n|dz  }d}g }||d          D ]}|j        }	|j        }
|	|j        k    rnH|	|j        k    r|r*n9|j        |v r||j                 }
|j        }	d}n|r|j        }	|
|j        u rt$          }
|                    |                    |
|	                     |                    |          S )	Nr   Fz$curry object has incorrect argumentsr   r
   T)defaultkind)
parameters)inspect	signaturer%   r&   rU   is_partial_argsr"   listrc   valueslenrb   VAR_POSITIONALra   VAR_KEYWORDnameKEYWORD_ONLYemptyr   appendreplace)rD   sigr&   rU   paramsskipparamkwonly	newparamsrb   ra   s              r   __signature__zcurry.__signature__   s   	**yB=&B49dHc::eC 	DBCCCcn++--..JSYYJ' 	 	EzU11 AIDD	DEE] 	H 	HE:DmGu(( )-- ) x' )"5:.) . -Dek) )(GU]]7]FFGGGG{{i{000r    c                     | j         j        S rF   )rX   r&   r^   s    r   r&   z
curry.args  r_   r    c                     | j         j        S rF   )rX   rU   r^   s    r   rU   zcurry.keywords  s    }%%r    c                     | j         S rF   rP   r^   s    r   	func_namezcurry.func_name  s
    }r    c                 *    t          | j                  S rF   )strr%   r^   s    r   __str__zcurry.__str__  s    49~~r    c                 *    t          | j                  S rF   )reprr%   r^   s    r   __repr__zcurry.__repr__  s    DIr    c                     t          | j        | j        | j        r&t	          | j                                                  nd f          S rF   )hashr%   r&   rU   	frozensetitemsr^   s    r   __hash__zcurry.__hash__"  sI    TY	9= Yt}2244555  ! ! 	!r    c                     t          |t                    o/| j        |j        k    o| j        |j        k    o| j        |j        k    S rF   )r,   r   r%   r&   rU   rD   others     r   __eq__zcurry.__eq__'  sJ    5%(( LTY%*-D L	UZ'L,0MU^,K	Mr    c                 .    |                      |           S rF   )r   r   s     r   __ne__zcurry.__ne__+  s    ;;u%%%%r    c                     	  | j         |i |S # t          $ r/}|                     |||          r | j        |i |cY d }~S  d }~ww xY wrF   )rX   r"   _should_currybind)rD   r&   r$   excs       r   __call__zcurry.__call__.  s    	 4=$1&111 	 	 	!!$44 2 ty$1&11111111	s    
A#AAAANc                 B   | j         }| j        |z   }| j        rt          | j        fi |}| j        3t          j        |          x}| _        t          ||          du| _        n| j        }t          ||||          du rdS | j        rdS t          ||||          sdS dS NFT)r%   r&   rU   dictrZ   _sigssignature_or_spechas_varargsr[   rf   is_valid_args)rD   r&   r$   r   r%   sigspecs         r   r   zcurry._should_curry6  s    yy4= 	3$-22622F= 	$&+&=d&C&CCGdm%0w%?%?u%LD""mG4vw775@ 	5# 
	 4tT67;; 	4 5r    c                 4     t          |           | g|R i |S rF   )rI   rD   r&   r$   s      r   r   z
curry.bindP  s(    tDzz$0000000r    c                      | j         |i |S rF   )rX   r   s      r   callz
curry.callS  s    t}d-f---r    c                 *    || S t          | |          S rF   )r   )rD   instanceowners      r   rG   zcurry.__get__V  s     	KT8$$$r    c                    | j         }t          |dd           }t          |dd           }|t          |dd           }d }|r|rg }t          |          }|                    d          D ]]}t	          |t
                    r|                    d           |j         }t          ||d           }| n|                    |           ^t	          |t
                    r)|j         |u r || u }d                    |          }|d|}t          d | j	        
                                D                       }t          |           || j        | j        ||f}	t          |	fS )NrQ   rR   rP   .r%   :c              3   ,   K   | ]\  }}|d v	||fV  dS ))rX   rZ   Nr   ).0kvs      r   	<genexpr>z#curry.__reduce__.<locals>.<genexpr>s  sH       ? ?DAq%==?!Q ? ? ? ? ? ?r    )r%   rY   r   splitr,   r   ro   joinr-   __dict__r   rI   r&   rU   _restore_curry)
rD   r%   modnamequalnameis_decoratedattrsrH   attruserdictrM   s
             r   rN   zcurry.__reduce__[  s   y$d33466 	7tZ66H 	5x 	5E((C s++ # #c5)) #LL((((Cc4.. ET""""#u%% 5#(d*: 5"d{88E??")''884  ? ?DM,?,?,A,A ? ? ? ? ?dT49dmXu$$r    rF   )rP   rQ   rR   rK   rC   r>   r%   rw   r&   rU   r|   r   r   r   r   r   r   r   r   r   rG   rN   r   r    r   r   r      sh        6 &  &  &D " " " #1 #1 #1J " " " & & &       ! ! !
M M M& & &     41 1 1. . .% % %
% % % % %r    r   c                 6   t          |t                    r[|                    dd          \  }}t          |          }|                    d          D ]}	t          ||	          }|r|S |j        } | |g|R i |pi }|j                            |           |S )Nr   r
   r   )	r,   r~   rsplitr   r   rY   r%   r   rW   )
clsr%   r&   r$   r   r   r   r   rH   r   s
             r   r   r   z  s    $  KKQ//G$$NN3'' 	% 	%D#t$$CC 	Jx
#d
,T
,
,
,fl
,
,CL!!!Jr    c                     i 	 t                     du}t          d           }n# t          $ r d}d}Y nw xY w|rd n	|rd nd  fd}	  j        |_        n# t          $ r Y nw xY w j        |_         |_        |S )	aP   Cache a function's result for speedy future evaluation

    Considerations:
        Trades memory for speed.
        Only use on pure functions.

    >>> def add(x, y):  return x + y
    >>> add = memoize(add)

    Or use as a decorator

    >>> @memoize
    ... def add(x, y):
    ...     return x + y

    Use the ``cache`` keyword to provide a dict-like object as an initial cache

    >>> @memoize(cache={(1, 2): 3})
    ... def add(x, y):
    ...     return x + y

    Note that the above works as a decorator because ``memoize`` is curried.

    It is also possible to provide a ``key(args, kwargs)`` function that
    calculates keys used for the cache, which receives an ``args`` tuple and
    ``kwargs`` dict as input, and must return a hashable value.  However,
    the default key function should be sufficient most of the time.

    >>> # Use key function that ignores extraneous keyword arguments
    >>> @memoize(key=lambda args, kwargs: args)
    ... def add(x, y, verbose=False):
    ...     if verbose:
    ...         print('Calculating %s + %s' % (x, y))
    ...     return x + y
    NFr
   Tc                     | d         S )Nr   r   r&   r$   s     r   keyzmemoize.<locals>.key  s    Awr    c                 T    | pd |r!t          |                                          nd fS rF   )r   r   r   s     r   r   zmemoize.<locals>.key  s0    LD17AIfllnn---T r    c                     | S rF   r   r   s     r   r   zmemoize.<locals>.key  s    r    c                       | |          }	 |         S # t           $ r t          d          t          $ r  | i |x|<   }|cY S w xY w)Nz/Arguments to memoized function must be hashable)r"   KeyError)r&   r$   r   resultcacher%   r   s       r   memofzmemoize.<locals>.memof  s    Cf	8O 	O 	O 	OMNNN 	 	 	 $d 5f 5 55E!HvMMM	s    1A
A)has_keywordsis_arityr"   rP   AttributeErrorrK   __wrapped__)r%   r   r   may_have_kwargsis_unaryr   s   ```   r   r   r     s    J  &t,,E9At$$      	    	              LEMELs   !+ <<A% %
A21A2c                       e Zd ZdZdZd Zd Zd Zd Z e	e          d             Ze
d	             Z d
 Zd Zd Zd ZddZe	d             Z e	 ed                    ZdS )Composez? A composition of functions

    See Also:
        compose
    firstfuncsc                 v    t          t          |                    }|d         | _        |dd          | _        d S r)   )r-   reversedr   r   rD   r   s     r   rC   zCompose.__init__  s3    huoo&&1X
122Y


r    c                 J     | j         |i |}| j        D ]} ||          }|S rF   r   )rD   r&   r$   retfs        r   r   zCompose.__call__  s=    dj$)&)) 	 	A!C&&CC
r    c                     | j         | j        fS rF   r   r^   s    r   __getstate__zCompose.__getstate__  s    z4:%%r    c                 $    |\  | _         | _        d S rF   r   rL   s     r   __setstate__zCompose.__setstate__  s    !&
DJJJr    r;   c                 x    fd	 d t          | j        f| j        z              z   S # t          $ r Y dS w xY w)Nc                  f    | sdS d                     | d         j         | dd                    S )z<Generate a docstring for the composition of fs.
            z*args, **kwargsz{f}({g})r   r
   N)r   g)formatrP   )fscomposed_docs    r   r   z%Compose.__doc__.<locals>.composed_doc  sA      )(($$r!u~r!""v9N$OOOr    zlambda *args, **kwargs: zA composition of functions)r   r   r   r   )rD   r   s    @r   rK   zCompose.__doc__  sw    	P 	P 	P 	P 	P	0*h
}tz'ABBCD  	0 	0 	0///	0s   "+ 
99c                     	 d                     d t          | j        f| j        z             D                       S # t          $ r t          |           j        cY S w xY w)N_of_c              3   $   K   | ]}|j         V  d S rF   r{   )r   r   s     r   r   z#Compose.__name__.<locals>.<genexpr>
  s$      JJJJJJJJr    )r   r   r   r   r   rI   rP   r^   s    r   rP   zCompose.__name__  ss    	';;JJXtzmdj.H%I%IJJJ    	' 	' 	'::&&&&	's   9< AAc           	      ~    d                     | t          t          | j        f| j        z                                 S )Nz{.__class__.__name__}{!r})r   r-   r   r   r   r^   s    r   r   zCompose.__repr__  s=    *11%$*$*!<==>>@ @ 	@r    c                 z    t          |t                    r |j        | j        k    o|j        | j        k    S t          S rF   )r,   r   r   r   NotImplementedr   s     r   r   zCompose.__eq__  s8    eW%% 	K;$*,J
1JJr    c                 R    |                      |          }|t          u rt          n| S rF   )r   r   )rD   r   equalitys      r   r   zCompose.__ne__  s)    ;;u%%!)^!;M~~XMr    c                 T    t          | j                  t          | j                  z  S rF   )r   r   r   r^   s    r   r   zCompose.__hash__  s!    DJ$tz"2"222r    Nc                 *    || nt          | |          S rF   r   )rD   rH   objtypes      r   rG   zCompose.__get__#  s    =tt
4(=(==r    c                     t          j        | j                  }t          j        | j        d                   }|                    |j                  S )N)return_annotation)rd   re   r   r   rp   r   )rD   baselasts      r   rw   zCompose.__signature__'  sA     ,, B00||d.D|EEEr    r   rF   )rP   rQ   rR   rK   	__slots__rC   r   r   r   r>   rB   r   r   r   r   rG   rw   r   r   r   r    r   r   r     s1        
 !I  
  & & &' ' ' w'''0 0 ('0& ' ' X'@ @ @  
N N N3 3 3> > > > F F F
 #"::g#6#677KKKr    r   c                  h    | st           S t          |           dk    r| d         S t          |           S )a   Compose functions to operate in series.

    Returns a function that applies other functions in sequence.

    Functions are applied from right to left so that
    ``compose(f, g, h)(x, y)`` is the same as ``f(g(h(x, y)))``.

    If no arguments are provided, the identity function (f(x) = x) is returned.

    >>> inc = lambda i: i + 1
    >>> compose(str, inc)(3)
    '4'

    See Also:
        compose_left
        pipe
    r
   r   )r   ri   r   r   s    r   r   r   0  s8    $  
5zzQ Qxu~~r    c                  .    t          t          |            S )a   Compose functions to operate in series.

    Returns a function that applies other functions in sequence.

    Functions are applied from left to right so that
    ``compose_left(f, g, h)(x, y)`` is the same as ``h(g(f(x, y)))``.

    If no arguments are provided, the identity function (f(x) = x) is returned.

    >>> inc = lambda i: i + 1
    >>> compose_left(inc, str)(3)
    '4'

    See Also:
        compose
        pipe
    )r   r   r   s    r   r   r   J  s    $ HUOO$$r    c                 &    |D ]} ||           } | S )a   Pipe a value through a sequence of functions

    I.e. ``pipe(data, f, g, h)`` is equivalent to ``h(g(f(data)))``

    We think of the value as progressing through a pipe of several
    transformations, much like pipes in UNIX

    ``$ cat data | f | g | h``

    >>> double = lambda i: 2 * i
    >>> pipe(3, double, str)
    '6'

    See Also:
        compose
        compose_left
        thread_first
        thread_last
    r   )datar   r%   s      r   r   r   _  s'    (   tDzzKr    c                 ,    t          t          |           S )a4   Convert a predicate function to its logical complement.

    In other words, return a function that, for inputs that normally
    yield True, yields False, and vice-versa.

    >>> def iseven(n): return n % 2 == 0
    >>> isodd = complement(iseven)
    >>> iseven(2)
    True
    >>> isodd(2)
    False
    )r   r   )r%   s    r   r   r   x  s     4r    c                   0    e Zd ZdZdgZd Zd Zd Zd ZdS )r   a   Creates a function that calls several functions with the same arguments

    Takes several functions and returns a function that applies its arguments
    to each of those functions then returns a tuple of the results.

    Name comes from juxtaposition: the fact of two things being seen or placed
    close together with contrasting effect.

    >>> inc = lambda x: x + 1
    >>> double = lambda x: x * 2
    >>> juxt(inc, double)(10)
    (11, 20)
    >>> juxt([inc, double])(10)
    (11, 20)
    r   c                     t          |          dk    rt          |d                   s|d         }t          |          | _        d S )Nr
   r   )ri   r+   r-   r   r   s     r   rC   zjuxt.__init__  sA    u::? 	8E!H#5#5 	!HE5\\


r    c                 H    t          fd| j        D                       S )Nc              3   (   K   | ]} |i V  d S rF   r   )r   r%   r&   r$   s     r   r   z juxt.__call__.<locals>.<genexpr>  s2      BBtTT4*6**BBBBBBr    )r-   r   r   s    ``r   r   zjuxt.__call__  s,    BBBBBtzBBBBBBr    c                     | j         S rF   r   r^   s    r   r   zjuxt.__getstate__  s
    zr    c                     || _         d S rF   r   rL   s     r   r   zjuxt.__setstate__  s    


r    N)	rP   rQ   rR   rK   r   rC   r   r   r   r   r    r   r   r     sf          	I" " "
C C C      r    r   c                      | |           |S )a   Runs ``func`` on ``x``, returns ``x``

    Because the results of ``func`` are not returned, only the side
    effects of ``func`` are relevant.

    Logging functions can be made by composing ``do`` with a storage function
    like ``list.append`` or ``file.write``

    >>> from toolz import compose
    >>> from toolz.curried import do

    >>> log = []
    >>> inc = lambda x: x + 1
    >>> inc = compose(inc, do(log.append))
    >>> inc(1)
    2
    >>> inc(11)
    12
    >>> log
    [1, 11]
    r   )r%   r   s     r   r   r     s    , 	DGGGHr    c                      | ||          S )a/   Call the function call with the arguments flipped

    This function is curried.

    >>> def div(a, b):
    ...     return a // b
    ...
    >>> flip(div, 2, 6)
    3
    >>> div_by_two = flip(div, 2)
    >>> div_by_two(4)
    2

    This is particularly useful for built in functions and functions defined
    in C extensions that accept positional only arguments. For example:
    isinstance, issubclass.

    >>> data = [1, 'a', 'b', 2, 1.5, object(), 3]
    >>> only_ints = list(filter(flip(isinstance, int), data))
    >>> only_ints
    [1, 2, 3]
    r   )r%   abs      r   r   r     s    0 41::r    c                     dS )z Returns None.
    Nr   )r   s    r   return_noner     s	     4r    c                   b    e Zd ZdZefdZd Z ee          d             Zed             Z dS )r   aw  A wrapper around a function to catch exceptions and
    dispatch to a handler.

    This is like a functional try/except block, in the same way that
    ifexprs are functional if/else blocks.

    Examples
    --------
    >>> excepting = excepts(
    ...     ValueError,
    ...     lambda a: [1, 2].index(a),
    ...     lambda _: -1,
    ... )
    >>> excepting(1)
    0
    >>> excepting(3)
    -1

    Multiple exceptions and default except clause.
    >>> excepting = excepts((IndexError, KeyError), lambda a: a[0])
    >>> excepting([])
    >>> excepting([1])
    1
    >>> excepting({})
    >>> excepting({0: 1})
    1
    c                 0    || _         || _        || _        d S rF   )r   r%   handler)rD   r   r%   r  s       r   rC   zexcepts.__init__   s    	r    c                 v    	  | j         |i |S # | j        $ r}|                     |          cY d }~S d }~ww xY wrF   )r%   r   r  )rD   r&   r$   es       r   r   zexcepts.__call__  s^    	#49d-f---x 	# 	# 	#<<??""""""	#s    
8388r   c                 F   ddl m} | j        }	 t          |t                    r4dd                    t          t          d          |                    z  }n|j        } |d          	                    | |          S # t          $ r t          |           j        cY S w xY w)Nr   )dedentz(%s)z, rP   al                  A wrapper around {inst.func.__name__!r} that will except:
                {exc}
                and handle any exceptions with {inst.handler.__name__!r}.

                Docs for {inst.func.__name__!r}:
                {inst.func.__doc__}

                Docs for {inst.handler.__name__!r}:
                {inst.handler.__doc__}
                )instr   )textwrapr  r   r,   r-   r   mapr   rP   r   r   rI   rK   )rD   r  r   exc_names       r   rK   zexcepts.__doc__  s    ######h	&#u%% (!DII
:..44% %  <6
  f      	& 	& 	&::%%%%	&s   A/A? ?B B c                     | j         }	 t          |t                    r1d                    t	          t          d          |                    }n|j        }| j        j        d|S # t          $ r Y dS w xY w)N_or_rP   _excepting_	excepting)	r   r,   r-   r   r
  r   rP   r%   r   )rD   r   r  s      r   rP   zexcepts.__name__+  s    h	#u%% (!;;s:j+A+A3'G'GHH<(,	(:(:(:HHEE 	 	 	;;	s   AA' '
A54A5N)	rP   rQ   rR   rK   r   rC   r   r>   rB   r   r    r   r   r     s         6 +6    
# # # w'''& & ('&> 	 	 X	 	 	r    r   c                 b   | 6	 t          j        |          } n # t          t          f$ r}|} Y d }~nd }~ww xY wt	          | t                    rd  || fS t	          | t           j                  s>|t          j        v r.t          |d          rt          |j	        d          r	 || }d |fS dS | d fS )Nrw   rG   )NF)
rd   re   
ValueErrorr"   r,   	Signaturer   
signaturesrV   rw   )r   r%   builtin_funcbuiltin_argsr  r/   s         r   _check_sigspecr  8  s     	'--GGI& 	 	 	GGGGGG	':&& \\<000!233 
E$$	 o..	 D.	::		 ,-C9{D=s    616c                 N    |t           j        v r	 || }d |fS t          | ||g|R  S rF   )r   r  _check_sigspec_orig)r   r%   r  r  r/   s        r   r  r  Q  sB    5## 	,-C9"7D,NNNNNr    z Private function to aid in introspection compatibly across Python versions.

If a callable doesn't have a signature (Python 3) or an argspec (Python 2),
the signature registry in toolz._signatures is used.
c                     t          || t          j        |           \  }}||S t          d |j                                        D                       S )Nc              3   `   K   | ])}|j         |j        u |j        |j        |j        fv %d V  *dS )r
   N)ra   rn   rb   POSITIONAL_OR_KEYWORDPOSITIONAL_ONLYr   ps     r   r   z$num_required_args.<locals>.<genexpr>f  sg       K KQ)qw&K6a5q7HIIKq K K K K K Kr    )r  r   _num_required_argssumrc   rh   r%   r   rvs      r   num_required_argsr#  a  sr     $0H!%' 'KGR 	 K K',3355 K K K K K Kr    c                     t          || t          j        |           \  }}||S t          d |j                                        D                       S )Nc              3   6   K   | ]}|j         |j        k    V  d S rF   )rb   rj   r  s     r   r   zhas_varargs.<locals>.<genexpr>o  s@       5 5 v)) 5 5 5 5 5 5r    )r  r   _has_varargsanyrc   rh   r!  s      r   r   r   k  sf     $0BDIIKGR 	 5 5*11335 5 5 5 5 5r    c                     t          || t          j        |           \  }}||S t          d |j                                        D                       S )Nc              3   \   K   | ]'}|j         |j        up|j        |j        |j        fv V  (d S rF   )ra   rn   rb   rm   rk   r  s     r   r   zhas_keywords.<locals>.<genexpr>w  sW       5 5 y' <&Q^Q];;5 5 5 5 5 5r    )r  r   _has_keywordsr'  rc   rh   r!  s      r   r   r   s  sf     $0CTJJKGR 	 5 5*11335 5 5 5 5 5r    c                     t          || t          j        | ||          \  }}||S 	  |j        |i | n# t          $ r Y dS w xY wdS r   )r  r   _is_valid_argsr   r"   r%   r&   r$   r   r"  s        r   r   r   |  sx     $0D!%tV5 5KGR 	d%f%%%%   uu4   5 
AAc                     t          || t          j        | ||          \  }}||S 	  |j        |i | n# t          $ r Y dS w xY wdS r   )r  r   _is_partial_argsbind_partialr"   r-  s        r   rf   rf     sy     $0F!%tV5 5KGR 	d-f----   uu4r.  c                     t          ||t          j        | |          \  }}||S t          ||          }|
|| k    }|sdS t	          ||          }|rdS t          ||          }|rdS |||dS dS )aM   Does a function have only n positional arguments?

    This function relies on introspection and does not call the function.
    Returns None if validity can't be determined.

    >>> def f(x):
    ...     return x
    >>> is_arity(1, f)
    True
    >>> def g(x, y=1):
    ...     return x + y
    >>> is_arity(1, g)
    False
    NFT)r  r   	_is_arityr#  r   r   )nr%   r   r"  numvarargsrU   s          r   r   r     s     !$DIIKGR 	
D'
*
*C
 Qh 	5$((G uD'**H u
 g  t4r    aY   Number of required positional arguments

    This function relies on introspection and does not call the function.
    Returns None if validity can't be determined.

    >>> def f(x, y, z=3):
    ...     return x + y + z
    >>> num_required_args(f)
    2
    >>> def g(*args, **kwargs):
    ...     pass
    >>> num_required_args(g)
    0
    aW   Does a function have variadic positional arguments?

    This function relies on introspection and does not call the function.
    Returns None if validity can't be determined.

    >>> def f(*args):
    ...    return args
    >>> has_varargs(f)
    True
    >>> def g(**kwargs):
    ...    return kwargs
    >>> has_varargs(g)
    False
    z Does a function have keyword arguments?

    This function relies on introspection and does not call the function.
    Returns None if validity can't be determined.

    >>> def f(x, y=0):
    ...     return x + y

    >>> has_keywords(f)
    True
    a   Is ``func(*args, **kwargs)`` a valid function call?

    This function relies on introspection and does not call the function.
    Returns None if validity can't be determined.

    >>> def add(x, y):
    ...     return x + y

    >>> is_valid_args(add, (1,), {})
    False
    >>> is_valid_args(add, (1, 2), {})
    True
    >>> is_valid_args(map, (), {})
    False

    **Implementation notes**
    Python 2 relies on ``inspect.getargspec``, which only works for
    user-defined functions.  Python 3 uses ``inspect.signature``, which
    works for many more types of callables.

    Many builtins in the standard library are also supported.
    aj   Can partial(func, *args, **kwargs)(*args2, **kwargs2) be a valid call?

    Returns True *only* if the call is valid or if it is possible for the
    call to become valid by adding more positional or keyword arguments.

    This function relies on introspection and does not call the function.
    Returns None if validity can't be determined.

    >>> def add(x, y):
    ...     return x + y

    >>> is_partial_args(add, (1,), {})
    True
    >>> is_partial_args(add, (1, 2), {})
    True
    >>> is_partial_args(add, (1, 2, 3), {})
    False
    >>> is_partial_args(map, (), {})
    True

    **Implementation notes**
    Python 2 relies on ``inspect.getargspec``, which only works for
    user-defined functions.  Python 3 uses ``inspect.signature``, which
    works for many more types of callables.

    Many builtins in the standard library are also supported.
    )_signaturesrO   )NNrF   )3	functoolsr   r   rd   sysoperatorr   r   	importlibr   typesr	   utilsr   rV   version_infoPYPY__all__r   r   r   r   r>   rB   r?   objectr   r   r   r   r   r   r   r   r   r   r   r   r   r  r  rK   r#  r   r   r   rf   r    r7  r   r   r    r   <module>rC     s   % % % % % % % %  



 % % % % % % % % # # # # # #            ws'((DS-=a-@1-D' ws'((  ! ! !". . .D$- $- $-N/ / / /:' ' ' ' 'x ' ' '(O% O% O% O% O%F O% O% O%d   M M M M`T8 T8 T8 T8 T8f T8 T8 T8n  4% % %*  2       6   B  4   4  Q Q Q Q Qf Q Q Qh  ,  O(O O O K K K K5 5 5 55 5 5 5	 	 	 		 	 	 	   D       0 : # " " " " " " "r    