U
    W[                      @   s
  d Z ddlmZmZ ddlZddlZddlmZmZ dd Z	e	 Z
ddl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eZG dd deZdd Zz
ejZW n ek
r   dddZY nX dd Zd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
    )absolute_importdivisionN)	Interface
providedByc                  C   s4   zddl } | W S  tk
r.   ddl}| Y S X dS )z5
    Determine which 'pickle' API module to use.
    r   N)cPickleImportErrorpickle)r   r    r	   0/usr/lib/python3/dist-packages/twisted/plugin.py_determinePickleModule   s    r   )getAdapterFactory)namedAny)log)	getModule)	iteritemsc                   @   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	   r	   r
   r   )   s   r   c                   @   s2   e Zd Zdd Z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__5   s
    zCachedPlugin.__init__c                 C   s&   d| j | jjddd | jD f S )Nz"<CachedPlugin %r/%r (provides %r)>z, c                 S   s   g | ]
}|j qS r	   )r   ).0ir	   r	   r
   
<listcomp>?   s     z)CachedPlugin.__repr__.<locals>.<listcomp>)r   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
   loadA   s    zCachedPlugin.loadNc                 C   sH   | j D ]<}||r |    S t||d d k	r||  |  S q|S r   )r   ZisOrExtendsr(   r   )r   	interfaceregistrydefaultZprovidedInterfacer	   r	   r
   __conform__D   s    

zCachedPlugin.__conform__)NN)r   r   r   r   r&   r(   r,   ZgetComponentr	   r	   r	   r
   r   4   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   b   s    zCachedDropin.__init__N)r   r   r   r   r   r	   r	   r	   r
   r-   Q   s   r-   c                 C   sP   t | j| j}t| jD ]2\}}t|d }|d k	rt|||jtt| q|S r   )	r-   r   r   r   __dict__r   r   listr   )providerr   kvpluginr	   r	   r
   _generateCacheEntryi   s    
r4   c                 C   s   i }| D ]}|||< q|S r   r	   )keysvaluedr1   r	   r	   r
   fromkeysv   s    
r8   c                 C   s  i }t | j}i }| D ]0}|j }||kr8g ||< || }|| qt|D ]f\}}|d}z,| }	|	d}
t
|
}W 5 Q R X W n   i }d}	Y nX d}i }|D ]h}|jdd }d||< ||ks|j |	krd}z| }W n   t  Y qX t|}|||< qt| D ]}||kr,||= d}q,|rz|t
| W nN tk
r } ztjd|j|jd	 W 5 d
}~X Y n   td
d Y nX || qT|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rr   Fr'   Tz@Unable to write to plugin cache %(path)s: error number %(errno)d)formatpatherrnoNz)Unexpected error while writing cache file)r   r   ZiterModulesZfilePathparentr   r   ZchildZgetModificationTimeopenr   r(   r   splitr   errr4   r/   r5   Z
setContentdumpsOSErrormsgr<   r=   update)moduleZallCachesCombinedmodZbucketsZplugmodZfppZbucketZpseudoPackagePathZ
dropinPathZ
lastCachedfZdropinDotCacheZ
needsWriteZexistingKeysZpluginModuleZ	pluginKeyr0   entryer	   r	   r
   getCache~   sd    






 rK   c                 c   sp   |dkrddl m} t|}t|D ]F\}}|jD ]6}z| |d}W n   t  Y q2X |dk	r2|V  q2q$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.
    Nr   )Ztwisted.pluginsr   rK   r   r   rA   )r)   packageZ
allDropinskeyr   r3   Zadaptedr	   r	   r
   
getPlugins   s    
rN   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                    sF   g | ]>}t jt jj|f d g  st jt jj|f  qS )z__init__.py)osr<   existsr$   abspath)r    xrL   r	   r
   r"      s    z&pluginPackagePaths.<locals>.<listcomp>)r@   sysr<   )r   r	   rS   r
   pluginPackagePaths   s    


rU   )N)N)"r   Z
__future__r   r   rO   rT   Zzope.interfacer   r   r   r   Ztwisted.python.componentsr   Ztwisted.python.reflectr   Ztwisted.pythonr   Ztwisted.python.modulesr   Ztwisted.python.compatr   r   objectr   r-   r4   dictr8   AttributeErrorrK   rN   Z
getPlugInsrU   __all__r	   r	   r	   r
   <module>   s0   

I
