o
    rZhS                      @   s   d Z dZg dZddlZejdd Zdd ejD e_ddlZee_dd Zd	d
 ZdddZ	dd Z
dd Zdd Zdd Zdd Zedd ZdS )a  
Decorator module by Michele Simionato <michelesimionato@libero.it>
Copyright Michele Simionato, distributed under the terms of the BSD License (see below).
http://www.phyast.pitt.edu/~micheles/python/documentation.html

Included in NLTK for its support of a nice memoization decorator.
zrestructuredtext en)	decoratornew_wrappergetinfo    Nc                 C   s    g | ]}|rd t |vr|qS )Znltk)str).0p r   >/var/www/auris/lib/python3.10/site-packages/nltk/decorators.py
<listcomp>   s     r
   c                 C   sh   t | dd d}t|D ]\}}|ddkr(|d|d  ||< q| ||< qd|S )z
    For retrocompatibility reasons, we don't use a standard Signature.
    Instead, we use the string generated by this method.
    Basically, from a Signature we create a string and remove the default values.
       ,=r   z, )r   split	enumeratecountindexstripjoin)	signatureZlistsignaturecounterparamr   r   r	   __legacysignature   s   
r   c           
      C   s   t | st | sJ t | }|dd \}}}t|}|r%|| |r,|| t | }t|}t| drA| j	}| j
}	n| j}| j}	t| j|||| j| j| j| j|	|d
S )a  
    Returns an info dictionary containing:
    - name (the name of the function : str)
    - argnames (the names of the arguments : list)
    - defaults (the values of the default arguments : tuple)
    - signature (the signature : str)
    - fullsignature (the full signature : Signature)
    - doc (the docstring : str)
    - module (the module name : str)
    - dict (the function __dict__ : str)

    >>> def f(self, x=1, y=2, *args, **kw): pass

    >>> info = getinfo(f)

    >>> info["name"]
    'f'
    >>> info["argnames"]
    ['self', 'x', 'y', 'args', 'kw']

    >>> info["defaults"]
    (1, 2)

    >>> info["signature"]
    'self, x, y, *args, **kw'

    >>> info["fullsignature"]
    <Signature (self, x=1, y=2, *args, **kw)>
    N   __closure__)
nameargnamesr   fullsignaturedefaultsdocmoduledictglobalsclosure)inspectismethod
isfunctiongetfullargspeclistappendr   r   hasattrr   __globals__Zfunc_closureZfunc_globalsr!   __name____defaults____doc__
__module____dict__)
funcZargspecZregargsvarargsZ	varkwargsr   r   r   Z_closureZ_globalsr   r   r	   r   ,   s6   




r   c                 C   sN   |pt |}|d | _|d | _|d | _| j|d  |d | _|| _| S )z akin to functools.update_wrapperr   r   r    r!   r   )r   r,   r.   r/   r0   updater-   Zundecorated)wrappermodelinfodictr   r   r	   update_wrapperl   s   



r7   c                 C   sP   t |tr|}nt|}d|d vsJ dd| }t|t| d}t|||S )aA  
    An improvement over functools.update_wrapper. The wrapper is a generic
    callable object. It works by generating a copy of the wrapper with the
    right signature and by updating the copy, not the original.
    Moreovoer, 'model' can be a dictionary with keys 'name', 'doc', 'module',
    'dict', 'defaults'.
    	_wrapper_r   z("_wrapper_" is a reserved argument name!z.lambda %(signature)s: _wrapper_(%(signature)s))r8   )
isinstancer!   r   evalr7   )r4   r5   r6   srcZfuncopyr   r   r	   r   x   s   
r   c                    s   t  fdd S )Nc                     s   j  g| R i |S N)call)akr1   selfr   r	   <lambda>   s    z__call__.<locals>.<lambda>)r   )rA   r1   r   r@   r	   __call__   s   rC   c                 C   s6   t t| }d|v rtdd|vrtdt| _| S )z
    Take a class with a ``.caller`` method and return a callable decorator
    object. It works by adding a suitable __call__ method to the class;
    it raises a TypeError if the class already has a nontrivial __call__
    method.
    rC   z=You cannot decorate a class with a nontrivial __call__ methodr=   z2You cannot decorate a class without a .call method)setdir	TypeErrorrC   )clsattrsr   r   r	   decorator_factory   s   rI   c                    s(   t  r	t S  fdd}t| S )a  
    General purpose decorator factory: takes a caller function as
    input and returns a decorator with the same attributes.
    A caller function is any function like this::

     def caller(func, *args, **kw):
         # do something
         return func(*args, **kw)

    Here is an example of usage:

    >>> @decorator
    ... def chatty(f, *args, **kw):
    ...     print("Calling %r" % f.__name__)
    ...     return f(*args, **kw)

    >>> chatty.__name__
    'chatty'

    >>> @chatty
    ... def f(): pass
    ...
    >>> f()
    Calling 'f'

    decorator can also take in input a class with a .caller method; in this
    case it converts the class into a factory of callable decorator objects.
    See the documentation for an example.
    c                    sN   t | }|d }d|v sd|v rJ dd| }t|t|  d}t|| |S )Nr   _call__func_z2You cannot use _call_ or _func_ as argument names!z3lambda %(signature)s: _call_(_func_, %(signature)s))rK   rJ   )r   r:   r!   r7   )r1   r6   r   r;   Zdec_funccallerr   r	   
_decorator   s   zdecorator.<locals>._decorator)r$   isclassrI   r7   )rM   rN   r   rL   r	   r      s   

r   c                 C   s6   zt | |W S  ty   | }t| || | Y S w )z'Similar to .setdefault in dictionaries.)getattrAttributeErrorsetattr)objr   Zdefault_thunkdefaultr   r   r	   getattr_   s   rU   c                 G   s0   t | dt}||v r|| S | | }|||< |S )NZmemoize_dic)rU   r!   )r1   argsZdicresultr   r   r	   memoize   s   rX   r<   )r.   __docformat____all__syspathZOLD_SYS_PATHr$   r   r   r7   r   rC   rI   r   rU   rX   r   r   r   r	   <module>   s$    
@/
