o
    iS                      @   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 )nltk)str).0p r	   J/var/www/edux/Edux_v2/venv/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)	signature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__func_closurefunc_globalsr#   __name____defaults____doc__
__module____dict__)
funcargspecregargsvarargs	varkwargsr   r   r   _closure_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   r0   r2   r3   r4   updater1   undecorated)wrappermodelinfodictr	   r	   r
   update_wrapperl   s   



rA   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))rB   )
isinstancer#   r   evalrA   )r>   r?   r@   src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r5   selfr	   r
   <lambda>   s    z__call__.<locals>.<lambda>)r   )rL   r5   r	   rK   r
   __call__   s   rN   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.
    rN   z=You cannot decorate a class with a nontrivial __call__ methodrH   z2You cannot decorate a class without a .call method)setdir	TypeErrorrN   )clsattrsr	   r	   r
   decorator_factory   s   rT   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))rV   rU   )r   rD   r#   rA   )r5   r@   r   rE   dec_funccallerr	   r
   
_decorator   s   zdecorator.<locals>._decorator)r&   isclassrT   rA   )rY   rZ   r	   rX   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   default_thunkdefaultr	   r	   r
   getattr_   s   rb   c                 G   s0   t | dt}||v r|| S | | }|||< |S )Nmemoize_dic)rb   r#   )r5   argsdicresultr	   r	   r
   memoize   s   rg   rG   )r2   __docformat____all__syspathOLD_SYS_PATHr&   r   r   rA   r   rN   rT   r   rb   rg   r	   r	   r	   r
   <module>   s$    
@/
