B
    GFFb,                 @   s   d Z ddlZddlZddlZG dd dZG dd dZdd Zeed	Zd
d Z	G dd dZ
G dd dZG dd dZG dd dZdS )zA
Internal hook annotation, representation and calling machinery.
    Nc               @   s"   e Zd ZdZdd ZdddZdS )	HookspecMarkera,  Decorator helper class for marking functions as hook specifications.

    You can instantiate it with a project_name to get a decorator.
    Calling :py:meth:`.PluginManager.add_hookspecs` later will discover all marked functions
    if the :py:class:`.PluginManager` uses the same project_name.
    c             C   s
   || _ d S )N)project_name)selfr    r   ,lib/python3.7/site-packages/pluggy/_hooks.py__init__   s    zHookspecMarker.__init__NFc                s*    fdd}|dk	r"||S |S dS )ak  if passed a function, directly sets attributes on the function
        which will make it discoverable to :py:meth:`.PluginManager.add_hookspecs`.
        If passed no function, returns a decorator which can be applied to a function
        later using the attributes supplied.

        If ``firstresult`` is ``True`` the 1:N hook call (N being the number of registered
        hook implementation functions) will stop at I<=N when the I'th function
        returns a non-``None`` result.

        If ``historic`` is ``True`` calls to a hook will be memorized and replayed
        on later registered plugins.

        c                s0   r rt dt| jd t d | S )Nz'cannot have a historic firstresult hook_spec)firstresulthistoricwarn_on_impl)
ValueErrorsetattrr   dict)func)r	   r
   r   r   r   r   setattr_hookspec_opts%   s    
z6HookspecMarker.__call__.<locals>.setattr_hookspec_optsNr   )r   functionr	   r
   r   r   r   )r	   r
   r   r   r   __call__   s    zHookspecMarker.__call__)NFFN)__name__
__module____qualname____doc__r   r   r   r   r   r   r   	   s   r   c               @   s"   e Zd ZdZdd ZdddZdS )	HookimplMarkera)  Decorator helper class for marking functions as hook implementations.

    You can instantiate with a ``project_name`` to get a decorator.
    Calling :py:meth:`.PluginManager.register` later will discover all marked functions
    if the :py:class:`.PluginManager` uses the same project_name.
    c             C   s
   || _ d S )N)r   )r   r   r   r   r   r   A   s    zHookimplMarker.__init__NFc                s.    fdd}|dkr"|S ||S dS )a~  if passed a function, directly sets attributes on the function
        which will make it discoverable to :py:meth:`.PluginManager.register`.
        If passed no function, returns a decorator which can be applied to a
        function later using the attributes supplied.

        If ``optionalhook`` is ``True`` a missing matching hook specification will not result
        in an error (by default it is an error if no matching spec is found).

        If ``tryfirst`` is ``True`` this hook implementation will run as early as possible
        in the chain of N hook implementations for a specification.

        If ``trylast`` is ``True`` this hook implementation will run as late as possible
        in the chain of N hook implementations.

        If ``hookwrapper`` is ``True`` the hook implementations needs to execute exactly
        one ``yield``.  The code before the ``yield`` is run early before any non-hookwrapper
        function is run.  The code after the ``yield`` is run after all non-hookwrapper
        function have run.  The ``yield`` receives a :py:class:`.callers._Result` object
        representing the exception or result outcome of the inner calls (including other
        hookwrapper calls).

        If ``specname`` is provided, it will be used instead of the function name when
        matching this hook implementation to a hook specification during registration.

        c          
      s$   t | jd t d | S )NZ_impl)hookwrapperoptionalhooktryfirsttrylastspecname)r   r   r   )r   )r   r   r   r   r   r   r   r   setattr_hookimpl_optsh   s    
z6HookimplMarker.__call__.<locals>.setattr_hookimpl_optsNr   )r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   D   s    $zHookimplMarker.__call__)NFFFFN)r   r   r   r   r   r   r   r   r   r   r   9   s        r   c             C   s@   |  dd |  dd |  dd |  dd |  dd  d S )Nr   Fr   r   r   r   )
setdefault)optsr   r   r   normalize_hookimpl_opts|   s
    r    Zpypy_version_infoc             C   s  t | r,y
| j} W q\ tk
r(   dS X n0t | s\yt| d| } W n tk
rZ   dS X yt | }W n tk
r~   dS X t	|j
|j }}|rt| }|d| t	||d  }}nd}tsdnd}|rt | sdt| ddkr|d	 |kr|d
d }||fS )zReturn tuple of positional and keywrord argument names for a function,
    method, class or callable.

    In case of a class, its ``__init__`` method is considered.
    For methods the ``self`` parameter is not included.
    )r   r   r   Nr   )r   )r   obj.r   r      )inspectZisclassr   AttributeErrorZ	isroutinegetattr	ExceptionZgetfullargspec	TypeErrortupleargsdefaultslen_PYPYZismethod)r   specr*   r+   indexkwargsZimplicit_namesr   r   r   varnames   s2    



  r1   c               @   s   e Zd ZdZdS )
_HookRelayzghook holder object for performing 1:N hook calls where N is the number
    of registered plugins.

    N)r   r   r   r   r   r   r   r   r2      s   r2   c               @   sp   e Zd ZdddZdd Zdd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd ZdddZdd Zdd ZdS )_HookCallerNc             C   sH   || _ g | _g | _|| _d | _d | _|d k	rD|d k	s8t| || d S )N)name	_wrappers_nonwrappers	_hookexec_call_historyr.   AssertionErrorset_specification)r   r4   Zhook_executespecmodule_or_class	spec_optsr   r   r   r      s    z_HookCaller.__init__c             C   s
   | j d k	S )N)r.   )r   r   r   r   has_spec   s    z_HookCaller.has_specc             C   s0   |   rtt|| j|| _|dr,g | _d S )Nr
   )r=   r9   HookSpecr4   r.   getr8   )r   r;   r<   r   r   r   r:      s    
z_HookCaller.set_specificationc             C   s
   | j d k	S )N)r8   )r   r   r   r   is_historic   s    z_HookCaller.is_historicc                s<    fdd}|| j d kr8|| jd kr8td dd S )Nc                s.   x(t | D ]\}}|j kr
| |= dS q
W d S )NT)	enumerateplugin)Zwrappersimethod)rB   r   r   remove   s    
z*_HookCaller._remove_plugin.<locals>.removezplugin z
 not found)r5   r6   r   )r   rB   rE   r   )rB   r   _remove_plugin   s    z_HookCaller._remove_pluginc             C   s   | j | j S )N)r6   r5   )r   r   r   r   get_hookimpls   s    z_HookCaller.get_hookimplsc             C   sz   |j r| j}n| j}|jr(|d| nN|jr:|| n<t|d }x|dkrd|| jrd|d8 }qHW ||d | dS )z,Add an implementation to the callback chain.r   r#   N)r   r5   r6   r   insertr   appendr,   )r   hookimplmethodsrC   r   r   r   _add_hookimpl   s    z_HookCaller._add_hookimplc             C   s   d| j dS )Nz<_HookCaller >)r4   )r   r   r   r   __repr__   s    z_HookCaller.__repr__c             O   s   |rt d|  rt| jrvxF| jjD ]:}||kr(tt| jj|  }tj	d
|dd P q(W | jjd}nd}| | j|  ||S )Nz,hook calling supports only keyword argumentszTArgument(s) {} which are declared in the hookspec can not be found in this hook call   )
stacklevelr	   F)r(   r@   r9   r.   argnamesr)   setkeyswarningswarnformatr   r?   r7   r4   rG   )r   r*   r0   argnameZ	notincallr	   r   r   r   r      s    z_HookCaller.__call__c             C   sT   | j |pi |f | | j|  |d}|dkr6dS x|p>g D ]}|| q@W dS )a  Call the hook with given ``kwargs`` for all registered plugins and
        for all plugins which will be registered afterwards.

        If ``result_callback`` is not ``None`` it will be called for for each
        non-``None`` result obtained from a hook implementation.
        FN)r8   rI   r7   r4   rG   )r   result_callbackr0   resxr   r   r   call_historic  s    z_HookCaller.call_historicc          	   C   sf   t | jt | jf}x2|D ]*}tdddd}tdd||}| | qW z
| f |S |\| _| _X dS )zCall the hook with some additional temporarily participating
        methods using the specified ``kwargs`` as call parameters.F)r   r   r   Nz<temp>)listr6   r5   r   HookImplrL   )r   rK   r0   oldrD   r   rJ   r   r   r   
call_extra  s    

z_HookCaller.call_extrac             C   sL   |   rHx>| jD ]4\}}| | j|g|d}|r|dk	r||d  qW dS )zAApply call history to a new hookimpl if it is marked as historic.FNr   )r@   r8   r7   r4   )r   rD   r0   rX   rY   r   r   r   _maybe_apply_history(  s
    z _HookCaller._maybe_apply_history)NN)NN)r   r   r   r   r=   r:   r@   rF   rG   rL   rN   r   r[   r_   r`   r   r   r   r   r3      s   

r3   c               @   s   e Zd Zdd Zdd ZdS )r]   c             C   s:   || _ t| j \| _| _|| _|| _|| _| j| d S )N)	r   r1   rQ   
kwargnamesrB   r   plugin_name__dict__update)r   rB   rb   r   Zhook_impl_optsr   r   r   r   2  s    zHookImpl.__init__c             C   s   d| j d| jdS )Nz<HookImpl plugin_name=z	, plugin=rM   )rb   rB   )r   r   r   r   rN   :  s    zHookImpl.__repr__N)r   r   r   r   rN   r   r   r   r   r]   1  s   r]   c               @   s   e Zd Zdd ZdS )r>   c             C   sB   || _ t|| | _}|| _t|\| _| _|| _|d| _	d S )Nr   )
	namespacer&   r   r4   r1   rQ   ra   r   r?   r   )r   re   r4   r   r   r   r   r   r   ?  s    zHookSpec.__init__N)r   r   r   r   r   r   r   r   r>   >  s   r>   )r   r$   sysrT   r   r   r    hasattrr-   r1   r2   r3   r]   r>   r   r   r   r   <module>   s   0C
*y