B
    `<                 @   s   d dl Z d dlZddlmZ ddlmZ ddlmZmZm	Z	m
Z
 d dlZejdkr`d dlmZ nd dlZdd	 ZG d
d deZG dd deZG dd deZee drdd Zndd ZdS )    N   )_tracing)_Result)HookImpl
_HookRelay_HookCallernormalize_hookimpl_opts)      )metadatac             C   s"   t j| t| |jj|jjd d S )N)linenofilename)warningswarn_explicittype__code__co_firstlinenoco_filename)warningfunction r   V/home/kop/projects/devel/pgwui/test_venv/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               @   s6   e Zd ZdZdd Zedd ZdddZd	d
 ZdS )
DistFacadez$Emulate a pkg_resources Distributionc             C   s
   || _ d S )N)_dist)r   distr   r   r   r   &   s    zDistFacade.__init__c             C   s
   | j d S )Nname)r   )r   r   r   r   project_name)   s    zDistFacade.project_nameNc             C   s   t | j||S )N)getattrr'   )r   attrdefaultr   r   r   __getattr__-   s    zDistFacade.__getattr__c             C   s   t t| jddg S )Nr'   r*   )sorteddirr'   )r   r   r   r   __dir__0   s    zDistFacade.__dir__)N)	r!   r"   r#   r$   r   propertyr*   r.   r1   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 :py:class:`.PluginManager` class which manages registration
    of plugin objects and 1:N hook calling.

    You can register new hooks by calling :py:meth:`add_hookspecs(module_or_class)
    <.PluginManager.add_hookspecs>`.
    You can register plugin objects (which contain hooks) by calling
    :py:meth:`register(plugin) <.PluginManager.register>`.  The :py:class:`.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 :py:meth:`.PluginManager.enable_tracing`
    which will subsequently send debug information to the trace helper.
    Nc             C   s\   || _ i | _i | _g | _t d| _t | _	|dk	rHt
jdtdd || _dd | _dS )zyIf ``implprefix`` is given implementation functions
        will be recognized if their name matches the ``implprefix``. ZpluginmanageNzySupport 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)r6   )	multicallspecoptsget)hookmethodskwargsr   r   r   <lambda>T   s   z(PluginManager.__init__.<locals>.<lambda>)r*   _name2plugin_plugin2hookcallers_plugin_distinfor   Z	TagTracerr:   tracer   r;   r   warnDeprecationWarning_implprefix_inner_hookexec)r   r*   Z
implprefixr   r   r   r   C   s    zPluginManager.__init__c             C   s   |  |||S )N)rF   )r   r;   r<   r=   r   r   r   	_hookexecZ   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 :py:class:`ValueError` if the plugin
        is already registered. Nz#Plugin already registered: %s=%s
%s)get_canonical_namer?   r@   r:   
ValueErrorr0   parse_hookimpl_optsr   r+   r   r;   r   rG   setattrhas_spec_verify_hookZ_maybe_apply_history_add_hookimplappend)	r   r   r)   plugin_nameZhookcallersZhookimpl_optsmethodhookimplr;   r   r   r   register_   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 )N_implzhThe `implprefix` system is deprecated please decorate this function using an instance of HookimplMarker.)r+   inspect	isroutiner*   r   
isinstancedictrE   
startswithr   rD   )r   r   r)   rR   resr   r   r   rK      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   r)   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. )r)   N)r`   r?   )r   r)   r   r   r   set_blocked   s    zPluginManager.set_blockedc             C   s   || j ko| j | dkS )z6 return ``True`` if the given plugin name is blocked. N)r?   )r   r)   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)r0   parse_hookspec_optsr+   r;   r   rG   rL   Zset_specificationget_hookimplsrN   rP   rJ   r*   )r   module_or_classnamesr)   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   re   r)   rR   r   r   r   rc      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 )z6 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 )aW   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 :py:meth:`register(plugin, name) <.PluginManager.register>`.
        To obtain the name of an registered plugin use :py:meth:`get_name(plugin)
        <.PluginManager.get_name>` instead.r!   N)r+   strid)r   r   r   r   r   rI      s    z PluginManager.get_canonical_namec             C   s   | j |S )z1 Return a plugin or ``None`` for the given name. )r?   r:   )r   r)   r   r   r   r^      s    zPluginManager.get_pluginc             C   s   |  |dk	S )z@ Return ``True`` if a plugin with the given name is registered. N)r^   )r   r)   r   r   r   
has_plugin   s    zPluginManager.has_pluginc             C   s(   x"| j  D ]\}}||kr|S qW dS )zB Return name for registered plugin or ``None`` if not registered. N)r?   items)r   r   r)   valr   r   r   r]      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   rQ   r)   r8   Zwarn_on_implr   r   rj   argnames
_formatdef)r   r;   rS   Z	notinspecr   r   r   rN      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 :py:class:`.PluginValidationError`.r   _zunknown hook %r in plugin %rN)r;   __dict__r+   rM   rd   Zoptionalhookr   r   )r   r)   r;   rS   r   r   r   check_pending	  s    zPluginManager.check_pendingc             C   s   d}xt  D ]~}xx|jD ]n}|j|ks|dk	r:|j|ks| |js| |jrTq| }| j||jd | j	
|t|f |d7 }qW 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   N)r)   r   )importlib_metadatadistributionsZentry_pointsgroupr)   r^   rb   loadrT   rA   rP   r&   )r   ry   r)   countr(   epr   r   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. )listrA   )r   r   r   r   list_plugin_distinfo1  s    z"PluginManager.list_plugin_distinfoc             C   s   t | j S )z# return list of name/plugin pairs. )r~   r?   rp   )r   r   r   r   list_name_plugin6  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                s.   j  fdd}|_ fdd}|S )aP   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:`pluggy.callers._Result` object
        which represents the result of the overall hook call.
        c                s>    j  t fdd}| j  | S )Nc                  s    S )Nr   r   )r;   
hook_implsr=   oldcallr   r   r>   O      zPPluginManager.add_hookcall_monitoring.<locals>.traced_hookexec.<locals>.<lambda>)r)   r   Z	from_call
get_result)r;   r   r=   outcome)afterbeforer   )r;   r   r=   r   traced_hookexecM  s    z>PluginManager.add_hookcall_monitoring.<locals>.traced_hookexecc                  s
    _ d S )N)rF   r   )r   r   r   r   undoU  s    z3PluginManager.add_hookcall_monitoring.<locals>.undo)rF   )r   r   r   r   r   r   )r   r   r   r   r   add_hookcall_monitoring>  s
    z%PluginManager.add_hookcall_monitoringc                s2   | j jd  fdd} fdd}| ||S )z; enable tracing of hook calls and return an undo function. r;   c                s    j  jd7  _ | | d S )Nr   )rootindent)	hook_namer<   r=   )	hooktracer   r   r   ^  s    z,PluginManager.enable_tracing.<locals>.beforec                s0   | j d kr d|d|    j jd8  _d S )Nfinishz-->r   )excinfor   r   r   )r   r   r<   r=   )r   r   r   r   b  s    
z+PluginManager.enable_tracing.<locals>.after)rB   r   r:   r   )r   r   r   r   )r   r   enable_tracingZ  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 :py:class:`.hooks._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)r)   r   r   
<listcomp>n  s    z4PluginManager.subset_hook_caller.<locals>.<listcomp>)r+   r;   r   r)   rG   r8   	namespacer9   rd   r   rO   r@   
setdefaultrP   )r   r)   Zremove_pluginsorigZplugins_to_removerg   rS   r   r   )r)   r   subset_hook_calleri  s    
z PluginManager.subset_hook_caller)N)N)NN)N)r!   r"   r#   r$   r   rG   rT   rK   r`   ra   rb   rh   rc   rk   rl   rI   r^   ro   r]   rN   rv   r}   r   r   r   r   r   r   r   r   r   r   r3   4   s2   

%

r3   	signaturec             C   s   d| j tt| f S )Nz%s%s)r!   rm   rV   r   )funcr   r   r   rs     s    rs   c             C   s   d| j tjt|  f S )Nz%s%s)r!   rV   formatargspec
getargspec)r   r   r   r   rs     s    )rV   sys r   callersr   hooksr   r   r   r   r   version_info	importlibr   rw   r   r   r   objectr&   r3   r   rs   r   r   r   r   <module>   s"   
	  L

