From db399def0e2edc2444e5d2fee8944ec3d0b8553b Mon Sep 17 00:00:00 2001 From: Oliver Schoenborn Date: Sun, 29 Dec 2013 20:57:01 +0000 Subject: [PATCH] Updated for latest pubsub release v3.3.0rc1 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@75492 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wx/lib/pubsub/README.txt | 28 +--- wx/lib/pubsub/README_WxPython.txt | 22 +++ wx/lib/pubsub/__init__.py | 6 +- wx/lib/pubsub/core/topicobj.py | 12 +- wx/lib/pubsub/examples/advanced/README.txt | 15 ++ .../examples/advanced/arg1_listeners.py | 39 +++++ .../pubsub/examples/advanced/arg1_senders.py | 19 +++ .../pubsub/examples/advanced/arg1_topics.py | 32 ++++ .../examples/advanced/arg1_topics_out.py | 32 ++++ wx/lib/pubsub/examples/advanced/exchandle.py | 21 +++ .../examples/advanced/kwargs_listeners.py | 37 +++++ .../examples/advanced/kwargs_senders.py | 19 +++ .../pubsub/examples/advanced/kwargs_topics.py | 53 ++++++ .../examples/advanced/kwargs_topics_out.py | 53 ++++++ wx/lib/pubsub/examples/advanced/main_arg1.py | 51 ++++++ .../pubsub/examples/advanced/main_kwargs.py | 50 ++++++ .../pubsub/examples/advanced/notifhandle.py | 30 ++++ wx/lib/pubsub/examples/basic_arg1/README.txt | 17 ++ .../examples/basic_arg1/console_listeners.py | 41 +++++ .../examples/basic_arg1/console_main.py | 23 +++ .../examples/basic_arg1/console_senders.py | 22 +++ wx/lib/pubsub/examples/basic_arg1/wx_main.py | 107 ++++++++++++ .../pubsub/examples/basic_kwargs/README.txt | 13 ++ .../basic_kwargs/console_listeners.py | 38 +++++ .../examples/basic_kwargs/console_main.py | 22 +++ .../examples/basic_kwargs/console_senders.py | 22 +++ .../pubsub/examples/basic_kwargs/wx_main.py | 74 +++++++++ .../pubsub/examples/basic_kwargs/wx_win1.py | 33 ++++ .../pubsub/examples/basic_kwargs/wx_win2.py | 38 +++++ wx/lib/pubsub/examples/multithreadloop.py | 130 +++++++++++++++ wx/lib/pubsub/examples/runall.bat | 86 ++++++++++ wx/lib/pubsub/examples/runall_regression.txt | 152 ++++++++++++++++++ wx/lib/pubsub/utils/intraimport.py | 61 ------- wx/lib/pubsub/utils/topictreeprinter.py | 3 +- 34 files changed, 1313 insertions(+), 88 deletions(-) create mode 100644 wx/lib/pubsub/README_WxPython.txt create mode 100644 wx/lib/pubsub/examples/advanced/README.txt create mode 100644 wx/lib/pubsub/examples/advanced/arg1_listeners.py create mode 100644 wx/lib/pubsub/examples/advanced/arg1_senders.py create mode 100644 wx/lib/pubsub/examples/advanced/arg1_topics.py create mode 100644 wx/lib/pubsub/examples/advanced/arg1_topics_out.py create mode 100644 wx/lib/pubsub/examples/advanced/exchandle.py create mode 100644 wx/lib/pubsub/examples/advanced/kwargs_listeners.py create mode 100644 wx/lib/pubsub/examples/advanced/kwargs_senders.py create mode 100644 wx/lib/pubsub/examples/advanced/kwargs_topics.py create mode 100644 wx/lib/pubsub/examples/advanced/kwargs_topics_out.py create mode 100644 wx/lib/pubsub/examples/advanced/main_arg1.py create mode 100644 wx/lib/pubsub/examples/advanced/main_kwargs.py create mode 100644 wx/lib/pubsub/examples/advanced/notifhandle.py create mode 100644 wx/lib/pubsub/examples/basic_arg1/README.txt create mode 100644 wx/lib/pubsub/examples/basic_arg1/console_listeners.py create mode 100644 wx/lib/pubsub/examples/basic_arg1/console_main.py create mode 100644 wx/lib/pubsub/examples/basic_arg1/console_senders.py create mode 100644 wx/lib/pubsub/examples/basic_arg1/wx_main.py create mode 100644 wx/lib/pubsub/examples/basic_kwargs/README.txt create mode 100644 wx/lib/pubsub/examples/basic_kwargs/console_listeners.py create mode 100644 wx/lib/pubsub/examples/basic_kwargs/console_main.py create mode 100644 wx/lib/pubsub/examples/basic_kwargs/console_senders.py create mode 100644 wx/lib/pubsub/examples/basic_kwargs/wx_main.py create mode 100644 wx/lib/pubsub/examples/basic_kwargs/wx_win1.py create mode 100644 wx/lib/pubsub/examples/basic_kwargs/wx_win2.py create mode 100644 wx/lib/pubsub/examples/multithreadloop.py create mode 100644 wx/lib/pubsub/examples/runall.bat create mode 100644 wx/lib/pubsub/examples/runall_regression.txt delete mode 100644 wx/lib/pubsub/utils/intraimport.py diff --git a/wx/lib/pubsub/README.txt b/wx/lib/pubsub/README.txt index e065eee1..99de95ff 100644 --- a/wx/lib/pubsub/README.txt +++ b/wx/lib/pubsub/README.txt @@ -1,21 +1,9 @@ -PyPubSub provides a publish - subscribe API that facilitates the development of -event-based (also known as message-based) applications. PyPubSub supports sending and -receiving messages between objects of an application, as well as a variety of -advanced features that facilitate debugging and maintaining topics and messages -in larger applications. +Release Notes +============= -See the PyPubSub website (http://pubsub.sourceforge.net/) for -further details, and to download. - -In order for easy_install to find the correct download links, they are listed here: - -* `Windows Installer `_ -* `Egg for Python 2.7 `_ -* `Egg for Python 2.6 `_ -* `Egg for Python 2.5 `_ -* `Egg for Python 2.4 `_ -* `Zip (source) `_ - -Note: "easy_install pypubsub" will install the egg, which is a zip file, whereas -"easy_install -Z pypubsub" will extract the egg contents to a folder; this option will -make importing pubsub much faster. \ No newline at end of file +* cleanup low-level API: exception classes, moved some out of pub module that did not + belong there (clutter), move couple modules, +* completed the reference documentation +* support installation via pip +* follow some guidelines in some PEPs such as PEP 396 and PEP 8 +* support Python 2.6, 2.7, and 3.2 to 3.4a4 but drop support for Python <= 2.5 diff --git a/wx/lib/pubsub/README_WxPython.txt b/wx/lib/pubsub/README_WxPython.txt new file mode 100644 index 00000000..8fcf8dd7 --- /dev/null +++ b/wx/lib/pubsub/README_WxPython.txt @@ -0,0 +1,22 @@ +# this file gets copied to wx/lib/pubsub folder when release to wxPython + +For wxPython users: + +The code in this wx/lib/pubsub folder is taken verbatim from the PyPubSub +project on SourceForge.net. Pubsub originated as a wxPython lib, but it is now +a standalone project on SourceForge. It is included as part of wxPython +distribution for convenience to wxPython users, but pubsub can also be installed +standalone (see installation notes at http://pypubsub.sourceforge.net), or you +can also overwrite the version in this folder with the standalone version or +put an SVN checkout of pubsub in this folder, etc. + +Note that the source distribution on SF.net tends to be updated more often than +the copy in wx/lib/pubsub. If you wish to install pubsub standalone, there are +instructions on the Install page of http://pypubsub.sourceforge.net. + +There is extensive documentation for pubsub at http://pypubsub.sourceforge.net, +and some examples are in wx/lib/pubsub/examples. The WxPython wiki also discusses +usage of pubsub in wxPython. + +Oliver Schoenborn +December 2013 diff --git a/wx/lib/pubsub/__init__.py b/wx/lib/pubsub/__init__.py index 703d2739..bace45fc 100644 --- a/wx/lib/pubsub/__init__.py +++ b/wx/lib/pubsub/__init__.py @@ -5,15 +5,15 @@ Pubsub package initialization. :license: BSD, see LICENSE_BSD_Simple.txt for details. Last change info: -- $Date: 2013-11-17 13:09:24 -0500 (Sun, 17 Nov 2013) $ -- $Revision: 340 $ +- $Date: 2013-12-22 11:36:16 -0500 (Sun, 22 Dec 2013) $ +- $Revision: 344 $ """ LAST_RELEASE_DATE = "2013-09-15" LAST_RELEASE_VER = "3.2.1b" -__version__ = "3.3.0dev1" +__version__ = "3.3.0rc1" __all__ = [ 'pub', diff --git a/wx/lib/pubsub/core/topicobj.py b/wx/lib/pubsub/core/topicobj.py index 72418686..716fa21e 100644 --- a/wx/lib/pubsub/core/topicobj.py +++ b/wx/lib/pubsub/core/topicobj.py @@ -260,7 +260,13 @@ class Topic(PublisherMixin): return bool(self.__listeners) def getListeners(self): - """Get an iterator of listeners subscribed to this topic.""" + """Get a copy of list of listeners subscribed to this topic. Safe to iterate over while listeners + get un/subscribed from this topics (such as while sending a message).""" + return py2and3.keys(self.__listeners) + + def getListenersIter(self): + """Get an iterator over listeners subscribed to this topic. Do not use if listeners can be + un/subscribed while iterating. """ return py2and3.iterkeys(self.__listeners) def validate(self, listener): @@ -382,7 +388,9 @@ class Topic(PublisherMixin): self._treeConfig.notificationMgr.notifySend('post', self) def __sendMessage(self, data, topicObj, iterState): - # now send message data to each listener for current topic: + # now send message data to each listener for current topic; + # use list of listeners rather than iterator, so that if listeners added/removed during + # send loop, no runtime exception: for listener in topicObj.getListeners(): try: self._treeConfig.notificationMgr.notifySend('in', topicObj, pubListener=listener) diff --git a/wx/lib/pubsub/examples/advanced/README.txt b/wx/lib/pubsub/examples/advanced/README.txt new file mode 100644 index 00000000..1ef31654 --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/README.txt @@ -0,0 +1,15 @@ +These two examples demonstrate a more advanced use of pubsub. One of the +examples uses the *kwargs* messaging protocol, the other uses the *arg1* +messaging protocol. There are two examples that can be run from this folder: + +**main_kwargs.py**: advanced example that shows other capabilities of + pubsub such as pubsub notification and listener exception + handling, in the 'kwargs' messaging protocol. All modules that + start with 'kwargs\_' are used, as well as some modules that are + independent of protocol and are shared with the arg1_main + example. + +**main_arg1.py**: same as kwargs_main but using the 'arg1' protocol. + All modules that start with 'kwargs\_' are used, as well as some + modules that are independent of protocol and are shared with the + kwargs_main example. \ No newline at end of file diff --git a/wx/lib/pubsub/examples/advanced/arg1_listeners.py b/wx/lib/pubsub/examples/advanced/arg1_listeners.py new file mode 100644 index 00000000..4ecf15f9 --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/arg1_listeners.py @@ -0,0 +1,39 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. +""" + +from pubsub import pub +from pubsub.py2and3 import print_ + +# ------------ create some listeners -------------- + +class Listener: + def onTopic11(self, msg): + data = msg.data + print_('Method Listener.onTopic11 received: ', repr(data)) + + def onTopic1(self, msg, topic=pub.AUTO_TOPIC): + info = 'Method Listener.onTopic1 received "%s" message: %s' + print_(info % (topic.getName(), repr(msg.data))) + + def __call__(self, msg): + print_('Listener instance received: ', msg.data) + +listenerObj = Listener() + + +def listenerFn(msg): + data = msg.data + print_('Function listenerFn received: ', repr(data)) + +# ------------ subscribe listeners ------------------ + +pub.subscribe(listenerObj, pub.ALL_TOPICS) # via its __call__ + +pub.subscribe(listenerFn, 'topic_1.subtopic_11') +pub.subscribe(listenerObj.onTopic11, 'topic_1.subtopic_11') + +pub.subscribe(listenerObj.onTopic1, 'topic_1') + diff --git a/wx/lib/pubsub/examples/advanced/arg1_senders.py b/wx/lib/pubsub/examples/advanced/arg1_senders.py new file mode 100644 index 00000000..d59a2998 --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/arg1_senders.py @@ -0,0 +1,19 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. + +""" + +from pubsub import pub + + +def doSomething1(): + pub.sendMessage('topic_1.subtopic_11', ('message for subtopic 11', 'other message', 123)) + + +def doSomething2(): + pub.sendMessage('topic_1', 'message for topic 1') + pub.sendMessage('topic_2.subtopic_21', 'message for subtopic 2') + + diff --git a/wx/lib/pubsub/examples/advanced/arg1_topics.py b/wx/lib/pubsub/examples/advanced/arg1_topics.py new file mode 100644 index 00000000..ecadb014 --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/arg1_topics.py @@ -0,0 +1,32 @@ +# Automatically generated by TopicTreeSpecPrinter(**kwargs). +# The kwargs were: +# - fileObj: file +# - width: 70 +# - treeDoc: None +# - indentStep: 4 +# - footer: '# End of topic tree definition. Note that application may l...' + + +class topic_1: + """ + Explain when topic_1 should be used + """ + + class subtopic_11: + """ + Explain when subtopic_11 should be used + """ + +class topic_2: + """ + Some something useful about topic2 + """ + + class subtopic_21: + """ + description for subtopic 21 + """ + + +# End of topic tree definition. Note that application may load +# more than one definitions provider. diff --git a/wx/lib/pubsub/examples/advanced/arg1_topics_out.py b/wx/lib/pubsub/examples/advanced/arg1_topics_out.py new file mode 100644 index 00000000..5102fc7e --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/arg1_topics_out.py @@ -0,0 +1,32 @@ +# Automatically generated by TopicTreeSpecPrinter(**kwargs). +# The kwargs were: +# - fileObj: file +# - footer: '# End of topic tree definition. Note that application may l...' +# - indentStep: 4 +# - treeDoc: None +# - width: 70 + + +class topic_1: + """ + Explain when topic_1 should be used + """ + + class subtopic_11: + """ + Explain when subtopic_11 should be used + """ + +class topic_2: + """ + Some something useful about topic2 + """ + + class subtopic_21: + """ + description for subtopic 21 + """ + + +# End of topic tree definition. Note that application may load +# more than one definitions provider. diff --git a/wx/lib/pubsub/examples/advanced/exchandle.py b/wx/lib/pubsub/examples/advanced/exchandle.py new file mode 100644 index 00000000..9cc5887c --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/exchandle.py @@ -0,0 +1,21 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. +""" + +from pubsub import pub +from pubsub.py2and3 import print_ + + +# create one special notification handler that ignores all except +# one type of notification +class MyPubsubExcHandler(pub.IListenerExcHandler): + + def __call__(self, listenerID): + print_('Exception raised in listener %s during sendMessage()' % listenerID) + print_(TracebackInfo()) + + +pub.setListenerExcHandler( MyPubsubExcHandler() ) + diff --git a/wx/lib/pubsub/examples/advanced/kwargs_listeners.py b/wx/lib/pubsub/examples/advanced/kwargs_listeners.py new file mode 100644 index 00000000..64cce59c --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/kwargs_listeners.py @@ -0,0 +1,37 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. +""" + +from pubsub import pub +from pubsub.py2and3 import print_ + +# ------------ create some listeners -------------- + +class Listener: + def onTopic11(self, msg, msg2, extra=None): + print_('Method Listener.onTopic11 received: ', repr(msg), repr(msg2), repr(extra)) + + def onTopic1(self, msg, topic=pub.AUTO_TOPIC): + info = 'Method Listener.onTopic1 received "%s" message: %s' + print_(info % (topic.getName(), repr(msg))) + + def __call__(self, **kwargs): + print_('Listener instance received: ', kwargs) + +listenerObj = Listener() + + +def listenerFn(msg, msg2, extra=None): + print_('Function listenerFn received: ', repr(msg), repr(msg2), repr(extra)) + +# ------------ subscribe listeners ------------------ + +pub.subscribe(listenerObj, pub.ALL_TOPICS) # via its __call__ + +pub.subscribe(listenerFn, 'topic_1.subtopic_11') +pub.subscribe(listenerObj.onTopic11, 'topic_1.subtopic_11') + +pub.subscribe(listenerObj.onTopic1, 'topic_1') + diff --git a/wx/lib/pubsub/examples/advanced/kwargs_senders.py b/wx/lib/pubsub/examples/advanced/kwargs_senders.py new file mode 100644 index 00000000..69e84405 --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/kwargs_senders.py @@ -0,0 +1,19 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. + +""" + +from pubsub import pub + +def doSomething1(): + pub.sendMessage('topic_1.subtopic_11', + msg='message for subtopic 11', msg2='other message', extra=123) + + +def doSomething2(): + pub.sendMessage('topic_1', msg='message for topic 1') + pub.sendMessage('topic_2.subtopic_21', msg='message for subtopic 2') + + diff --git a/wx/lib/pubsub/examples/advanced/kwargs_topics.py b/wx/lib/pubsub/examples/advanced/kwargs_topics.py new file mode 100644 index 00000000..6dc645bc --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/kwargs_topics.py @@ -0,0 +1,53 @@ +# Automatically generated by TopicTreeSpecPrinter(**kwargs). +# The kwargs were: +# - fileObj: file +# - width: 70 +# - treeDoc: None +# - indentStep: 4 +# - footer: '# End of topic tree definition. Note that application may l...' + + +class topic_1: + """ + Explain when topic_1 should be used + """ + + def msgDataSpec(msg): + """ + - msg: a text string message for recipient + """ + + class subtopic_11: + """ + Explain when subtopic_11 should be used + """ + + def msgDataSpec(msg, msg2, extra=None): + """ + - extra: something optional + - msg2: a text string message #2 for recipient + """ + +class topic_2: + """ + Some something useful about topic2 + """ + + def msgDataSpec(msg=None): + """ + - msg: a text string + """ + + class subtopic_21: + """ + description for subtopic 21 + """ + + def msgDataSpec(msg, arg1=None): + """ + - arg1: UNDOCUMENTED + """ + + +# End of topic tree definition. Note that application may load +# more than one definitions provider. diff --git a/wx/lib/pubsub/examples/advanced/kwargs_topics_out.py b/wx/lib/pubsub/examples/advanced/kwargs_topics_out.py new file mode 100644 index 00000000..9154c4ad --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/kwargs_topics_out.py @@ -0,0 +1,53 @@ +# Automatically generated by TopicTreeSpecPrinter(**kwargs). +# The kwargs were: +# - fileObj: file +# - footer: '# End of topic tree definition. Note that application may l...' +# - indentStep: 4 +# - treeDoc: None +# - width: 70 + + +class topic_1: + """ + Explain when topic_1 should be used + """ + + def msgDataSpec(msg): + """ + - msg: a text string message for recipient + """ + + class subtopic_11: + """ + Explain when subtopic_11 should be used + """ + + def msgDataSpec(msg, msg2, extra=None): + """ + - extra: something optional + - msg2: a text string message #2 for recipient + """ + +class topic_2: + """ + Some something useful about topic2 + """ + + def msgDataSpec(msg=None): + """ + - msg: a text string + """ + + class subtopic_21: + """ + description for subtopic 21 + """ + + def msgDataSpec(msg, arg1=None): + """ + - arg1: UNDOCUMENTED + """ + + +# End of topic tree definition. Note that application may load +# more than one definitions provider. diff --git a/wx/lib/pubsub/examples/advanced/main_arg1.py b/wx/lib/pubsub/examples/advanced/main_arg1.py new file mode 100644 index 00000000..f4fa6f6c --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/main_arg1.py @@ -0,0 +1,51 @@ +""" +Uses topic definition provider for arg1 messaging protocol. Compare with +main_kwargs.py which shows example using kwargs messaging protocol: +kwargs protocol provides for message data self-documentation and more +robustness (pubsub can determine if message data missing or unknown due +to type, etc). + +Experiment by changing arg1_topics.py and looking at the output tree +in arg1_topics_out.py. + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. +""" + +from pubsub import setuparg1 +from pubsub import pub +from pubsub.py2and3 import print_ + +import notifhandle +import exchandle + +import arg1_topics + +#***** actual application ********** + +print_('Using "arg1" messaging protocol of pubsub v3') + +try: + print_('------- init ----------') + + pub.addTopicDefnProvider( arg1_topics, pub.TOPIC_TREE_FROM_CLASS ) + pub.setTopicUnspecifiedFatal() + + import arg1_listeners + import arg1_senders as senders + + print_('-----------------------') + senders.doSomething1() + senders.doSomething2() + + print_('------- done ----------') + + print_('Exporting topic tree to', arg1_topics.__name__) + pub.exportTopicTreeSpec('arg1_topics_out') + +except Exception: + import traceback + traceback.print_exc() + print_(pub.exportTopicTreeSpec()) + +print_('------ exiting --------') \ No newline at end of file diff --git a/wx/lib/pubsub/examples/advanced/main_kwargs.py b/wx/lib/pubsub/examples/advanced/main_kwargs.py new file mode 100644 index 00000000..2aab8786 --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/main_kwargs.py @@ -0,0 +1,50 @@ +""" +Uses topic definition provider for kwargs messaging protocol. Compare with +main_arg1.py which shows example using arg1 messaging protocol: +kwargs protocol provides for message data self-documentation and more +robustness (pubsub can determine if message data missing or unknown due +to type, etc). + +Experiment by changing arg1_topics.py and looking at the output tree +in kwargs_topics_out.py. + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. +""" + +from pubsub import pub +from pubsub.py2and3 import print_ + +import notifhandle +import exchandle + +import kwargs_topics + +#***** actual application ********** + +print_('Using "kwargs" messaging protocol of pubsub v3') + +try: + print_('------- init ----------') + + pub.addTopicDefnProvider( kwargs_topics, pub.TOPIC_TREE_FROM_CLASS ) + pub.setTopicUnspecifiedFatal() + + import kwargs_listeners + import kwargs_senders as senders + + print_('-----------------------') + senders.doSomething1() + senders.doSomething2() + + print_('------- done ----------') + + print_('Exporting topic tree to', kwargs_topics.__name__) + pub.exportTopicTreeSpec('kwargs_topics_out') + +except Exception: + import traceback + traceback.print_exc() + print_(pub.exportTopicTreeSpec()) + +print_('------ exiting --------') \ No newline at end of file diff --git a/wx/lib/pubsub/examples/advanced/notifhandle.py b/wx/lib/pubsub/examples/advanced/notifhandle.py new file mode 100644 index 00000000..7fc21b28 --- /dev/null +++ b/wx/lib/pubsub/examples/advanced/notifhandle.py @@ -0,0 +1,30 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. + +""" + +from pubsub import pub +from pubsub.py2and3 import print_ +from pubsub.utils.notification import useNotifyByWriteFile, IgnoreNotificationsMixin + + +# create one special notification handler that ignores all except +# one type of notification +class MyPubsubNotifHandler(IgnoreNotificationsMixin): + + def notifySubscribe(self, pubListener, topicObj, newSub): + newSubMsg = '' + if not newSub: + newSubMsg = ' was already' + msg = 'MyPubsubNotifHandler: listener %s%s subscribed to %s' + print_(msg % (pubListener.name(), newSubMsg, topicObj.getName())) + + +pub.addNotificationHandler( MyPubsubNotifHandler() ) + + +# print_(all notifications to stdout) +import sys +useNotifyByWriteFile(sys.stdout, prefix='NotifyByWriteFile:') diff --git a/wx/lib/pubsub/examples/basic_arg1/README.txt b/wx/lib/pubsub/examples/basic_arg1/README.txt new file mode 100644 index 00000000..8288d96e --- /dev/null +++ b/wx/lib/pubsub/examples/basic_arg1/README.txt @@ -0,0 +1,17 @@ +These two examples demonstrate a simple use of pubsub with the *arg1* +messaging protocol. There are two examples that can be run from this folder: + +**console_main.py**: basic console based, uses the console_senders.py and + console_listeners.py modules, giving basic example of the *arg1* + messaging protocol. + +**wx.py**: basic wxPython GUI application that uses the *arg1* messaging + protocol. Note that it imports pubsub from + wxPython's wx.lib package. Therefore you must have (a copy of) + pubsub installed there for this example to work (pubsub can be + installed in multiple places independently and they will all work + without interfering with each other). + + Note that this example is copied almost + verbatim from the wxPython wiki site and is probably not a + good model of how an application should be structured. \ No newline at end of file diff --git a/wx/lib/pubsub/examples/basic_arg1/console_listeners.py b/wx/lib/pubsub/examples/basic_arg1/console_listeners.py new file mode 100644 index 00000000..1fba52d8 --- /dev/null +++ b/wx/lib/pubsub/examples/basic_arg1/console_listeners.py @@ -0,0 +1,41 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. + +""" + +from pubsub import pub +from pubsub.py2and3 import print_ + +# ------------ create some listeners -------------- + +class Listener: + def onTopic11(self, msg): + msg, extra = msg.data + print_('Method Listener.onTopic11 received: ', repr(msg), repr(extra)) + + def onTopic1(self, msg, topic=pub.AUTO_TOPIC): + msg = msg.data[0] + info = 'Method Listener.onTopic1 received "%s" message: %s' + print_(info % (topic.getName(), repr(msg))) + + def __call__(self, msg): + print_('Listener instance received: ', repr(msg)) + +listenerObj = Listener() + + +def listenerFn(msg): + msg, extra = msg.data + print_('Function listenerFn received: ', repr(msg), repr(extra)) + +# ------------ subscribe listeners ------------------ + +pub.subscribe(listenerObj, pub.ALL_TOPICS) # via its __call__ + +pub.subscribe(listenerFn, 'topic1.subtopic11') +pub.subscribe(listenerObj.onTopic11, 'topic1.subtopic11') + +pub.subscribe(listenerObj.onTopic1, 'topic1') + diff --git a/wx/lib/pubsub/examples/basic_arg1/console_main.py b/wx/lib/pubsub/examples/basic_arg1/console_main.py new file mode 100644 index 00000000..9d559e69 --- /dev/null +++ b/wx/lib/pubsub/examples/basic_arg1/console_main.py @@ -0,0 +1,23 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. + +""" + +from pubsub import setuparg1 +from pubsub.py2and3 import print_ + +import console_senders as senders +import console_listeners + + +def run(): + print_('Using "arg1" messaging protocol of pubsub v3') + + senders.doSomething1() + senders.doSomething2() + + +if __name__ == '__main__': + run() diff --git a/wx/lib/pubsub/examples/basic_arg1/console_senders.py b/wx/lib/pubsub/examples/basic_arg1/console_senders.py new file mode 100644 index 00000000..4f12c7c7 --- /dev/null +++ b/wx/lib/pubsub/examples/basic_arg1/console_senders.py @@ -0,0 +1,22 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. + +""" + +from pubsub import pub +from pubsub.py2and3 import print_ + + +def doSomething1(): + print_('--- SENDING topic1.subtopic11 message ---') + pub.sendMessage('topic1.subtopic11', ('message for 11', 123)) + print_('---- SENT topic1.subtopic11 message ----') + +def doSomething2(): + print_('--- SENDING topic1 message ---') + pub.sendMessage('topic1', ('message for 1',) ) + print_('---- SENT topic1 message ----') + + diff --git a/wx/lib/pubsub/examples/basic_arg1/wx_main.py b/wx/lib/pubsub/examples/basic_arg1/wx_main.py new file mode 100644 index 00000000..7bcefbc4 --- /dev/null +++ b/wx/lib/pubsub/examples/basic_arg1/wx_main.py @@ -0,0 +1,107 @@ +""" +Taken from wxPython wiki at http://wiki.wxpython.org/ModelViewController/. +Used to verify that the wx.lib.pubsub can be replaced by pubsub v3 if message +protocol set to "arg1" (as long as only main API functions are used such as +sendMessage and subscribe... a few peripheral ones have changed or been replaced +with more powerful features). + +Notes: +- the imports assume that pubsub package has been + copied to wx.lib, otherwise change them. +- this code is probably not a good example to follow, see instead + basic_kwargs_wx_*.py. + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. +""" + +import wx + +from wx.lib.pubsub import setuparg1 +from wx.lib.pubsub import pub + + +class Model: + def __init__(self): + self.myMoney = 0 + + def addMoney(self, value): + self.myMoney += value + #now tell anyone who cares that the value has been changed + pub.sendMessage("MONEY CHANGED", self.myMoney) + + def removeMoney(self, value): + self.myMoney -= value + #now tell anyone who cares that the value has been changed + pub.sendMessage("MONEY CHANGED", self.myMoney) + + +class View(wx.Frame): + def __init__(self, parent): + wx.Frame.__init__(self, parent, -1, "Main View") + + sizer = wx.BoxSizer(wx.VERTICAL) + text = wx.StaticText(self, -1, "My Money") + ctrl = wx.TextCtrl(self, -1, "") + sizer.Add(text, 0, wx.EXPAND|wx.ALL) + sizer.Add(ctrl, 0, wx.EXPAND|wx.ALL) + + self.moneyCtrl = ctrl + ctrl.SetEditable(False) + self.SetSizer(sizer) + + def SetMoney(self, money): + self.moneyCtrl.SetValue(str(money)) + +class ChangerWidget(wx.Frame): + def __init__(self, parent): + wx.Frame.__init__(self, parent, -1, "Main View") + + sizer = wx.BoxSizer(wx.VERTICAL) + self.add = wx.Button(self, -1, "Add Money") + self.remove = wx.Button(self, -1, "Remove Money") + sizer.Add(self.add, 0, wx.EXPAND|wx.ALL) + sizer.Add(self.remove, 0, wx.EXPAND|wx.ALL) + self.SetSizer(sizer) + +class Controller: + def __init__(self, app): + self.model = Model() + + #set up the first frame which displays the current Model value + self.view1 = View(None) + self.view1.SetMoney(self.model.myMoney) + + #set up the second frame which allows the user to modify the Model's value + self.view2 = ChangerWidget(self.view1) + self.view2.add.Bind(wx.EVT_BUTTON, self.AddMoney) + self.view2.remove.Bind(wx.EVT_BUTTON, self.RemoveMoney) + #subscribe to all "MONEY CHANGED" messages from the Model + #to subscribe to ALL messages (topics), omit the second argument below + pub.subscribe(self.MoneyChanged, "MONEY CHANGED") + + self.view1.Show() + self.view2.Show() + + def AddMoney(self, evt): + self.model.addMoney(10) + + def RemoveMoney(self, evt): + self.model.removeMoney(10) + + def MoneyChanged(self, message): + """ + This method is the handler for "MONEY CHANGED" messages, + which pubsub will call as messages are sent from the model. + + We already know the topic is "MONEY CHANGED", but if we + didn't, message.topic would tell us. + """ + self.view1.SetMoney(message.data) + + +if __name__ == "__main__": + app = wx.App() + Controller(app) + app.MainLoop() + \ No newline at end of file diff --git a/wx/lib/pubsub/examples/basic_kwargs/README.txt b/wx/lib/pubsub/examples/basic_kwargs/README.txt new file mode 100644 index 00000000..8a7ad4aa --- /dev/null +++ b/wx/lib/pubsub/examples/basic_kwargs/README.txt @@ -0,0 +1,13 @@ +These two examples demonstrate a simple use of pubsub with the *kwargs* +messaging protocol (default). There are two examples that can be run from +this folder: + +**console_main.py**: basic console based, uses the console_senders.py and + console_listeners.py modules, giving example of the *kwargs* + messaging protocol. + +**wx_main.py**: wxPython GUI application with two windows (win1 and win2) + that exchange data without any reference to the other. This example + looks for pubsub on your system path so default install ok. + + diff --git a/wx/lib/pubsub/examples/basic_kwargs/console_listeners.py b/wx/lib/pubsub/examples/basic_kwargs/console_listeners.py new file mode 100644 index 00000000..901ddf18 --- /dev/null +++ b/wx/lib/pubsub/examples/basic_kwargs/console_listeners.py @@ -0,0 +1,38 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. + +""" + +from pubsub import pub +from pubsub.py2and3 import print_ + +# ------------ create some listeners -------------- + +class Listener: + def onTopic11(self, msg, extra=None): + print_('Method Listener.onTopic11 received: ', repr(msg), repr(extra)) + + def onTopic1(self, msg, topic=pub.AUTO_TOPIC): + info = 'Method Listener.onTopic1 received "%s" message: %s' + print_(info % (topic.getName(), repr(msg))) + + def __call__(self, **kwargs): + print_('Listener instance received: ', kwargs) + +listenerObj = Listener() + + +def listenerFn(msg, extra=None): + print_('Function listenerFn received: ', repr(msg), repr(extra)) + +# ------------ subscribe listeners ------------------ + +pub.subscribe(listenerObj, pub.ALL_TOPICS) # via its __call__ + +pub.subscribe(listenerFn, 'topic1.subtopic11') +pub.subscribe(listenerObj.onTopic11, 'topic1.subtopic11') + +pub.subscribe(listenerObj.onTopic1, 'topic1') + diff --git a/wx/lib/pubsub/examples/basic_kwargs/console_main.py b/wx/lib/pubsub/examples/basic_kwargs/console_main.py new file mode 100644 index 00000000..b792a8fd --- /dev/null +++ b/wx/lib/pubsub/examples/basic_kwargs/console_main.py @@ -0,0 +1,22 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. + +""" + +import console_listeners +import console_senders as senders + +from pubsub.py2and3 import print_ + +def run(): + print_('Using "kwargs" messaging protocol of pubsub v3') + + senders.doSomething1() + senders.doSomething2() + + +if __name__ == '__main__': + run() + \ No newline at end of file diff --git a/wx/lib/pubsub/examples/basic_kwargs/console_senders.py b/wx/lib/pubsub/examples/basic_kwargs/console_senders.py new file mode 100644 index 00000000..a23db203 --- /dev/null +++ b/wx/lib/pubsub/examples/basic_kwargs/console_senders.py @@ -0,0 +1,22 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. + +""" + +from pubsub import pub +from pubsub.py2and3 import print_ + + +def doSomething1(): + print_('--- SENDING topic1.subtopic11 message ---') + pub.sendMessage('topic1.subtopic11', msg='message for 11', extra=123) + print_('---- SENT topic1.subtopic11 message ----') + +def doSomething2(): + print_('--- SENDING topic1 message ---') + pub.sendMessage('topic1', msg='message for 1') + print_('---- SENT topic1 message ----') + + diff --git a/wx/lib/pubsub/examples/basic_kwargs/wx_main.py b/wx/lib/pubsub/examples/basic_kwargs/wx_main.py new file mode 100644 index 00000000..23bc8230 --- /dev/null +++ b/wx/lib/pubsub/examples/basic_kwargs/wx_main.py @@ -0,0 +1,74 @@ +""" +Adapted from wxPython website at http://wiki.wxpython.org/ModelViewController/. + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. +""" + +import wx + +from pubsub import pub +from pubsub.py2and3 import print_ + +print_('pubsub API version', pub.VERSION_API) + +# notification +from pubsub.utils.notification import useNotifyByWriteFile +import sys +useNotifyByWriteFile(sys.stdout) + +# the following two modules don't know about each other yet will +# exchange data via pubsub: +from wx_win1 import View +from wx_win2 import ChangerWidget + + +class Model: + + def __init__(self): + self.myMoney = 0 + + def addMoney(self, value): + self.myMoney += value + #now tell anyone who cares that the value has been changed + pub.sendMessage("money_changed", money=self.myMoney) + + def removeMoney(self, value): + self.myMoney -= value + #now tell anyone who cares that the value has been changed + pub.sendMessage("money_changed", money=self.myMoney) + + +class Controller: + + def __init__(self): + self.model = Model() + + #set up the first frame which displays the current Model value + self.view1 = View() + self.view1.setMoney(self.model.myMoney) + + #set up the second frame which allows the user to modify the Model's value + self.view2 = ChangerWidget() + + self.view1.Show() + self.view2.Show() + + pub.subscribe(self.changeMoney, 'money_changing') + + def changeMoney(self, amount): + if amount >= 0: + self.model.addMoney(amount) + else: + self.model.removeMoney(-amount) + + +if __name__ == "__main__": + app = wx.App() + c = Controller() + sys.stdout = sys.__stdout__ + + print_('---- Starting main event loop ----') + app.MainLoop() + print_('---- Exited main event loop ----') + \ No newline at end of file diff --git a/wx/lib/pubsub/examples/basic_kwargs/wx_win1.py b/wx/lib/pubsub/examples/basic_kwargs/wx_win1.py new file mode 100644 index 00000000..d6ba32a8 --- /dev/null +++ b/wx/lib/pubsub/examples/basic_kwargs/wx_win1.py @@ -0,0 +1,33 @@ +""" + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. + +""" + +import wx +from pubsub import pub + + +class View(wx.Frame): + def __init__(self, parent=None): + wx.Frame.__init__(self, parent, -1, "Main View") + + sizer = wx.BoxSizer(wx.VERTICAL) + text = wx.StaticText(self, -1, "My Money") + ctrl = wx.TextCtrl(self, -1, "") + sizer.Add(text, 0, wx.EXPAND|wx.ALL) + sizer.Add(ctrl, 0, wx.EXPAND|wx.ALL) + + self.moneyCtrl = ctrl + ctrl.SetEditable(False) + self.SetSizer(sizer) + + #subscribe to all "MONEY CHANGED" messages from the Model + #to subscribe to ALL messages (topics), omit the second argument below + pub.subscribe(self.setMoney, "money_changed") + + def setMoney(self, money): + self.moneyCtrl.SetValue(str(money)) + + diff --git a/wx/lib/pubsub/examples/basic_kwargs/wx_win2.py b/wx/lib/pubsub/examples/basic_kwargs/wx_win2.py new file mode 100644 index 00000000..8464f1ac --- /dev/null +++ b/wx/lib/pubsub/examples/basic_kwargs/wx_win2.py @@ -0,0 +1,38 @@ +""" +Widget from which money can be added or removed from account. + +:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. +""" + +import wx +from pubsub import pub +from pubsub.py2and3 import print_ + + +class ChangerWidget(wx.Frame): + + CHANGE = 10 # by how much money changes every time click + + def __init__(self, parent=None): + wx.Frame.__init__(self, parent, -1, "Changer View") + + sizer = wx.BoxSizer(wx.VERTICAL) + self.add = wx.Button(self, -1, "Add Money") + self.remove = wx.Button(self, -1, "Remove Money") + sizer.Add(self.add, 0, wx.EXPAND|wx.ALL) + sizer.Add(self.remove, 0, wx.EXPAND|wx.ALL) + self.SetSizer(sizer) + + self.add.Bind(wx.EVT_BUTTON, self.onAdd) + self.remove.Bind(wx.EVT_BUTTON, self.onRemove) + + def onAdd(self, evt): + print_('-----') + pub.sendMessage("money_changing", amount = self.CHANGE) + + def onRemove(self, evt): + print_('-----') + pub.sendMessage("money_changing", amount = - self.CHANGE) + + diff --git a/wx/lib/pubsub/examples/multithreadloop.py b/wx/lib/pubsub/examples/multithreadloop.py new file mode 100644 index 00000000..874d55c1 --- /dev/null +++ b/wx/lib/pubsub/examples/multithreadloop.py @@ -0,0 +1,130 @@ +""" +This test gives an example of how some computation results from an +auxiliary thread could be 'published' via pubsub in a thread-safe +manner, in a 'gui'-like application, ie an application where the +main thread is in an infinite event loop and supports the callback +of user-defined functions when the gui is idle. + +The worker thread 'work' is to increment a counter +as fast as interpreter can handle. Every so often (every resultStep counts), +the thread stores the count in a synchronized queue, for later retrieval +by the main thread. In parallel to this, the main thread loops forever (or +until user interrupts via keyboard), doing some hypothetical work +(represented by the sleep(1) call) and calling all registered 'idle' +callbacks. The transfer is done by extracting items from the queue and +publishing them via pubsub. + +Oliver Schoenborn +May 2009 + +:copyright: Copyright 2008-2009 by Oliver Schoenborn, all rights reserved. +:license: BSD, see LICENSE.txt for details. + +""" + + +__author__="schoenb" +__date__ ="$31-May-2009 9:11:41 PM$" + +from Queue import Queue +import time +import threading + +from pubsub import pub +from pubsub.py2and3 import print_ + + +resultStep = 1000000 # how many counts for thread "result" to be available + + +def threadObserver(transfers, threadObj, count): + """Listener that listens for data from testTopic. This function + doesn't know where the data comes from (or in what thread it was + generated... but threadObj is the thread in which this + threadObserver is called and should indicate Main thread).""" + + print_(transfers, threadObj, count / resultStep) + +pub.subscribe(threadObserver, 'testTopic') + + +def onIdle(): + """This should be registered with 'gui' to be called when gui is idle + so we get a chance to transfer data from aux thread without blocking + the gui. Ie this function must spend as little time as possible so + 'gui' remains reponsive.""" + thread.transferData() + + +class ParaFunction(threading.Thread): + """ + Represent a function running in a parallel thread. The thread + just increments a counter and puts the counter value on a synchronized + queue every resultStep counts. The content of the queue can be published by + calling transferData(). + """ + + def __init__(self): + threading.Thread.__init__(self) + self.running = False # set to True when thread should stop + self.count = 0 # our workload: keep counting! + self.queue = Queue() # to transfer data to main thread + self.transfer = 0 # count how many transfers occurred + + def run(self): + print_('aux thread started') + self.running = True + while self.running: + self.count += 1 + if self.count % resultStep == 0: + self.queue.put(self.count) + + print_('aux thread done') + + def stop(self): + self.running = False + + def transferData(self): + """Send data from aux thread to main thread. The data was put in + self.queue by the aux thread, and this queue is a Queue.Queue which + is a synchronized queue for inter-thread communication. + Note: This method must be called from main thread.""" + self.transfer += 1 + while not self.queue.empty(): + pub.sendMessage('testTopic', + transfers = self.transfer, + threadObj = threading.currentThread(), + count = self.queue.get()) + + +thread = ParaFunction() + + +def main(): + idleFns = [] # list of functions to call when 'gui' idle + idleFns.append( onIdle ) + + try: + thread.start() + + print_('starting event loop') + eventLoop = True + while eventLoop: + time.sleep(1) # pretend that main thread does other stuff + for idleFn in idleFns: + idleFn() + + except KeyboardInterrupt: + print_('Main interrupted, stopping aux thread') + thread.stop() + + except Exception, exc: + from pubsub import py2and3 + exc = py2and3.getexcobj() + print_(exc) + print_('Exception, stopping aux thread') + thread.stop() + + +main() + diff --git a/wx/lib/pubsub/examples/runall.bat b/wx/lib/pubsub/examples/runall.bat new file mode 100644 index 00000000..99dccf8c --- /dev/null +++ b/wx/lib/pubsub/examples/runall.bat @@ -0,0 +1,86 @@ +echo off + +rem This script runs all examples. This should be mostly for using the +rem examples as regression tests (after all tests have passed in tests +rem folder). +rem One command line argument is required, the python version number to +rem use, no dots: 24 for 2.4, 30 for 3.0, etc. +rem +rem (C) Oliver Schoenborn 2009 + +set PY_VER=%1 +IF "%1" EQU "" ( + SET PY_VER=26 + echo Will use Python 2.6. To use other, put version ID as command line arg + echo Example: for Python 2.7 put 27, for 3.0 put 30, etc. +) + +set PYTHON_EXE=python +echo python exe is %PYTHON_EXE% + +echo. +echo. +echo ######################## basic - kwargs - console ######################### +echo. + +pushd basic_kwargs +%PYTHON_EXE% console_main.py +popd +pause + + +echo. +echo. +echo ######################## basic - kwargs - wx ######################### +echo. + +pushd basic_kwargs +%PYTHON_EXE% wx_main.py +popd +pause + + +echo. +echo. +echo ######################## basic - arg1 - console ######################### +echo. + +pushd basic_arg1 +%PYTHON_EXE% console_main.py +popd +pause + + +echo. +echo. +echo ######################## basic - arg1 - wx ######################### +echo. + +pushd basic_arg1 +%PYTHON_EXE% wx_main.py +popd +pause + + +echo. +echo. +echo ######################## advanced - kwargs - console ######################### +echo. + +pushd advanced +%PYTHON_EXE% main_kwargs.py +popd +pause + + +echo. +echo. +echo ######################## advanced - arg1 - console ######################### +echo. + +pushd advanced +%PYTHON_EXE% main_arg1.py +popd +pause + + diff --git a/wx/lib/pubsub/examples/runall_regression.txt b/wx/lib/pubsub/examples/runall_regression.txt new file mode 100644 index 00000000..083b3b58 --- /dev/null +++ b/wx/lib/pubsub/examples/runall_regression.txt @@ -0,0 +1,152 @@ +Will use Python 2.6. To use other, put version ID as command line arg +Example: for Python 2.7 put 27, for 3.0 put 30, etc. +python exe is python + + +######################## basic - kwargs - console ######################### + +Using "kwargs" messaging protocol of pubsub v3 +--- SENDING topic1.subtopic11 message --- +Method Listener.onTopic11 received: 'message for 11' 123 +Function listenerFn received: 'message for 11' 123 +Method Listener.onTopic1 received "topic1.subtopic11" message: 'message for 11' +Listener instance received: {'msg': 'message for 11', 'extra': 123} +---- SENT topic1.subtopic11 message ---- +--- SENDING topic1 message --- +Method Listener.onTopic1 received "topic1" message: 'message for 1' +Listener instance received: {'msg': 'message for 1'} +---- SENT topic1 message ---- +Press any key to continue . . . + + +######################## basic - kwargs - wx ######################### + +pubsub version 3.1.2.201112.r243 +PUBSUB: New topic "money_changed" created +PUBSUB: Subscribed listener "View.setMoney" to topic "money_changed" +PUBSUB: New topic "money_changing" created +PUBSUB: Subscribed listener "Controller.changeMoney" to topic "money_changing" +---- Starting main event loop ---- +----- +PUBSUB: Start sending message of topic "money_changing" +PUBSUB: Sending message of topic "money_changing" to listener Controller.changeMoney +PUBSUB: Start sending message of topic "money_changed" +PUBSUB: Sending message of topic "money_changed" to listener View.setMoney +PUBSUB: Done sending message of topic "money_changed" +PUBSUB: Done sending message of topic "money_changing" +----- +PUBSUB: Start sending message of topic "money_changing" +PUBSUB: Sending message of topic "money_changing" to listener Controller.changeMoney +PUBSUB: Start sending message of topic "money_changed" +PUBSUB: Sending message of topic "money_changed" to listener View.setMoney +PUBSUB: Done sending message of topic "money_changed" +PUBSUB: Done sending message of topic "money_changing" +---- Exited main event loop ---- +Press any key to continue . . . + + +######################## basic - arg1 - console ######################### + +Using "arg1" messaging protocol of pubsub v3 +--- SENDING topic1.subtopic11 message --- +Function listenerFn received: 'message for 11' 123 +Method Listener.onTopic11 received: 'message for 11' 123 +Method Listener.onTopic1 received "topic1.subtopic11" message: 'message for 11' +Listener instance received: +---- SENT topic1.subtopic11 message ---- +--- SENDING topic1 message --- +Method Listener.onTopic1 received "topic1" message: 'message for 1' +Listener instance received: +---- SENT topic1 message ---- +Press any key to continue . . . + + +######################## basic - arg1 - wx ######################### + +Press any key to continue . . . + + +######################## advanced - kwargs - console ######################### + +Using "kwargs" messaging protocol of pubsub v3 +------- init ---------- +NotifyByWriteFile: New topic "topic_2" created +NotifyByWriteFile: New topic "topic_2.subtopic_21" created +NotifyByWriteFile: New topic "topic_1" created +NotifyByWriteFile: New topic "topic_1.subtopic_11" created +MyPubsubNotifHandler: listener Listener_8304 subscribed to ALL_TOPICS +NotifyByWriteFile: Subscribed listener "Listener" to topic "ALL_TOPICS" +MyPubsubNotifHandler: listener listenerFn_2464 subscribed to topic_1.subtopic_11 +NotifyByWriteFile: Subscribed listener "listenerFn" to topic "topic_1.subtopic_11" +MyPubsubNotifHandler: listener Listener.onTopic11_8736 subscribed to topic_1.subtopic_11 +NotifyByWriteFile: Subscribed listener "Listener.onTopic11" to topic "topic_1.subtopic_11" +MyPubsubNotifHandler: listener Listener.onTopic1_8736 subscribed to topic_1 +NotifyByWriteFile: Subscribed listener "Listener.onTopic1" to topic "topic_1" +----------------------- +NotifyByWriteFile: Start sending message of topic "topic_1.subtopic_11" +NotifyByWriteFile: Sending message of topic "topic_1.subtopic_11" to listener Listener.onTopic11 +Method Listener.onTopic11 received: 'message for subtopic 11' 'other message' 123 +NotifyByWriteFile: Sending message of topic "topic_1.subtopic_11" to listener listenerFn +Function listenerFn received: 'message for subtopic 11' 'other message' 123 +NotifyByWriteFile: Sending message of topic "topic_1" to listener Listener.onTopic1 +Method Listener.onTopic1 received "topic_1.subtopic_11" message: 'message for subtopic 11' +NotifyByWriteFile: Sending message of topic "ALL_TOPICS" to listener Listener +Listener instance received: {'msg': 'message for subtopic 11', 'extra': 123, 'msg2': 'other message'} +NotifyByWriteFile: Done sending message of topic "topic_1.subtopic_11" +NotifyByWriteFile: Start sending message of topic "topic_1" +NotifyByWriteFile: Sending message of topic "topic_1" to listener Listener.onTopic1 +Method Listener.onTopic1 received "topic_1" message: 'message for topic 1' +NotifyByWriteFile: Sending message of topic "ALL_TOPICS" to listener Listener +Listener instance received: {'msg': 'message for topic 1'} +NotifyByWriteFile: Done sending message of topic "topic_1" +NotifyByWriteFile: Start sending message of topic "topic_2.subtopic_21" +NotifyByWriteFile: Sending message of topic "ALL_TOPICS" to listener Listener +Listener instance received: {'msg': 'message for subtopic 2'} +NotifyByWriteFile: Done sending message of topic "topic_2.subtopic_21" +------- done ---------- +Exporting topic tree to kwargs_topics +------ exiting -------- +Press any key to continue . . . + + +######################## advanced - arg1 - console ######################### + +Using "arg1" messaging protocol of pubsub v3 +------- init ---------- +NotifyByWriteFile: New topic "topic_2" created +NotifyByWriteFile: New topic "topic_2.subtopic_21" created +NotifyByWriteFile: New topic "topic_1" created +NotifyByWriteFile: New topic "topic_1.subtopic_11" created +MyPubsubNotifHandler: listener Listener_2608 subscribed to ALL_TOPICS +NotifyByWriteFile: Subscribed listener "Listener" to topic "ALL_TOPICS" +MyPubsubNotifHandler: listener listenerFn_1024 subscribed to topic_1.subtopic_11 +NotifyByWriteFile: Subscribed listener "listenerFn" to topic "topic_1.subtopic_11" +MyPubsubNotifHandler: listener Listener.onTopic11_8808 subscribed to topic_1.subtopic_11 +NotifyByWriteFile: Subscribed listener "Listener.onTopic11" to topic "topic_1.subtopic_11" +MyPubsubNotifHandler: listener Listener.onTopic1_8808 subscribed to topic_1 +NotifyByWriteFile: Subscribed listener "Listener.onTopic1" to topic "topic_1" +----------------------- +NotifyByWriteFile: Start sending message of topic "topic_1.subtopic_11" +NotifyByWriteFile: Sending message of topic "topic_1.subtopic_11" to listener Listener.onTopic11 +Method Listener.onTopic11 received: ('message for subtopic 11', 'other message', 123) +NotifyByWriteFile: Sending message of topic "topic_1.subtopic_11" to listener listenerFn +Function listenerFn received: ('message for subtopic 11', 'other message', 123) +NotifyByWriteFile: Sending message of topic "topic_1" to listener Listener.onTopic1 +Method Listener.onTopic1 received "topic_1.subtopic_11" message: ('message for subtopic 11', 'other message', 123) +NotifyByWriteFile: Sending message of topic "ALL_TOPICS" to listener Listener +Listener instance received: ('message for subtopic 11', 'other message', 123) +NotifyByWriteFile: Done sending message of topic "topic_1.subtopic_11" +NotifyByWriteFile: Start sending message of topic "topic_1" +NotifyByWriteFile: Sending message of topic "topic_1" to listener Listener.onTopic1 +Method Listener.onTopic1 received "topic_1" message: 'message for topic 1' +NotifyByWriteFile: Sending message of topic "ALL_TOPICS" to listener Listener +Listener instance received: message for topic 1 +NotifyByWriteFile: Done sending message of topic "topic_1" +NotifyByWriteFile: Start sending message of topic "topic_2.subtopic_21" +NotifyByWriteFile: Sending message of topic "ALL_TOPICS" to listener Listener +Listener instance received: message for subtopic 2 +NotifyByWriteFile: Done sending message of topic "topic_2.subtopic_21" +------- done ---------- +Exporting topic tree to arg1_topics +------ exiting -------- +Press any key to continue . . . diff --git a/wx/lib/pubsub/utils/intraimport.py b/wx/lib/pubsub/utils/intraimport.py deleted file mode 100644 index 8f9de826..00000000 --- a/wx/lib/pubsub/utils/intraimport.py +++ /dev/null @@ -1,61 +0,0 @@ -''' -This is used internally by pubsub to allow modules of the pubsub.utils -subpackage to import modules of a sibbling subpackage (such as -pubsub.core). - -Value of "up" parameter: For intraImport() the defaut up is 1 because -it is always used from within an __init__ file ie most likely scenario -is up=1. The parentImport() function mostly used from within modules -of a package so up defaults to 2. - -:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved. -:license: BSD, see LICENSE_BSD_Simple.txt for details. -''' - -# allow utils modules to find sibblings in core -def intraImport(pathList, up=1): - '''Enable modules of a subpackage to import modules of a sibbling - subpackage, or parent modules, ie A.B.C could import A.D.E by doing - 'import D.E' (this is default behavior). If up > 1, can import from - higher up the import tree. For instance with up=2, ie A.B.C.D could - import A.E.F.G by doing 'import E.F.G'. - - WARNING: it looks like Python - loads a separate copy of sibbling modules found via the modified - module search path; this is a problem if the sibbling modulres - contain globals (singletons) since more than one instance of a module - could exist in an application. Use parentImport() in such case.''' - import os - newPath = pathList[0] - for _ in range(0, up): - newPath = os.path.join(newPath, '..') - # py2exe requires abspath to find new path - pathList.append( os.path.abspath( newPath ) ) - - -_importCache = {} - -def parentImport(modName, up=2): - '''Import a module modName from parent of current package. Default - assumes used within a non-init module of pubsub.utils, ie up=2.''' - - # see if in cache - modObj = _importCache.get( (modName, up), None ) - if modObj is not None: - return modObj - - # not in cache, assume parent already imported - module = globals()['__name__'].split('.') - parentModName = '.'.join( module[:-up] ) - import sys - parentModObj = sys.modules[parentModName] - - try: - modObj = getattr(parentModObj, modName) - _importCache[ (modName, up) ] = modObj - return modObj - - except AttributeError: - msg = 'no module named %s in %s' % (modName, parentModName) - raise ImportError(msg) - diff --git a/wx/lib/pubsub/utils/topictreeprinter.py b/wx/lib/pubsub/utils/topictreeprinter.py index fec9d182..1ff673ab 100644 --- a/wx/lib/pubsub/utils/topictreeprinter.py +++ b/wx/lib/pubsub/utils/topictreeprinter.py @@ -152,11 +152,10 @@ class TopicTreePrinter(ITopicTreeVisitor): def __printTopicListeners(self, indent, topicObj): if topicObj.hasListeners(): - listeners = topicObj.getListeners() item = '%s Listeners:' % self.__topicItemsBullet self.__output.append( self.__formatDefn(indent, item) ) tmpIndent = indent + self.__indentStep - for listener in listeners: + for listener in topicObj.getListenersIter(): item = '%s %s (from %s)' % (self.__topicArgsBullet, listener.name(), listener.module()) self.__output.append( self.__formatDefn(tmpIndent, item) )