ó J9•Qc@sřdZddlZddlZddlZddlZddlmZddlm Z ddl Z ddl m Z ddlmZddlmZyddlZWnddlZnXyddlmZWnddlmZnXd d d d d gZejeƒZdefd„ƒYZdefd„ƒYZd efd„ƒYZddd„ƒYZd efd„ƒYZd efd„ƒYZ y)ddl!Z!d ee fd„ƒYZ"Wn'e#k rÝd e fd„ƒYZ"nXd e"fd„ƒYZ$dS(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(tchain(twarn(tFailure(tIPluginInterface(t sort_list(tStringIOtDefaultPluginManagert PluginManagertEntryPointPluginManagertBuiltinPluginManagertRestrictedPluginManagert PluginProxycBs_eZdZeZd„Zd„Zd„Zd„Zd„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. cCs‰yt|j|ƒ|_Wn-tk rHtd||jjfƒ‚nX|j|ƒ|_g|_x|D]}|j||ƒqkWdS(Ns%s is not a valid %s method( tgetattrt interfacetmethodtAttributeErrort__name__tmakeCalltcalltpluginst addPlugin(tselfRRtp((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyt__init__Ws   cOs|j||ŽS(N(R(Rtargtkw((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyt__call__bscs~t||dƒ}|dk rz|dkrattj|ƒdƒdkra|‰‡fd†}n|jj||fƒndS(s`Add plugin to my list of plugins to call, if it has the attribute I'm bound to. tloadTestsFromModuleiics ˆ|ƒS(N((tmoduletpathtkwargs(t orig_meth(s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pytnsN(R tNonetlentinspectt getargspecRtappend(RtpluginRtmeth((Rs8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyRes  cs_|dkrˆjSˆj}t|dtƒr;‡fd†St|dtƒrTˆjSˆjSdS(NtloadTestsFromNamest generativecstˆj||ŽƒS(N(tlisttgenerate(RR(R(s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyR {st chainable(t_loadTestsFromNamesRR tFalseRtsimple(RRR'((Rs8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyRqs   cOs„d}gtt|jdgƒ|ƒD]\}}|r%|^q%}x:|jD]/\}}|||Ž}|}|j|ƒqMW|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!tzipR RRR%(RRRtresulttstatictaRR'((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyR‚s(cos™x’|jD]‡\}}d}y8|||Ž}|dk rSx|D] }|VqAWnWq ttfk rp‚q tjƒ}t|ŒVq q Xq WdS(sFCall all plugins, yielding each item in each non-None result. N(RR!tKeyboardInterruptt SystemExittsystexc_infoR(RRRRR'R2trtexc((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyR+’s    cOs=x6|jD]+\}}|||Ž}|dk r |Sq WdS(s?Call all plugins, returning the first non-None result. N(RR!(RRRRR'R2((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyR/Łs cCsmg}xZ|jD]O\}}||d|ƒ}|dk r|\}}|r_|j|ƒq_qqW||fS(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. RN(RR!textend(RtnamesRtsuiteRR'R2t suite_part((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyR-Ťs  N(Rt __module__t__doc__RR RRRRRR+R/R!R-(((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyR Ns     t NoPluginscBsneZdZeZd„Zd„Zd„Zd„Zd„Z d„Z d„Z d„Z d „Z d „ZRS( s(Null Plugin manager that has no plugins.cCsd|_|_dS(N((t_pluginsR(R((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyRžscCsdS(N(((R((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyt__iter__ÁscOsdS(N((Rtargstkwds((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyt _doNothingÄscOsdS(N(((RRDRE((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyt_emptyIteratorÇscCs6t|j|ƒ}t|dtƒr+|jS|jSdS(NR)(R R R.RGRF(RRR((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyt __getattr__ĘscCs tƒ‚dS(N(tNotImplementedError(Rtplug((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyRŃscCs tƒ‚dS(N(RI(RR((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyt addPluginsÔscCsdS(N((Rtoptionstconfig((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyt configure×scCsdS(N((R((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyt loadPluginsÚscCsdS(N((R((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pytsortÝs(RR?R@RR RRCRFRGRHRRKRNRORP(((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyRAťs         cBseZdZeZd d d„Zd„Zd„Zd„Z ddd„Z d„Z d„Z d„Z d „Zd „Zeeed d ƒZRS(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. cCsMg|_d|_i|_|r1|j|ƒn|dk rI||_ndS(N((RBt _extrapluginst_proxiesRKR!t proxyClass(RRRS((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyRďs    cCsIy|j|SWn3tk rD|j||jƒ}||j|Proxy for 0.9 plugins, adapts 0.10 calls to 0.9 standard. cCs ||_dS(N(R&(RR&((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyR8scCs|jj||ƒdS(N(R&t add_options(Rtparsertenv((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyRL;sc CsÍt|jdƒsdSddlm}m}|\}}}t||ƒrst|jdƒs`dS|jj|jƒSt||ƒrŤt|jdƒs˜dS|jj|jƒS|j }|jj |j||ƒS(NtaddErrori˙˙˙˙(tSkipTesttDeprecatedTesttaddSkipt addDeprecated( thasattrR&tnose.excRlRmt issubclassRnttestRotcapturedOutputRk( RRsterrRlRmtectevttbtcapt((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyRk>s cCs&t|jdƒr"|jj|ƒSdS(NtloadTestsFromPath(RpR&Rz(Rtfilename((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pytloadTestsFromFilePscCsDt|jdƒsdS|j}|j}|jj|j|||ƒS(Nt addFailure(RpR&RtttbinfoR}Rs(RRsRuRyR~((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyR}Ts   cCs9t|jdƒsdS|j}|jj|j|ƒdS(Nt addSuccess(RpR&RtRRs(RRsRy((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyR\s cCs)t|jdƒsdS|jj|jƒS(Nt startTest(RpR&R€Rs(RRs((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyR€bscCs)t|jdƒsdS|jj|jƒS(NtstopTest(RpR&RRs(RRs((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyRgscCst|j|ƒS(N(R R&(Rtval((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyRHls(RR?R@RtostenvironRLRkR|R}RR€RRH(((s8/sys/lib/python2.7/site-packages/nose/plugins/manager.pyRg5s       cBs)eZdZddeffZd„ZRS(shPlugin manager that loads plugins from the `nose.plugins` and `nose.plugins.0.10` entry points. snose.plugins.0.10s nose.pluginsc Csddlm}i}xę|jD]ß\}}xĐ||ƒD]Â}|j|krTq9nt||j2sB       m&T;%