B
    t\8                 @   s|   d dl Z ddlmZ ddlmZmZmZmZ d dlZdd Z	G dd de
ZG d	d
 d
eZee drpdd Zndd ZdS )    N   )_tracing)HookImpl
_HookRelay_HookCallernormalize_hookimpl_optsc             C   s"   t j| t| |jj|jjd d S )N)linenofilename)warningswarn_explicittype__code__co_firstlinenoco_filename)Zwarningfunction r   -lib/python3.7/site-packages/pluggy/manager.py_warn_for_function   s
    r   c                   s    e Zd ZdZ fddZ  ZS )PluginValidationErrorz plugin failed validation.

    :param object plugin: the plugin which failed validation,
        may be a module or an arbitrary object.
    c                s   || _ tt| | d S )N)pluginsuper	Exception__init__)selfr   message)	__class__r   r   r      s    zPluginValidationError.__init__)__name__
__module____qualname____doc__r   __classcell__r   r   )r   r   r      s   r   c               @   s   e Zd ZdZd3ddZdd Zd4ddZd	d
 Zd5d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 Zdd  Zd!d" Zd#d$ Zd6d%d&Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 ZdS )7PluginManagera   Core Pluginmanager class which manages registration
    of plugin objects and 1:N hook calling.

    You can register new hooks by calling ``add_hookspec(module_or_class)``.
    You can register plugin objects (which contain hooks) by calling
    ``register(plugin)``.  The Pluginmanager is initialized with a
    prefix that is searched for in the names of the dict of registered
    plugin objects.

    For debugging purposes you can call ``enable_tracing()``
    which will subsequently send debug information to the trace helper.
    Nc             C   sh   || _ i | _i | _g | _t d| _t| jj	d| _
|dk	rTtjdtdd || _dd | _dS )	zuIf ``implprefix`` is given implementation functions
        will be recognized if their name matches the implprefix. ZpluginmanagehookNzySupport for the `implprefix` arg is now deprecated and will be removed in an upcoming release. Please use HookimplMarker.   )
stacklevelc             S   s$   | j ||| jr| jjdnddS )NfirstresultF)r%   )Z	multicallspecoptsget)r"   methodskwargsr   r   r   <lambda>;   s   z(PluginManager.__init__.<locals>.<lambda>)project_name_name2plugin_plugin2hookcallers_plugin_distinfor   Z	TagTracerr(   Ztracer   rootr"   r
   warnDeprecationWarning_implprefix_inner_hookexec)r   r,   Z
implprefixr   r   r   r   *   s    zPluginManager.__init__c             C   s   |  |||S )N)r4   )r   r"   r)   r*   r   r   r   	_hookexecA   s    zPluginManager._hookexecc       	      C   s  |p|  |}|| jks"|| jkrL| j|ddkr8dS td||| jf || j|< g  | j|< }xt|D ]}| ||}|dk	rnt| t||}t	||||}t| j
|d}|dkrt|| j}t| j
|| n| r| || || || || qnW |S )z Register a plugin and return its canonical name or None if the name
        is blocked from registering.  Raise a ValueError if the plugin is already
        registered. Nz#Plugin already registered: %s=%s
%s)get_canonical_namer-   r.   r(   
ValueErrordirparse_hookimpl_optsr   getattrr   r"   r   r5   setattrhas_spec_verify_hookZ_maybe_apply_history_add_hookimplappend)	r   r   nameplugin_nameZhookcallersZhookimpl_optsmethodhookimplr"   r   r   r   registerF   s2    



zPluginManager.registerc             C   s   t ||}t|sd S yt || jd d }W n tk
rF   i }Y nX |d k	r`t|ts`d }n,|d kr| jr|| jrt	t
d| i }|S )NZ_implzhThe `implprefix` system is deprecated please decorate this function using an instance of HookimplMarker.)r;   inspectZ	isroutiner,   r   
isinstancedictr3   
startswithr   r2   )r   r   rA   rC   Zresr   r   r   r:   k   s     


z!PluginManager.parse_hookimpl_optsc             C   sn   |dkr"|dk	st d| |}|dkr4| |}| j|rH| j|= x | j|g D ]}|| qXW |S )zn unregister a plugin object and all its contained hook implementations
        from internal data structures. Nz+one of name or plugin needs to be specified)AssertionErrorget_name
get_pluginr-   r(   r.   popZ_remove_plugin)r   r   rA   Z
hookcallerr   r   r   
unregister   s    

zPluginManager.unregisterc             C   s   | j |d d| j|< dS )zJ block registrations of the given name, unregister if already registered. )rA   N)rN   r-   )r   rA   r   r   r   set_blocked   s    zPluginManager.set_blockedc             C   s   || j ko| j | dkS )zA return True if the name blogs registering plugins of that name. N)r-   )r   rA   r   r   r   
is_blocked   s    zPluginManager.is_blockedc             C   s   g }xt |D ]}| ||}|dk	rt| j|d}|dkr\t|| j||}t| j|| n*||| x| D ]}| 	|| qrW |
| qW |std| j|f dS )z add new hook specifications defined in the given module_or_class.
        Functions are recognized if they have been decorated accordingly. Nzdid not find any %r hooks in %r)r9   parse_hookspec_optsr;   r"   r   r5   r<   Zset_specificationget_hookimplsr>   r@   r8   r,   )r   module_or_classnamesrA   Z	spec_optshcZhookfunctionr   r   r   add_hookspecs   s    zPluginManager.add_hookspecsc             C   s   t ||}t || jd d S )N_spec)r;   r,   )r   rS   rA   rC   r   r   r   rQ      s    
z!PluginManager.parse_hookspec_optsc             C   s
   t | jS )z' return the set of registered plugins. )setr.   )r   r   r   r   get_plugins   s    zPluginManager.get_pluginsc             C   s
   || j kS )z2 Return True if the plugin is already registered. )r.   )r   r   r   r   r   is_registered   s    zPluginManager.is_registeredc             C   s   t |ddptt|S )a	   Return canonical name for a plugin object. Note that a plugin
        may be registered under a different name which was specified
        by the caller of register(plugin, name). To obtain the name
        of an registered plugin use ``get_name(plugin)`` instead.r   N)r;   strid)r   r   r   r   r   r7      s    z PluginManager.get_canonical_namec             C   s   | j |S )z- Return a plugin or None for the given name. )r-   r(   )r   rA   r   r   r   rL      s    zPluginManager.get_pluginc             C   s   |  |dk	S )z< Return True if a plugin with the given name is registered. N)rL   )r   rA   r   r   r   
has_plugin   s    zPluginManager.has_pluginc             C   s(   x"| j  D ]\}}||kr|S qW dS )z> Return name for registered plugin or None if not registered. N)r-   items)r   r   rA   valr   r   r   rK      s    zPluginManager.get_namec             C   s~   |  r&|jr&t|jd|j|jf |jjr>t|jj|j	 t
|jt
|jj }|rzt|jd|j|jt|j	|f d S )Nz6Plugin %r
hook %r
historic incompatible to hookwrapperz~Plugin %r for hook %r
hookimpl definition: %s
Argument(s) %s are declared in the hookimpl but can not be found in the hookspec)Zis_historicZhookwrapperr   r   rB   rA   r&   Zwarn_on_implr   r   rX   Zargnames
_formatdef)r   r"   rD   Z	notinspecr   r   r   r>      s     zPluginManager._verify_hookc             C   sd   x^| j jD ]R}|d dkr
t| j |}| s
x,| D ] }|js8t|jd||jf q8W q
W dS )z Verify that all hooks which have not been verified against
        a hook specification are optional, otherwise raise PluginValidationErrorr   _zunknown hook %r in plugin %rN)r"   __dict__r;   r=   rR   Zoptionalhookr   r   )r   rA   r"   rD   r   r   r   check_pending   s    zPluginManager.check_pendingc       
      C   s   ddl m}m}m} d}x|||dD ]}| |js&| |jrDq&y| }W nL |k
rf   w&Y n8 |k
r }	 ztdd|j|	f dW dd}	~	X Y nX | j	||jd | j
||jf |d7 }q&W |S )a+   Load modules from querying the specified setuptools ``group``.

        :param str group: entry point group to load plugins
        :param str name: if given, loads only plugins with the given ``name``.
        :rtype: int
        :return: return the number of loaded plugins by this call.
        r   )iter_entry_pointsDistributionNotFoundVersionConflict)rA   Nz"Plugin %r could not be loaded: %s!)r   r   r   )Zpkg_resourcesrd   re   rf   rL   rA   rP   loadr   rE   r/   r@   Zdist)
r   grouprA   rd   re   rf   countZepr   er   r   r   load_setuptools_entrypoints   s"    $z)PluginManager.load_setuptools_entrypointsc             C   s
   t | jS )zV return list of distinfo/plugin tuples for all setuptools registered
        plugins. )listr/   )r   r   r   r   list_plugin_distinfo  s    z"PluginManager.list_plugin_distinfoc             C   s   t | j S )z# return list of name/plugin pairs. )rl   r-   r^   )r   r   r   r   list_name_plugin$  s    zPluginManager.list_name_pluginc             C   s   | j |S )z0 get all hook callers for the specified plugin. )r.   r(   )r   r   r   r   r   get_hookcallers(  s    zPluginManager.get_hookcallersc             C   s   t | ||jS )aB   add before/after tracing functions for all hooks
        and return an undo function which, when called,
        will remove the added tracers.

        ``before(hook_name, hook_impls, kwargs)`` will be called ahead
        of all hook calls and receive a hookcaller instance, a list
        of HookImpl instances and the keyword arguments for the hook call.

        ``after(outcome, hook_name, hook_impls, kwargs)`` receives the
        same arguments as ``before`` but also a :py:class:`_Result`` object
        which represents the result of the overall hook call.
        )r   Z_TracedHookExecutionZundo)r   beforeafterr   r   r   add_hookcall_monitoring,  s    z%PluginManager.add_hookcall_monitoringc                s,   | j j  fdd} fdd}| ||S )z; enable tracing of hook calls and return an undo function. c                s    j  jd7  _ | | d S )Nr   )r0   indent)	hook_namer)   r*   )	hooktracer   r   rp   ?  s    z,PluginManager.enable_tracing.<locals>.beforec                s0   | j d kr d|d|    j jd8  _d S )NZfinishz-->r   )excinfoZ
get_resultr0   rs   )Zoutcomert   r)   r*   )ru   r   r   rq   C  s    
z+PluginManager.enable_tracing.<locals>.after)r"   Z_tracerr   )r   rp   rq   r   )ru   r   enable_tracing;  s    zPluginManager.enable_tracingc                s   t | j } fdd|D }|r~t|j|j|jj|jj}x<| D ]0}|j	}||krF|
| | j|g | qFW |S |S )z Return a new _HookCaller instance for the named method
        which manages calls to all registered plugins except the
        ones from remove_plugins. c                s   g | ]}t | r|qS r   )hasattr).0Zplug)rA   r   r   
<listcomp>O  s    z4PluginManager.subset_hook_caller.<locals>.<listcomp>)r;   r"   r   rA   r5   r&   	namespacer'   rR   r   r?   r.   
setdefaultr@   )r   rA   Zremove_pluginsZorigZplugins_to_removerU   rD   r   r   )rA   r   subset_hook_callerJ  s    
z PluginManager.subset_hook_caller)N)N)NN)N)r   r   r   r   r   r5   rE   r:   rN   rO   rP   rV   rQ   rY   rZ   r7   rL   r]   rK   r>   rc   rk   rm   rn   ro   rr   rw   r}   r   r   r   r   r!      s2   

%

!r!   	signaturec             C   s   d| j tt| f S )Nz%s%s)r   r[   rF   r~   )funcr   r   r   r`   a  s    r`   c             C   s   d| j tjt|  f S )Nz%s%s)r   rF   ZformatargspecZ
getargspec)r   r   r   r   r`   g  s    )rF    r   Zhooksr   r   r   r   r
   r   r   r   objectr!   rx   r`   r   r   r   r   <module>   s   	  E

