[TIP] Coming changes to unittest2 plugins

Michael Foord fuzzyman at voidspace.org.uk
Mon Sep 27 08:18:49 PDT 2010


  On 27/09/2010 15:33, Michael Foord wrote:
>  Hello all,
>
> After recent conversations with Holger Krekel and Robert Collins I 
> have decided to make a fairly major internal changes to unittest2 
> plugins. I'm getting rid of all global state, which includes the 
> global hooks that are currently the core of the extension machinery.
>
> Getting rid of global state always *sounds goood*, but it isn't 
> without API consequences. With no global access to the hooks set it 
> needs to be passed down and 'made available' to the runner, loader, 
> suites and all test cases. This is annoying, but probably still better 
> than global state. Removing the global state makes *testing* the 
> plugin machinery massively easier however... It also allows multiple 
> different plugin configurations within the same process (which is nice 
> but only actually useful for a small set of use cases).
>
> This refactoring also means changing the way plugins are initialized, 
> merely importing the plugin is no longer enough (the metaclass goes - 
> which makes me sad but is probably also a good thing). I expect to 
> change configuration to look like:
>
> package.module:Class
>
> I hate the colon but it is how entry points do it *anyway*. Function 
> based plugins will still be possible, but will *require* an 
> initialization function that takes the hook set.

Ok, so after further discussions (mainly being harangued - entirely 
justifiably of course - on IRC by exarkun) this has changed slightly. I 
will use dot format as I'm not the only one who hates that colon and 
this will also be the format used by distutils2.

Each config entry must refer to a callable object, which can be a Plugin 
class of course, which will be called with the current 
plugin-configuration-context-manager-object-thingy-whatever. This object 
provides access to the hooks, plugin configuration and messaging API for 
the current test run.

This means that implementers of plugins inheriting from Plugin will need 
to write their __init__ methods taking a single argument (plus self of 
course), but overall it is still a nice simple way of specifying 
plugins. (It also means you should avoid global state within plugins.)

Depending on how much time I get to work on it this change will probably 
take another couple of weeks. Sorry. :-)

The next debate, for when this work is done, is whether the plugin API 
should *enforce* (where it can) compatibility with distributed 
testing... A multi-process (but not network distributed) test runner 
will be my proof of concept for this. This will require plugins to be 
able to know whether they are running in the master process or in a 
slave process. Fun. :-) (Particularly thanks to Holger for advice on 
this issue. We'll see how it works out in practise though.)

All the best,

Michael

>
> With no global state we also can't have global "add command line 
> option" functions and we can't have a global config structure. These 
> need to be associated with a plugin-configuration-context (or whatever 
> I call it - currently PluginManager which I also hate). The command 
> line option functions and access to the configuration will likely 
> become methods on the Plugin class, so actually a bit easier to use - 
> but another change.
>
> I'm part way through this. (In my local repo *everything* is broken.) 
> I'll be sure to make the announcement when it is done...
>
> The nicest part of the change is that the really horrible internal 
> tangle of the messaging API (the only part of the plugin system I was 
> really unhappy with) can be cleaned up, so definitely a nett win.
>
> All the best,
>
> Michael Foord
>


-- 
http://www.ironpythoninaction.com/
http://www.voidspace.org.uk/blog

READ CAREFULLY. By accepting and reading this email you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies (”BOGUS AGREEMENTS”) that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.





More information about the testing-in-python mailing list