U
    Ha0                     @   s   d Z ddlZddlZddlZddlmZmZ G dd deZG dd deZ	d	d
 Z
eedrhdd Zndd ZeedoejjdkZdd ZG dd deZG dd deZG dd deZG dd deZdS )zA
Internal hook annotation, representation and calling machinery.
    N   )_legacymulticall
_multicallc                   @   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   0/tmp/pip-unpacked-wheel-xuf3ljf8/pluggy/hooks.py__init__   s    zHookspecMarker.__init__NFc                    s*    fdd}|dk	r"||S |S dS )al   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   __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 r   r   r	   r   r   r   r   B   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).

        c              	      s"   t | jd t d | S )N_impl)hookwrapperoptionalhooktryfirsttrylast)r   r   r   r   r"   r#   r
   r$   r%   r   r   setattr_hookimpl_optse   s    
z6HookimplMarker.__call__.<locals>.setattr_hookimpl_optsNr   )r
   r   r"   r#   r$   r%   r'   r   r&   r   r   E   s     zHookimplMarker.__call__)NFFFFr   r   r   r   r   r    :   s        r    c                 C   s4   |  dd |  dd |  dd |  dd d S )Nr$   Fr%   r"   r#   )
setdefault)optsr   r   r   normalize_hookimpl_optsx   s    r*   getfullargspecc                 C   s
   t | S r   )inspectr+   r   r   r   r   _getargspec   s    r-   c                 C   s
   t | S r   )r,   
getargspecr   r   r   r   r-      s    pypy_version_info   c                 C   sr  t | di }z
|d W S  tk
r*   Y nX t| rZz
| j} W q tk
rV   Y dS X n2t| szt | d| } W n tk
r   Y dS X zt| }W n t	k
r   Y dS X t
|j|j }}| rt| }|d| t
||d  }}nd}ts dnd}|rBt| s6d	t | d
dkrB|d |krB|dd }z||f|d< W n t	k
rh   Y nX ||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.
    __dict__Z	_varnames)r   r   r   Nr   r
   )r
   obj.r   r   r   )getattrKeyErrorr,   isclassr   AttributeError	isroutine	Exceptionr-   	TypeErrortupleargsdefaultslen_PYPY3ismethod)r   cachespecr=   r>   indexkwargsZimplicit_namesr   r   r   varnames   sJ    





 
rF   c                   @   s   e Zd ZdZdS )
_HookRelayzh hook 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   rG      s   rG   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   sT   || _ g | _g | _|| _d | _d | _t| _d | _|d k	rP|d k	sDt	| 
|| d S r   )name	_wrappers_nonwrappers	_hookexecargnames
kwargnamesr   	multicallrC   AssertionErrorset_specification)r
   rI   Zhook_executespecmodule_or_class	spec_optsr   r   r   r      s    z_HookCaller.__init__c                 C   s
   | j d k	S r   )rC   r2   r   r   r   has_spec   s    z_HookCaller.has_specc                 C   s0   |   rtt|| j|| _|dr,g | _d S )Nr   )rT   rP   HookSpecrI   rC   get_call_history)r
   rR   rS   r   r   r   rQ      s    
z_HookCaller.set_specificationc                 C   s
   t | dS )NrW   )hasattrr2   r   r   r   is_historic   s    z_HookCaller.is_historicc                    s:    fdd}|| j d kr6|| jd kr6td f d S )Nc                    s,   t | D ]\}}|j kr| |=  dS qd S )NT)	enumerateplugin)wrappersimethodr[   r   r   remove   s    
z*_HookCaller._remove_plugin.<locals>.removezplugin %r not found)rJ   rK   r   )r
   r[   r`   r   r_   r   _remove_plugin   s    z_HookCaller._remove_pluginc                 C   s   | j | j S r   )rK   rJ   r2   r   r   r   get_hookimpls   s    z_HookCaller.get_hookimplsc                 C   s   |j r| j}n| j}|jr(|d| nJ|jr:|| n8t|d }|dkrb|| jrb|d8 }qF||d | d|jkrt	
dt t| _dS )z5Add an implementation to the callback chain.
        r   r   __multicall__zVSupport for __multicall__ is now deprecated and will beremoved in an upcoming release.N)r"   rJ   rK   r%   insertr$   appendr?   rM   warningswarnDeprecationWarningr   rO   )r
   hookimplmethodsr]   r   r   r   _add_hookimpl   s"    

z_HookCaller._add_hookimplc                 C   s   d| j f S )Nz<_HookCaller %r>)rI   r2   r   r   r   __repr__  s    z_HookCaller.__repr__c                 O   sv   |rt d|  rt| jrd| jjrdt| jjtdg t|  }|rdtjd	t
|dd | | |  |S )Nz,hook calling supports only keyword argumentsrc   zTArgument(s) {} which are declared in the hookspec can not be found in this hook call   )
stacklevel)r;   rY   rP   rC   rM   setkeysrf   rg   formatr<   rL   rb   )r
   r=   rE   Z	notincallr   r   r   r     s     z_HookCaller.__call__c                 C   sd   |dk	rt dt |}| j|p$i |f | | |  |}|dkrJdS |pPg D ]}|| qRd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.

        .. note::
            The ``proc`` argument is now deprecated.
        NzXSupport for `proc` argument is now deprecated and will beremoved in an upcoming release.)rf   rg   rh   rW   re   rL   rb   )r
   result_callbackrE   procresxr   r   r   call_historic   s    
z_HookCaller.call_historicc              	   C   sf   t | jt | jf}|D ]*}tdddd}tdd||}| | qz| f |W 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>)listrK   rJ   r   HookImplrk   )r
   rj   rE   oldr^   r)   ri   r   r   r   
call_extra;  s    z_HookCaller.call_extrac                 C   sD   |   r@| jD ]0\}}| | |g|}|r|dk	r||d  qdS )zJApply call history to a new hookimpl if it is marked as historic.
        Nr   )rY   rW   rL   )r
   r^   rE   rr   rt   r   r   r   _maybe_apply_historyH  s
    z _HookCaller._maybe_apply_history)NN)NNN)r   r   r   r   rT   rQ   rY   ra   rb   rk   rl   r   rv   rz   r{   r   r   r   r   rH      s   

rH   c                   @   s   e Zd Zdd Zdd ZdS )rx   c                 C   s:   || _ t| j \| _| _|| _|| _|| _| j| d S r   )	r   rF   rM   rN   r[   r)   plugin_namer1   update)r
   r[   r|   r   Zhook_impl_optsr   r   r   r   S  s    zHookImpl.__init__c                 C   s   d| j | jf S )Nz$<HookImpl plugin_name=%r, plugin=%r>)r|   r[   r2   r   r   r   rl   [  s    zHookImpl.__repr__N)r   r   r   r   rl   r   r   r   r   rx   R  s   rx   c                   @   s   e Zd Zdd ZdS )rU   c                 C   sT   || _ t|| | _}|| _t|\| _| _|| _dgt| j | _|	d| _
d S )Nrc   r   )	namespacer5   r   rI   rF   rM   rN   r)   rw   rV   r   )r
   r~   rI   r)   r   r   r   r   r   `  s    zHookSpec.__init__N)r   r   r   r   r   r   r   r   rU   _  s   rU   )r   r,   sysrf   callersr   r   objectr   r    r*   rX   r-   version_infomajorr@   rF   rG   rH   rx   rU   r   r   r   r   <module>   s"   0>

4 
