U
    k&p[*                     @   s<   d Z ddlZddlZddlZddlmZ G dd deZdS )as  A generic plugin manager.

The plugin manager finds files with plugins and loads them. It looks
for plugins in a number of locations specified by the caller. To add
a plugin to be loaded, it is enough to put it in one of the locations,
and name it *_plugin.py. (The naming convention is to allow having
other modules as well, such as unit tests, in the same locations.)

    N)Pluginc                   @   s   e Zd ZdZdZdd Zedd Ze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dZdddZdS )PluginManagera<  Manage plugins.

    This class finds and loads plugins, and keeps a list of them that
    can be accessed in various ways.

    The locations are set via the locations attribute, which is a list.

    When a plugin is loaded, an instance of its class is created. This
    instance is initialized using normal and keyword arguments specified
    in the plugin manager attributes plugin_arguments and
    plugin_keyword_arguments.

    The version of the application using the plugin manager is set via
    the application_version attribute. This defaults to '0.0.0'.

    z
_plugin.pyc                 C   s(   g | _ d | _d | _g | _i | _d| _d S )Nz0.0.0)	locations_plugins_plugin_filesplugin_argumentsplugin_keyword_argumentsapplication_versionself r   2/usr/lib/python3/dist-packages/cliapp/pluginmgr.py__init__:   s    zPluginManager.__init__c                 C   s   | j d kr|  | _ | j S N)r   find_plugin_filesr
   r   r   r   plugin_filesB   s    

zPluginManager.plugin_filesc                 C   s   | j d kr|  | _ | j S r   )r   load_pluginsr
   r   r   r   pluginsH   s    

zPluginManager.pluginsc                 C   s.   | j D ]}|j|kr|  S qtd| d S )NzPlugin %s is not known)r   nameKeyError)r   r   pluginr   r   r   __getitem__N   s    


zPluginManager.__getitem__c              	   C   s|   g }| j D ]h}zt|}W n tjk
r6   Y q
Y nX |D ]4}tj||}|| jr<tj|r<|	| q<q
t
|S )zFind files that may contain plugins.

        This finds all files named *_plugin.py in all locations.
        The returned list is sorted.

        )r   oslistdirerrorpathjoinendswithsuffixexistsappendsorted)r   Z	pathnameslocationZ	basenamesbasenamesr   r   r   r   T   s    

zPluginManager.find_plugin_filesc                 C   sh   t  }| jD ]N}| |D ]>}|j|krN||j }| |j|jrX|||j< q|||j< qqt| S )z#Load plugins from all plugin files.)dictr   load_plugin_filer   is_olderversionlistvalues)r   r   pathnamer   pr   r   r   r   j   s    


zPluginManager.load_pluginsc                 C   s   |  ||  |k S )z Is version1 older than version2?)parse_version)r   Zversion1Zversion2r   r   r   r'   z   s    zPluginManager.is_olderc           
      C   s   t jt j|\}}t|d}t|||ddtjf}|  g }t	
|t	jD ]6\}}t|trT|| j| j}	| |	jrT||	 qT|S )z'Return plugin classes in a plugin file.rz.py)r   r   splitextr#   openimpload_module	PY_SOURCEcloseinspectZ
getmembersZisclass
issubclassr   r   r   compatible_versionrequired_application_versionr    )
r   r+   r   _fmoduler   Zdummymemberr,   r   r   r   r&   ~   s    



zPluginManager.load_plugin_filec                 C   s.   |  |}|  | j}|d |d ko,||kS )zCheck that the plugin is version-compatible with the application.

        This checks the plugin's required_application_version against
        the declared application version and returns True if they are
        compatible, and False if not.

        r   )r-   r	   )r   r8   ZreqZappr   r   r   r7      s    	
z PluginManager.compatible_versionc                 C   s   dd | dD S )z<Parse a string represenation of a version into list of ints.c                 S   s   g | ]}t |qS r   )int).0r$   r   r   r   
<listcomp>   s     z/PluginManager.parse_version.<locals>.<listcomp>.)split)r   r(   r   r   r   r-      s    zPluginManager.parse_versionNc                 C   s   |p| j D ]}|  q
dS )zEnable all or selected plugins.N)r   Zenable_wrapperr   r   r   r   r   r   enable_plugins   s    zPluginManager.enable_pluginsc                 C   s   |p| j D ]}|  q
dS )z Disable all or selected plugins.N)r   Zdisable_wrapperrB   r   r   r   disable_plugins   s    zPluginManager.disable_plugins)N)N)__name__
__module____qualname____doc__r   r   propertyr   r   r   r   r   r'   r&   r7   r-   rC   rD   r   r   r   r   r   %   s    


r   )rH   r1   r5   r   Zcliappr   objectr   r   r   r   r   <module>   s
   