B t `<@sdZddlZddlZddlZddlZddlmZddlm Z ddl Z ddl m Z ddlmZddlmZy ddlZWnddlZYnXyddlmZWnddlmZYnXd d d d d gZeeZGdddeZGdddeZGdd d eZGdddZGdd d eZGdd d eZyddl Z Gdd d eeZ!Wn&e"k rnGdd d eZ!YnXGdd d e!Z#dS)a 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``. N)chain)warn)Failure)IPluginInterface) sort_list)StringIODefaultPluginManager PluginManagerEntryPointPluginManagerBuiltinPluginManagerRestrictedPluginManagerc@sVeZdZdZeZddZddZddZdd Z d d Z d d Z ddZ dddZ dS) PluginProxya#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. cCslyt|j||_Wn(tk r:td||jjfYnX|||_g|_x|D]}|||qTWdS)Nz%s is not a valid %s method) getattr interfacemethodAttributeError__name__makeCallcallplugins addPlugin)selfrrpr8/tmp/pip-unpacked-wheel-cjhnoqsi/nose/plugins/manager.py__init__Ws  zPluginProxy.__init__cOs |j||S)N)r)rargkwrrr__call__bszPluginProxy.__call__csVt||d}|dk rR|dkrBtt|ddkrB|fdd}|j||fdS)z`Add plugin to my list of plugins to call, if it has the attribute I'm bound to. NZloadTestsFromModulercs|S)Nr)modulepathkwargs) orig_methrrnz'PluginProxy.addPlugin..)rleninspect getargspecrappend)rpluginrmethr)r#rres  zPluginProxy.addPlugincsH|dkrjSj}t|ddr,fddSt|ddr>jSjSdS)NZloadTestsFromNames generativeFcstj||S)N)listgenerate)rr)rrrr${r%z&PluginProxy.makeCall..Z chainable)_loadTestsFromNamesrrrsimple)rrr+r)rrrqs   zPluginProxy.makeCallcOsZd}ddtt|jdg|D}x2|jD](\}}|||}|dd}||q*W|S)zCall 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. NcSsg|]\}}|r|qSrr).0staticarrr sz%PluginProxy.chain..Z static_args)ziprrrr))rrrresultr2rr+rrrrs  zPluginProxy.chainc osxz|jD]p\}}d}y*|||}|dk r.)robjectrCr))rrKr)rYrrszPluginManager.addPlugincCs(||_xt||D]}||qWdS)zextraplugins 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)rR iterchainr)rrZ extrapluginsrKrrrrL szPluginManager.addPluginscCsTtd||_td|j}|||dd|jD}||_|td|dS)zConfigure the set of plugins with the given options and config instance. After configuration, disabled plugins are removed from the plugins list. zConfiguring pluginsrOcSsg|]}|jr|qSr)enabled)r1rKrrrr4sz+PluginManager.configure..zPlugins enabled: %sN)logdebugrNr rCrrQ)rrMrNcfgr\rrrrOs   zPluginManager.configurecCsx|jD]}||qWdS)N)rRr)rrKrrrrP"s zPluginManager.loadPluginscCst|jddddS)NcSs t|ddS)NZscore)r)xrrrr$'r%z$PluginManager.sort..T)reverse)rrC)rrrrrQ&szPluginManager.sortcCs|jS)N)rC)rrrr _get_plugins)szPluginManager._get_pluginscCsg|_||dS)N)rCrL)rrrrr _set_plugins,szPluginManager._set_pluginszPAccess the list of plugins managed by this plugin manager)rN)rr)rr?r@rAr rTrrIrDrrLrOrPrQrcrdpropertyrrrrrr s   c@s^eZdZdZddZejfddZddZdd Z d d Z d d Z ddZ ddZ ddZdS)ZeroNinePluginz>Proxy for 0.9 plugins, adapts 0.10 calls to 0.9 standard. cCs ||_dS)N)r*)rr*rrrr8szZeroNinePlugin.__init__cCs|j||dS)N)r* add_options)rparserenvrrrrM;szZeroNinePlugin.optionsc Cst|jdsdSddlm}m}|\}}}t||rRt|jdsDdS|j|jSt||rzt|jdsldS|j|jS|j }|j |j||S)NaddErrorr)SkipTestDeprecatedTestaddSkip addDeprecated) hasattrr*Znose.excrkrl issubclassrmtestrncapturedOutputrj) rrqerrrkrlZecZevtbcaptrrrrj>s      zZeroNinePlugin.addErrorcCst|jdr|j|SdS)NloadTestsFromPath)ror*rv)rfilenamerrrloadTestsFromFilePs z ZeroNinePlugin.loadTestsFromFilecCs0t|jdsdS|j}|j}|j|j|||S)N addFailure)ror*rrtbinforyrq)rrqrsrurzrrrryTs  zZeroNinePlugin.addFailurecCs*t|jdsdS|j}|j|j|dS)N addSuccess)ror*rrr{rq)rrqrurrrr{\s zZeroNinePlugin.addSuccesscCst|jdsdS|j|jS)N startTest)ror*r|rq)rrqrrrr|bs zZeroNinePlugin.startTestcCst|jdsdS|j|jS)NstopTest)ror*r}rq)rrqrrrr}gs zZeroNinePlugin.stopTestcCs t|j|S)N)rr*)rvalrrrrIlszZeroNinePlugin.__getattr__N)rr?r@rArosenvironrMrjrxryr{r|r}rIrrrrrf5srfcs,eZdZdZddeffZfddZZS)r zhPlugin manager that loads plugins from the `nose.plugins` and `nose.plugins.0.10` entry points. )znose.plugins.0.10Nz nose.pluginsc sddlm}i}x|jD]\}}x||D]}|j|kr:q*d||j<td|jj|y |}WnJt k rxYn6t k r}zt d||ft w*Wdd}~XYnX|r||}n|}| |q*WqWtt|dS)zBLoad plugins by iterating the `nose.plugins` entry point. r)iter_entry_pointsTz%s load plugin %szUnable to load plugin %s: %sN) pkg_resourcesr entry_pointsrXr]r^ __class__rloadr7 ExceptionrRuntimeWarningrsuperr rP) rrZloadedZ entry_pointZadaptepZplugclserK)rrrrPws*      z#EntryPointPluginManager.loadPlugins)rr?r@rArfrrP __classcell__rr)rrr ps cs eZdZdZfddZZS)r zSPlugin manager that loads plugins from the list in `nose.plugins.builtin`. cs:ddlm}x|jD]}||qWtt|dS)z-Load plugins in nose.plugins.builtin r)builtinN)Z nose.pluginsrrrrr rP)rrrK)rrrrPs  z BuiltinPluginManager.loadPlugins)rr?r@rArPrrr)rrr sc@s eZdZdS)rN)rr?r@rrrrrsc@s eZdZdS)rN)rr?r@rrrrrsc@s*eZdZdZd ddZddZdd Zd S) r zPlugin 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. rTcCs(t||||_||_g|_d|_dS)N)rrrexcludeexcluded _excludedOpts)rrrrrrrrs  z RestrictedPluginManager.__init__cCsR|jdkrBddlm}|dd|_x|jD]}|j|jidq*W|jd|S)Nr) OptionParserF)add_help_option)riz--)roptparserrrM get_option)rrXrr*rrrexcludedOptions     z&RestrictedPluginManager.excludedOptioncCsl|jrt|g}xL|jD]B}d}x*|jD] }t||r,d}|j|Pq,W|r||qW||_dS)NTF)rrrPrrrorr))rZallowr*okrrrrrPs     z#RestrictedPluginManager.loadPluginsN)rrT)rr?r@rArrrPrrrrr s )$rAr'loggingrr9 itertoolsrr[warningsrZ nose.configZnoseZ nose.failurerZnose.plugins.baserZnose.pyversionrpickleior__all__ getLoggerrr]rZr rBr rfr r rr ImportErrorr rrrr2sB       m&T;%