U
    n5{i!  ã                   @   s8  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k
rØ   ddd„ZY nX dd„ Zejdœdd„Ze	ded�Zd ee eej ee 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
é    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   ú2/tmp/pip-unpacked-wheel-mnhg7r0q/twisted/plugin.pyr      s   r   c                   @   s8   e Zd Zdd„ Zedœ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 k	r||  ¡ |ƒ  S q|S r   )r   ZisOrExtendsr(   r	   )r   Ú	interfaceÚregistryÚdefaultZprovidedInterfacer   r   r   Ú__conform__8   s    

zCachedPlugin.__conform__)NN)	r   r   r   r   Ústrr&   r(   r,   Z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   r.   D   s   r.   c                 C   sP   t | j| jƒ}| j ¡ D ]2\}}t|d ƒ}|d k	rt|||jtt|ƒƒƒ q|S r   )	r.   r   r   Ú__dict__Úitemsr   r   Úlistr   )Úproviderr   ÚkÚvÚpluginr   r   r   Ú_generateCacheEntry\   s    
r6   c                 C   s   i }| D ]}|||< q|S r   r   )ÚkeysÚvalueÚdr3   r   r   r   Úfromkeysj   s    
r:   c                 C   sÞ  i }t | jƒ}i }| ¡ D ]0}|j ¡ }||kr8g ||< || }| |¡ q| ¡ D �]‚\}}| d¡}z,| ¡ }	| 	d¡�}
t
 |
¡}W 5 Q R X W n tk
r°   i }d}	Y nX d}i }|D ]r}|j d¡d }d||< ||ksð|j ¡ |	kr¾d}z| ¡ }W n tk
�r   t ¡  Y q¾X t|ƒ}|||< q¾t| ¡ ƒD ]}||k�r>||= d}�q>|�rÎz| t
 |¡¡ W nX tk
�r¬ } ztjd|j|jd	� W 5 d
}~X Y n" tk
�rÌ   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)r"   ÚpathÚerrnoNz)Unexpected error while writing cache file)r
   r   ZiterModulesZfilePathÚparentr   r0   ÚchildZgetModificationTimeÚopenÚpickler(   ÚBaseExceptionr   Úsplitr   Úerrr6   r1   r7   Z
setContentÚdumpsÚOSErrorÚmsgr=   r>   Úupdate)ÚmoduleZallCachesCombinedÚmodZbucketsZplugmodZfppZbucketZpseudoPackagePathZ
dropinPathZ
lastCachedÚfZdropinDotCacheZ
needsWriteZexistingKeysZpluginModuleZ	pluginKeyr2   ÚentryÚer   r   r   ÚgetCacheq   sd    




ÿ

úrO   r   c                  C   s   dd l m}  | S )Nr   )Ztwisted.pluginsr   ©Úpackager   r   r   Ú_pluginsPackage½   s    rR   Ú_TInterface)Úbound)r)   rQ   r   c              
   c   sr   |dkrt ƒ }t|ƒ}| ¡ D ]N\}}|jD ]>}z| |dƒ}W n tk
rZ   t ¡  Y q,X |dk	r,|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)rR   rO   r0   r   rC   r   rE   )r)   rQ   Z
allDropinsÚkeyr   r5   Zadaptedr   r   r   Ú
getPluginsÆ   s    
rV   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   ÚxrP   r   r   r!   ý   s    þz&pluginPackagePaths.<locals>.<listcomp>)rD   Úsysr=   )r   r   rP   r   ÚpluginPackagePathsæ   s    


þr\   )N)N)$r   rW   rB   r[   ÚtypesÚtypingr   r   r   r   Zzope.interfacer   r   Ztwisted.pythonr   Ztwisted.python.componentsr	   Ztwisted.python.modulesr
   Ztwisted.python.reflectr   r   r   r.   r6   Údictr:   ÚAttributeErrorrO   Ú
ModuleTyperR   rS   rV   Z
getPlugInsr\   Ú__all__r   r   r   r   Ú<module>   s<   


L ÿ þ