B
    `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   T/home/kop/projects/devel/pgwui/test_venv/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 )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   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
   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   r   r   r	   r   E   s     zHookimplMarker.__call__)NFFFF)r   r   r   r   r
   r   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 )N)inspectr$   )r   r   r   r	   _getargspec   s    r&   c             C   s
   t | S )N)r%   
getargspec)r   r   r   r	   r&      s    pypy_version_info   c             C   sh  t | di }y|d S  tk
r(   Y nX t| rVy
| j} W q tk
rR   dS X n0t| syt | d| } W n tk
r   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}|r8t| s,d	t | d
dkr8|d |kr8|dd }y||f|d< W n t	k
r^   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specr5   r6   indexkwargsZimplicit_namesr   r   r	   varnames   sD    



  r>   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	   r?      s   r?   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 )N)name	_wrappers_nonwrappers	_hookexecargnames
kwargnamesr   	multicallr;   AssertionErrorset_specification)r   rA   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   )rL   rH   HookSpecrA   r;   get_call_history)r   rJ   rK   r   r   r	   rI      s    
z_HookCaller.set_specificationc             C   s
   t | dS )NrO   )hasattr)r   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.   x(t | D ]\}}|j kr
| |= dS q
W d S )NT)	enumerateplugin)wrappersimethod)rS   r   r	   remove   s    
z*_HookCaller._remove_plugin.<locals>.removezplugin %r not found)rB   rC   r   )r   rS   rW   r   )rS   r	   _remove_plugin   s    z_HookCaller._remove_pluginc             C   s   | j | j S )N)rC   rB   )r   r   r   r	   get_hookimpls   s    z_HookCaller.get_hookimplsc             C   s   |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|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   rB   rC   r   insertr   appendr7   rE   warningswarnDeprecationWarningr   rG   )r   hookimplmethodsrU   r   r   r	   _add_hookimpl   s     
z_HookCaller._add_hookimplc             C   s   d| j f S )Nz<_HookCaller %r>)rA   )r   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 argumentsrZ   zTArgument(s) {} which are declared in the hookspec can not be found in this hook call   )
stacklevel)r3   rQ   rH   r;   rE   setkeysr]   r^   formatr4   rD   rY   )r   r5   r=   Z	notincallr   r   r	   r     s    "z_HookCaller.__call__c             C   sh   |dk	rt dt |}| j|p$i |f | | |  |}|dkrJdS x|pRg D ]}|| qTW 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.

        .. note::
            The ``proc`` argument is now deprecated.
        NzXSupport for `proc` argument is now deprecated and will beremoved in an upcoming release.)r]   r^   r_   rO   r\   rD   rY   )r   result_callbackr=   proc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>)listrC   rB   r   HookImplrb   )r   ra   r=   oldrV   r"   r`   r   r   r	   
call_extra;  s    

z_HookCaller.call_extrac             C   sH   |   rDx:| jD ]0\}}| | |g|}|r|dk	r||d  qW dS )zJApply call history to a new hookimpl if it is marked as historic.
        Nr   )rQ   rO   rD   )r   rV   r=   ri   rk   r   r   r	   _maybe_apply_historyH  s
    z _HookCaller._maybe_apply_history)NN)NNN)r   r   r   r
   rL   rI   rQ   rX   rY   rb   rc   r   rm   rq   rr   r   r   r   r	   r@      s   

r@   c               @   s   e Zd Zdd Zdd ZdS )ro   c             C   s:   || _ t| j \| _| _|| _|| _|| _| j| d S )N)	r   r>   rE   rF   rS   r"   plugin_namer*   update)r   rS   rs   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>)rs   rS   )r   r   r   r	   rc   [  s    zHookImpl.__repr__N)r   r   r   r
   rc   r   r   r   r	   ro   R  s   ro   c               @   s   e Zd Zdd ZdS )rM   c             C   sT   || _ t|| | _}|| _t|\| _| _|| _dgt| j | _|	d| _
d S )NrZ   r   )	namespacer-   r   rA   r>   rE   rF   r"   rn   rN   r   )r   ru   rA   r"   r   r   r   r	   r
   `  s    zHookSpec.__init__N)r   r   r   r
   r   r   r   r	   rM   _  s   rM   )r   r%   sysr]   callersr   r   objectr   r   r#   rP   r&   version_infomajorr8   r>   r?   r@   ro   rM   r   r   r   r	   <module>   s"   0>

4 
