Feb 2010

Currently in wxPython, pubsub is a module in wx.lib. New pubsub is a package that includes the old pubsub module, which gets used only if requested explicitely by user, otherwise a more sophisticated API is provided. But if new pubsub is to be included in next version of wxPython, "from wx.lib.pubsub import ..." must continue to work so it should default to the old pubsub module API within the new pubsub package. 

I expect that in a yet later version of wxPython, after the new pubsub has been in use for a while, that wx.lib.pubsub will not be made to default to the old API. Users of wx.lib.pubsub will have to be warned of this and they should either add a line like "from wx.lib.pubsub import setupv1" in anticipation of that future update, OR, they should fix a few of their method calls and make use of "from wx.lib.pubsub import setuparg1", which will use the new pubsub API but in the same messaging "format" as used by the old (legacy) pubsub in current wxPython. 

I put in some code to achieve this, it was mostly proof of concept, but needs to be made more robust, as there are at least 8 cases possible (see below). 


Case 1: auto-load not found; then the following imports should lead to the following assertions being successful:

    from pubsub import pub
    assert pub.PUBSUB_VERSION == 3
    
    OR 
    
    from pubsub import setupkwargs
    from pubsub import pub
    assert pub.PUBSUB_VERSION == 3
 
    OR 
    
    from pubsub import setuparg1
    from pubsub import pub       # pubsub3 module
    assert pub.PUBSUB_VERSION == 3
    
    OR 

    # pubsub has to load pub even if not asked by user 
    # because Publisher must NOT be a module but a singleton
    from pubsub import setupv1
    from pubsub import pub       # pubsub1 module OR
    from pubsub import Publisher # singleton from pub
    assert pub.PUBSUB_VERSION == 1
    
    
case 2: the auto-load is requested; assumption: no one but wxPython users would need this, so 

    # pubsub has to load pub even if not asked by user 
    # because Publisher must NOT be a module but a singleton

    from wx.lib.pubsub import pub         # pubsub1 module OR 
    from wx.lib.pubsub import Publisher   # singleton from pubsub1
    assert pub.PUBSUB_VERSION == 1
    
    OR 
    
    from wx.lib.pubsub import setupkwargs 
    # setupkwargs must also remove 'pub' and 'Publisher' from 'pubsub'
    from wx.lib.pubsub import pub         # pubsub3 module
    assert pub.PUBSUB_VERSION == 3
 
    OR 
    
    from wx.lib.pubsub import setuparg1
    # setuparg1 must also remove 'pub' and 'Publisher' from 'pubsub'
    from wx.lib.pubsub import pub         # pubsub3 module
    assert pub.PUBSUB_VERSION == 3
    
    OR 

    from wx.lib.pubsub import setupv1     # does nothing (already loaded by autoload)
    from wx.lib.pubsub import pub         # pubsub1 module OR
    from wx.lib.pubsub import Publisher   # singleton from pubsub1
    assert pub.PUBSUB_VERSION == 1


No other cases are supported (such as, importing pub and then changing version and re-importing pub). 


Conclusions: 

* Looks like setupv1 can be called manually or by auto to do whole job 
  of making 'pub' and 'Publisher' available from pubsub

* Setupv1 must check if it has already been "run" and do nothing if so

* The other setup files have to undo the effect of setupv1 if it has run; 
  they could check to see if setupv1 already run

* If pub *is* the actual module to load (pubsub1, 2 or 3) then the 
  symbols from current pubsub123 modules don't need to copied into pub; 
  would be good since a bit unclean solution right now (aka hack)

* Could put pubsub123 in subfolders in pubsub and modify pubsub module 
  search path according to chosen version 

* But none of the setup modules know how to find pubsub/__init__ so trick 
  is needed; both pubsub/__init__.py and the setup files put data in 
  pubsubconf; the former puts its dict 
  so the pubsubconf module can modify it (add/remove pub/Publisher when 
  setupv1 must be done/undone)

* If pubsub data in pubsub.pubsubconf then we have a module circular 
  reference (ie dict will point to pubsubconf as a module variable, 
  and pubsubconf will point to dict as a module variable). So when 
  pub loaded from pubsub, it should "cleanup" pubsubconf to break 
  circular ref (not abs necessary but always good to avoid), this is ok 
  since pubsubconf will not be used after pub imported by pubsub

* Since in principle the user could also have a non-wx pubsub installed
  on their system, pubsub cannot assume that it is the only one in the 
  system, or presume to know what package it has been installed in (such 
  as wx.lib). But since user may need to import setupkwargs or setuparg1
  after auto-load of pubsub1 as pub, then setupv1 must be able to remove 
  pubsub1 and Publisher from sys.modules and from pubsub module. 



Oliver
