Suggestions while developing application that uses pubsub:
Design your application into independent modules or subpackages that don’t import one another
Define basic topics exist in the application: ‘user’ (events from user interface), ‘filesystem’ (events from local filesystem), etc. These are your messaging topics. You may find it useful to use printTreeDocs from pubsub.utils.
Use Topic Definition Providers as eary as possible. Use pub.exportTopicTreeSpec() if already have partial implementation, and pub.addTopicDefnProvider() and pub.setTopicUnspecifiedFatal().
Start all listener functions and methods with pubOn, for instance def psOnCloseDocument()
Define some data for each message type, and which data are optional/required
Implement your modules
- Subscribe listeners with appropriate signature (according to data for each topic/event type)
- Send messages with appropriate data
- Handle messages in listeners, without making any assumptions about sender or order of receipt
Testing: import your control modules and generate messages to exercise them.
You can see a very informative view of an application before and after incorporatng pubsub, at Steven Sproat’s dev site (click “expand all” and “show diffs side-by-side”). Steven says:
You can see how I removed some GUI logic from the Canvas class (a child of the GUI) and placed “controller” functions into my GUI that subscribed to pubsub topics and delegates to the appropriate classes.
Pubsub supports two ways to send messages and transmit the data to listeners:
The arg1 was the first and only protocol of pubsub. It was difficult to specify what data was allowed in a topic, thus requiring the developer to put in verification code in the listener, having to deal with exceptions resulting from mismatches in field names, etc, it worked but for larger applications it involved more effort than seemed necessary.
The kwargs protocol was then designed: it allows the sender to name each datum, and the recipient (listener) to be checked via introspection at subscription time for its capability to receive the data. It also made it easier to document the message data. The protocol was implemented as pubsub version 3.
Due to the significant differences between the two, and the goal of kwargs being to allow for better runtime checks by pubsub, only one protocol can be active when importing pubsub: the application must choose either kwargs or arg1. The default is the kwargs protocol. In order to use arg1, the application must import pubsub.setuparg1.
The only reason for using the arg1 protocol is to avoid upgrading an application that was developed when this protocol was the only choice. Any new application should use the default kwargs protocol.
As pubsub matured, its API went through 2 dramatic changes:
The API version is different from the PyPubSub release version:
API v1 was given secondary status as of pypubsub v3.0. It was supported until the end of pypubsub v3.1.x by importing pubsub.setupv1, but deprecated. Starting from pypubsub version 3.2, the v1 API (and hence pubsub.setupv1) was no longer available as part of pubsub.
The version 1 API was the default in wx.lib.pubsub until pubsub version 3.1.0 (wx.lib.pubsub did the setupv1 import automatically). After that, it was deprecated. Eventually the default in wx.lib.pubsub was the v3 API with kwargs protocol; users had to manually import setuparg1 once in their application if they did not want to port their application to use the kwargs protocol. If this was a problem, they could continue to use setupv1. WxPython Phoenix will use pubsub 3.3, with the default being the kwargs protocol, and no support for v1 API.
API v2: <fill this out>
API v3: Starting with pypubsub version 3.3, the arg1 messaging protocol is officially deprecated.
Listener uses **kwargs then will be given all data of message, not just portion specific to registration topic. For example,
>>> def listener(**kwargs): pass >>> pub.subscribe(listener, 'topic') >>> pub.sendMessage('topic', arg1=1, arg2=2)
Then listener will receive arg1 and arg2.