ó
3ëSc           @   sř  d  Z  d d l Z d d l Z d d l Z d d l Z d d l m Z d d l m	 Z	 d d l
 Z d d l m Z d d l m Z d d l m Z y d d l Z Wn d d l Z n Xy d d l m Z Wn d d l m Z n Xd	 d
 d d d g Z e j e  Z d e f d     YZ d e f d     YZ d
 e f d     YZ d d d     YZ d e f d     YZ d e f d     YZ  y) d d l! Z! d	 e e  f d     YZ" Wn' e# k
 rÝd	 e  f d     YZ" n Xd e" f d     YZ$ d S(   s  
Plugin Manager
--------------

A plugin manager class is used to load plugins, manage the list of
loaded plugins, and proxy calls to those plugins.

The plugin managers provided with nose are:

:class:`PluginManager`
    This manager doesn't implement loadPlugins, so it can only work
    with a static list of plugins.

:class:`BuiltinPluginManager`
    This manager loads plugins referenced in ``nose.plugins.builtin``.

:class:`EntryPointPluginManager`
    This manager uses setuptools entrypoints to load plugins.

:class:`ExtraPluginsPluginManager`
    This manager loads extra plugins specified with the keyword
    `addplugins`.

:class:`DefaultPluginMananger`
    This is the manager class that will be used by default. If
    setuptools is installed, it is a subclass of
    :class:`EntryPointPluginManager` and :class:`BuiltinPluginManager`;
    otherwise, an alias to :class:`BuiltinPluginManager`.

:class:`RestrictedPluginManager`
    This manager is for use in test runs where some plugin calls are
    not available, such as runs started with ``python setup.py test``,
    where the test runner is the default unittest :class:`TextTestRunner`. It
    is a subclass of :class:`DefaultPluginManager`.

Writing a plugin manager
========================

If you want to load plugins via some other means, you can write a
plugin manager and pass an instance of your plugin manager class when
instantiating the :class:`nose.config.Config` instance that you pass to
:class:`TestProgram` (or :func:`main` or :func:`run`).

To implement your plugin loading scheme, implement ``loadPlugins()``,
and in that method, call ``addPlugin()`` with an instance of each plugin
you wish to make available. Make sure to call
``super(self).loadPlugins()`` as well if have subclassed a manager
other than ``PluginManager``.

i˙˙˙˙N(   t   chain(   t   warn(   t   Failure(   t   IPluginInterface(   t	   sort_list(   t   StringIOt   DefaultPluginManagert   PluginManagert   EntryPointPluginManagert   BuiltinPluginManagert   RestrictedPluginManagert   PluginProxyc           B   s_   e  Z d  Z e Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 d   Z d	 d  Z RS(
   s#  Proxy for plugin calls. Essentially a closure bound to the
    given call and plugin list.

    The plugin proxy also must be bound to a particular plugin
    interface specification, so that it knows what calls are available
    and any special handling that is required for each call.
    c         C   s   y t  |  j |  |  _ Wn- t k
 rH t d | |  j j f   n X|  j |  |  _ g  |  _ x | D] } |  j | |  qk Wd  S(   Ns   %s is not a valid %s method(	   t   getattrt	   interfacet   methodt   AttributeErrort   __name__t   makeCallt   callt   pluginst	   addPlugin(   t   selfR   R   t   p(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   __init__W   s    	c         O   s   |  j  | |   S(   N(   R   (   R   t   argt   kw(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   __call__b   s    c            s~   t  | | d  } | d k	 rz | d k ra t t j |  d  d k ra |     f d   } n  |  j j | | f  n  d S(   s`   Add plugin to my list of plugins to call, if it has the attribute
        I'm bound to.
        t   loadTestsFromModulei    i   c            s
     |   S(   N(    (   t   modulet   patht   kwargs(   t	   orig_meth(    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   <lambda>n   s    N(   R   t   Nonet   lent   inspectt
   getargspecR   t   append(   R   t   pluginR   t   meth(    (   R   s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   e   s    c            s_   | d k r   j  S  j } t | d t  r;   f d   St | d t  rT   j S  j Sd  S(   Nt   loadTestsFromNamest
   generativec             s   t    j |  |    S(   N(   t   listt   generate(   R   R   (   R   (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR    {   s    t	   chainable(   t   _loadTestsFromNamesR   R   t   FalseR    t   simple(   R   R   R'   (    (   R   s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   q   s    	c         O   s   d } g  t t |  j d g   |  D] \ } } | r% | ^ q% } x: |  j D]/ \ } } | | |   } | } | j |  qM W| S(   s   Call plugins in a chain, where the result of each plugin call is
        sent to the next plugin as input. The final output result is returned.
        t   static_argsN(   R!   t   zipR   R   R   R%   (   R   R   R   t   resultt   statict   aR   R'   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR       s    (c         o   s   x |  j  D] \ } } d } y8 | | |   } | d k	 rS x | D] } | VqA Wn  Wq
 t t f k
 rp   q
 t j   } t |   Vq
 q
 Xq
 Wd S(   sF   Call all plugins, yielding each item in each non-None result.
        N(   R   R!   t   KeyboardInterruptt
   SystemExitt   syst   exc_infoR   (   R   R   R   R   R'   R2   t   rt   exc(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR+      s    c         O   s=   x6 |  j  D]+ \ } } | | |   } | d k	 r
 | Sq
 Wd S(   s?   Call all plugins, returning the first non-None result.
        N(   R   R!   (   R   R   R   R   R'   R2   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR/   Ł   s    c         C   sm   g  } xZ |  j  D]O \ } } | | d | } | d k	 r | \ } } | r_ | j |  q_ q q W| | f S(   s
  Chainable but not quite normal. Plugins return a tuple of
        (tests, names) after processing the names. The tests are added
        to a suite that is accumulated throughout the full call, while
        names are input for the next plugin in the chain.
        R   N(   R   R!   t   extend(   R   t   namesR   t   suiteR   R'   R2   t
   suite_part(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR-   Ť   s    N(   R   t
   __module__t   __doc__R   R   R   R   R   R   R    R+   R/   R!   R-   (    (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   N   s   							t	   NoPluginsc           B   sn   e  Z d  Z e Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 d   Z d   Z d	   Z d
   Z RS(   s(   Null Plugin manager that has no plugins.c         C   s   d |  _  |  _ d  S(   N(    (   t   _pluginsR   (   R   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   ž   s    c         C   s   d S(   N(    (    (   R   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   __iter__Á   s    c         O   s   d  S(   N(    (   R   t   argst   kwds(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt
   _doNothingÄ   s    c         O   s   d S(   N(    (    (   R   RD   RE   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   _emptyIteratorÇ   s    c         C   s6   t  |  j |  } t  | d t  r+ |  j S|  j Sd  S(   NR)   (   R   R   R.   RG   RF   (   R   R   R   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   __getattr__Ę   s    c         C   s   t     d  S(   N(   t   NotImplementedError(   R   t   plug(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   Ń   s    c         C   s   t     d  S(   N(   RI   (   R   R   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt
   addPluginsÔ   s    c         C   s   d  S(   N(    (   R   t   optionst   config(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt	   configure×   s    c         C   s   d  S(   N(    (   R   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   loadPluginsÚ   s    c         C   s   d  S(   N(    (   R   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   sortÝ   s    (   R   R?   R@   R   R   R   RC   RF   RG   RH   R   RK   RN   RO   RP   (    (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRA   ť   s   									c           B   s   e  Z d  Z e Z d d d  Z d   Z d   Z d   Z	 d d d  Z
 d   Z d   Z d   Z d	   Z d
   Z e e e d d  Z RS(   sŮ  Base class for plugin managers. PluginManager is intended to be
    used only with a static list of plugins. The loadPlugins() implementation
    only reloads plugins from _extraplugins to prevent those from being
    overridden by a subclass.

    The basic functionality of a plugin manager is to proxy all unknown
    attributes through a ``PluginProxy`` to a list of plugins.

    Note that the list of plugins *may not* be changed after the first plugin
    call.
    c         C   sM   g  |  _  d |  _ i  |  _ | r1 |  j |  n  | d  k	 rI | |  _ n  d  S(   N(    (   RB   t   _extrapluginst   _proxiesRK   R!   t
   proxyClass(   R   R   RS   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   ď   s    			c         C   sI   y |  j  | SWn3 t k
 rD |  j | |  j  } | |  j  | <n X| S(   N(   RR   t   KeyErrorRS   RB   (   R   R   t   proxy(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRH   ř   s    c         C   s   t  |  j  S(   N(   t   iterR   (   R   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRC      s    c         C   sa   t  | d t    } g  |  j D]$ } t  | d d   | k r | ^ q |  j (|  j j |  d  S(   Nt   name(   R   t   objectRB   R!   R%   (   R   RJ   t   new_nameR   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR     s    (c         C   s4   | |  _  x$ t | |  D] } |  j |  q Wd S(   s¸   extraplugins are maintained in a separate list and
        re-added by loadPlugins() to prevent their being overwritten
        by plugins added by a subclass of PluginManager
        N(   RQ   t	   iterchainR   (   R   R   t   extrapluginsRJ   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRK     s    	c         C   s   t  j d  | |  _ t d |  j  } | | |  g  |  j D] } | j r? | ^ q? } | |  _ |  j   t  j d |  d S(   sŞ   Configure the set of plugins with the given options
        and config instance. After configuration, disabled plugins
        are removed from the plugins list.
        s   Configuring pluginsRN   s   Plugins enabled: %sN(   t   logt   debugRM   R   RB   t   enabledR   RP   (   R   RL   RM   t   cfgRJ   R^   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRN     s    	%	
c         C   s%   x |  j  D] } |  j |  q
 Wd  S(   N(   RQ   R   (   R   RJ   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRO   "  s    c         C   s   t  |  j d   d t S(   Nc         S   s   t  |  d d  S(   Nt   scorei   (   R   (   t   x(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR    '  s    t   reverse(   R   RB   t   True(   R   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRP   &  s    c         C   s   |  j  S(   N(   RB   (   R   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   _get_plugins)  s    c         C   s   g  |  _  |  j |  d  S(   N(   RB   RK   (   R   R   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   _set_plugins,  s    	sP   Access the list of plugins managed by
                       this plugin manager(    N(    (    (   R   R?   R@   R   RS   R!   R   RH   RC   R   RK   RN   RO   RP   Rd   Re   t   propertyR   (    (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   á   s   										t   ZeroNinePluginc           B   se   e  Z d  Z d   Z e j d  Z d   Z d   Z d   Z	 d   Z
 d   Z d   Z d	   Z RS(
   s>   Proxy for 0.9 plugins, adapts 0.10 calls to 0.9 standard.
    c         C   s   | |  _  d  S(   N(   R&   (   R   R&   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   8  s    c         C   s   |  j  j | |  d  S(   N(   R&   t   add_options(   R   t   parsert   env(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRL   ;  s    c   	      C   sÍ   t  |  j d  s d  Sd d l m } m } | \ } } } t | |  rs t  |  j d  s` d  S|  j j | j  St | |  rŤ t  |  j d  s d  S|  j j | j  S| j	 } |  j j
 | j | |  S(   Nt   addErrori˙˙˙˙(   t   SkipTestt   DeprecatedTestt   addSkipt   addDeprecated(   t   hasattrR&   t   nose.excRl   Rm   t
   issubclassRn   t   testRo   t   capturedOutputRk   (	   R   Rs   t   errRl   Rm   t   ect   evt   tbt   capt(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRk   >  s    	c         C   s&   t  |  j d  r" |  j j |  Sd  S(   Nt   loadTestsFromPath(   Rp   R&   Rz   (   R   t   filename(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   loadTestsFromFileP  s    c         C   sD   t  |  j d  s d  S| j } | j } |  j j | j | | |  S(   Nt
   addFailure(   Rp   R&   Rt   t   tbinfoR}   Rs   (   R   Rs   Ru   Ry   R~   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR}   T  s
    		c         C   s9   t  |  j d  s d  S| j } |  j j | j |  d  S(   Nt
   addSuccess(   Rp   R&   Rt   R   Rs   (   R   Rs   Ry   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   \  s    	c         C   s)   t  |  j d  s d  S|  j j | j  S(   Nt	   startTest(   Rp   R&   R   Rs   (   R   Rs   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   b  s    c         C   s)   t  |  j d  s d  S|  j j | j  S(   Nt   stopTest(   Rp   R&   R   Rs   (   R   Rs   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   g  s    c         C   s   t  |  j |  S(   N(   R   R&   (   R   t   val(    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRH   l  s    (   R   R?   R@   R   t   ost   environRL   Rk   R|   R}   R   R   R   RH   (    (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRg   5  s   							c           B   s)   e  Z d  Z d d e f f Z d   Z RS(   sh   Plugin manager that loads plugins from the `nose.plugins` and
    `nose.plugins.0.10` entry points.
    s   nose.plugins.0.10s   nose.pluginsc   	      C   s  d d l  m } i  } xę |  j D]ß \ } } xĐ | |  D]Â } | j | k rT q9 n  t | | j <t j d |  j j |  y | j	   } Wn@ t
 k
 r    n- t k
 rĚ } t d | | f t  q9 n X| rĺ | |    } n	 |   } |  j |  q9 Wq  Wt t |   j   d S(   sB   Load plugins by iterating the `nose.plugins` entry point.
        i˙˙˙˙(   t   iter_entry_pointss   %s load plugin %ss   Unable to load plugin %s: %sN(   t   pkg_resourcesR   t   entry_pointsRW   Rc   R\   R]   t	   __class__R   t   loadR5   t	   ExceptionR   t   RuntimeWarningR   t   superR   RO   (	   R   R   t   loadedt   entry_pointt   adaptt   ept   plugclst   eRJ   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRO   w  s*    	N(   s   nose.plugins.0.10N(   R   R?   R@   R!   Rg   R   RO   (    (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   p  s   c           B   s   e  Z d  Z d   Z RS(   sS   Plugin manager that loads plugins from the list in
    `nose.plugins.builtin`.
    c         C   sK   d d l  m } x! | j D] } |  j |    q Wt t |   j   d S(   s-   Load plugins in nose.plugins.builtin
        i˙˙˙˙(   t   builtinN(   t   nose.pluginsR   R   R   R   R	   RO   (   R   R   RJ   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRO     s    (   R   R?   R@   RO   (    (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR	     s   c           B   s   e  Z RS(    (   R   R?   (    (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   Ł  s   c           B   s   e  Z RS(    (   R   R?   (    (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   §  s   c           B   s2   e  Z d  Z d d e d  Z d   Z d   Z RS(   sé   Plugin manager that restricts the plugin list to those not
    excluded by a list of exclude methods. Any plugin that implements
    an excluded method will be removed from the manager's plugin list
    after plugins are loaded.
    c         C   s8   t  j |  |  | |  _ | |  _ g  |  _ d  |  _ d  S(   N(   R   R   R   t   excludet   excludedR!   t   _excludedOpts(   R   R   R   R   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR   °  s
    			c         C   sr   |  j  d  k r^ d d l m } | d t  |  _  x* |  j D] } | j |  j  d i  q; Wn  |  j  j d |  S(   Ni˙˙˙˙(   t   OptionParsert   add_help_optionRj   s   --(   R   R!   t   optparseR   R.   R   RL   t
   get_option(   R   RW   R   R&   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   excludedOptionˇ  s    c         C   s   |  j  r t j |   n  g  } xj |  j D]_ } t } x: |  j D]/ } t | |  r? t } |  j j	 |  Pq? q? W| r) | j	 |  q) q) W| |  _ d  S(   N(
   R   R   RO   R   Rc   R   Rp   R.   R   R%   (   R   t   allowR&   t   okR   (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyRO   ż  s    	(    (    (   R   R?   R@   Rc   R   R   RO   (    (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyR
   Ş  s   	(    (%   R@   R#   t   loggingR   R7   t	   itertoolsR    RZ   t   warningsR   t   nose.configt   noset   nose.failureR   t   nose.plugins.baseR   t   nose.pyversionR   t   cPicklet   picklet	   cStringIOR   t   __all__t	   getLoggerR   R\   RX   R   RA   R   Rg   R   R	   R   R   t   ImportErrorR
   (    (    (    s3   lib/python2.7/site-packages/nose/plugins/manager.pyt   <module>2   sB   	m&T;%