o
    b!                     @   s<  d Z ddlZddlZddlZddlZddlmZmZmZm	Z	 ddl
mZmZ ddlmZ ddlmZ ddlmZ ddlmZ G d	d
 d
eZG dd dZG dd dZdd ZzejZW n eyk   d ddZY nw dd ZdejfddZe	dedZ	d dee deej dee fddZ e Z!dd Z"ddgZ#dS )!zL
Plugin system for Twisted.

@author: Jp Calderone
@author: Glyph Lefkowitz
    N)IterableOptionalTypeTypeVar)	Interface
providedBy)log)getAdapterFactory)	getModule)namedAnyc                   @   s   e Zd ZdZdS )IPluginz
    Interface that must be implemented by all plugins.

    Only objects which implement this interface will be considered for return
    by C{getPlugins}.  To be useful, plugins should also implement some other
    application-specific interface.
    N)__name__
__module____qualname____doc__ r   r   0/usr/lib/python3/dist-packages/twisted/plugin.pyr      s    r   c                   @   s8   e Zd Zdd ZdefddZdd Zdd	d
ZeZdS )CachedPluginc                 C   s*   || _ || _|| _|| _| j j|  d S N)dropinnamedescriptionprovidedpluginsappend)selfr   r   r   r   r   r   r   __init__'   s
   zCachedPlugin.__init__returnc                 C   s&   d | j| jjddd | jD S )Nz(<CachedPlugin {!r}/{!r} (provides {!r})>z, c                 S   s   g | ]}|j qS r   )r   ).0ir   r   r   
<listcomp>2   s    z)CachedPlugin.__repr__.<locals>.<listcomp>)formatr   r   
moduleNamejoinr   r   r   r   r   __repr__.   s
   zCachedPlugin.__repr__c                 C   s   t | jjd | j S )N.)r   r   r"   r   r$   r   r   r   load5   s   zCachedPlugin.loadNc                 C   sH   | j D ]}||r|    S t||d d ur!||  |  S q|S r   )r   isOrExtendsr'   r	   )r   	interfaceregistrydefaultprovidedInterfacer   r   r   __conform__8   s   

zCachedPlugin.__conform__)NN)	r   r   r   r   strr%   r'   r-   getComponentr   r   r   r   r   &   s    
	r   c                   @   s   e Zd ZdZdd ZdS )CachedDropina  
    A collection of L{CachedPlugin} instances from a particular module in a
    plugin package.

    @type moduleName: C{str}
    @ivar moduleName: The fully qualified name of the plugin module this
        represents.

    @type description: C{str} or L{None}
    @ivar description: A brief explanation of this collection of plugins
        (probably the plugin module's docstring).

    @type plugins: C{list}
    @ivar plugins: The L{CachedPlugin} instances which were loaded from this
        dropin.
    c                 C   s   || _ || _g | _d S r   )r"   r   r   )r   r"   r   r   r   r   r   V   s   
zCachedDropin.__init__N)r   r   r   r   r   r   r   r   r   r0   D   s    r0   c                 C   sP   t | j| j}| j D ]\}}t|d }|d ur%t|||jtt| q|S r   )	r0   r   r   __dict__itemsr   r   listr   )providerr   kvpluginr   r   r   _generateCacheEntry\   s   
r8   c                 C   s   i }| D ]}|||< q|S r   r   )keysvaluedr5   r   r   r   fromkeysj   s   
r<   c                 C   s  i }t | j}i }| D ]}|j }||vrg ||< || }|| q| D ]\}}|d}z | }	|	d}
t
|
}W d   n1 sMw   Y  W n ty`   i }d}	Y nw d}i }|D ]7}|jdd }d||< ||vs|j |	krd}z| }W n ty   t  Y qgw t|}|||< qgt| D ]}||vr||= d}q|rz
|t
| W n* ty } ztjd	|j|jd
 W Y d}~nd}~w ty   tdd Y nw || q*|S )a;  
    Compute all the possible loadable plugins, while loading as few as
    possible and hitting the filesystem as little as possible.

    @param module: a Python module object.  This represents a package to search
    for plugins.

    @return: a dictionary mapping module names to L{CachedDropin} instances.
    zdropin.cacherNr   Fr&   Tz@Unable to write to plugin cache %(path)s: error number %(errno)d)r!   patherrnoz)Unexpected error while writing cache file)r
   r   iterModulesfilePathparentr   r2   childgetModificationTimeopenpickler'   BaseExceptionr   splitr   errr8   r3   r9   
setContentdumpsOSErrormsgr?   r@   update)moduleallCachesCombinedmodbucketsplugmodfppbucketpseudoPackagePath
dropinPath
lastCachedfdropinDotCache
needsWriteexistingKeyspluginModule	pluginKeyr4   entryer   r   r   getCacheq   sr   



rb   r   c                  C   s   dd l m}  | S )Nr   )twisted.pluginsr   packager   r   r   _pluginsPackage   s   rf   _TInterface)boundr)   re   c              
   c   sr    |du rt  }t|}| D ]&\}}|jD ]}z| |d}W n ty-   t  Y qw |dur5|V  qqdS )ac  
    Retrieve all plugins implementing the given interface beneath the given module.

    @param interface: An interface class.  Only plugins which implement this
    interface will be returned.

    @param package: A package beneath which plugins are installed.  For
    most uses, the default value is correct.

    @return: An iterator of plugins.
    N)rf   rb   r2   r   rH   r   rJ   )r)   re   
allDropinskeyr   r7   adaptedr   r   r   
getPlugins   s    
rl   c                    s   |  d  fddtjD S )a  
    Return a list of additional directories which should be searched for
    modules to be included as part of the named plugin package.

    @type name: C{str}
    @param name: The fully-qualified Python name of a plugin package, eg
        C{'twisted.plugins'}.

    @rtype: C{list} of C{str}
    @return: The absolute paths to other directories which may contain plugin
        modules for the named plugin package.
    r&   c                    sJ   g | ]!}t jt jj|g d g R  st jt jj|g R  qS )z__init__.py)osr?   existsr#   abspath)r   xrd   r   r   r       s     z&pluginPackagePaths.<locals>.<listcomp>)rI   sysr?   )r   r   rd   r   pluginPackagePaths   s   


rr   r   )$r   rm   rG   rq   typestypingr   r   r   r   zope.interfacer   r   twisted.pythonr   twisted.python.componentsr	   twisted.python.modulesr
   twisted.python.reflectr   r   r   r0   r8   dictr<   AttributeErrorrb   
ModuleTyperf   rg   rl   
getPlugInsrr   __all__r   r   r   r   <module>   sD   


	L
