FYI: pubsub update

Some of you might be interested to know that I gave the pubsub module
its own home a while back already, on cheese shop
(pypi.python.org/pypi/PyPubSub) and sourceforge.net
(www.sf.net/projects/pubsub). See
http://pubsub.wiki.sourceforge.net/history for details on move/evolution.

The latest version's sendMessage() is not compatible with the one
currently in wx.lib.pubsub, though the change requires only
straightforward changes to your code. For those who really can't risk
changing stuff in your existing applications, don't worry, the version
in wx.lib will by default use version 1 (at least for next while),
you'll have to specify an extra line to use version 1. Any new
applications should use version 3 as version 1 will only get bug fixes,
no new features.

Note that I don't have time to monitor wxPython these days so any
questions or bug reports should be posted on the
www.SF.net/projects/pubsub page.

Regards,
schoenborno

Oliver Schoenborn wrote:

Some of you might be interested to know that I gave the pubsub module
its own home a while back already, on cheese shop
(pypi.python.org/pypi/PyPubSub) and sourceforge.net
(www.sf.net/projects/pubsub). See
http://pubsub.wiki.sourceforge.net/history for details on move/evolution.

This would be a good time to get a discussion going into the benefits of pubsub3 -- should it be used as the default pubsub in future versions of wx?

It's nice to know you're working on it again -- it looked like it was sleeping for a while.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

What are the differences between the old and new sendMessage?

- Josiah

···

On Tue, Jul 22, 2008 at 9:27 PM, Oliver Schoenborn <oliver.schoenborn@utoronto.ca> wrote:

Some of you might be interested to know that I gave the pubsub module
its own home a while back already, on cheese shop
(pypi.python.org/pypi/PyPubSub) and sourceforge.net
(www.sf.net/projects/pubsub). See
http://pubsub.wiki.sourceforge.net/history for details on move/evolution.

The latest version's sendMessage() is not compatible with the one
currently in wx.lib.pubsub, though the change requires only
straightforward changes to your code. For those who really can't risk
changing stuff in your existing applications, don't worry, the version
in wx.lib will by default use version 1 (at least for next while),
you'll have to specify an extra line to use version 1. Any new
applications should use version 3 as version 1 will only get bug fixes,
no new features.

Note that I don't have time to monitor wxPython these days so any
questions or bug reports should be posted on the
www.SF.net/projects/pubsub page.

Regards,
schoenborno
_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

You don't need a PEP to get pubsub into Python proper. Basically you
just need to show that it's more or less the default standard library
for handling this particular kind of behavior, that there would be
great benefit to adding it, and someone to commit to maintaining it
for a couple years.

- Josiah

···

On Wed, Jul 23, 2008 at 1:16 PM, Karsten Hilbert <Karsten.Hilbert@gmx.net> wrote:

On Wed, Jul 23, 2008 at 10:06:37AM -0700, Christopher Barker wrote:

Oliver Schoenborn wrote:

Some of you might be interested to know that I gave the pubsub module
its own home a while back already, on cheese shop
(pypi.python.org/pypi/PyPubSub) and sourceforge.net
(www.sf.net/projects/pubsub). See
http://pubsub.wiki.sourceforge.net/history for details on move/evolution.

This would be a good time to get a discussion going into the benefits of
pubsub3 -- should it be used as the default pubsub in future versions of
wx?

Would it not actually (also ?) be a worthy goal to try and
get pubsub into Python proper ? I do realize it's fairly
involved with writing a PEP and all that.

You don't need a PEP to get pubsub into Python proper. Basically you
just need to show that it's more or less the default standard library
for handling this particular kind of behavior, that there would be
great benefit to adding it, and someone to commit to maintaining it
for a couple years.

- Josiah

Good to know. But I would think that a bigger user base would be
beneficial before such undertaking.
Oliver

Josiah Carlson wrote:

What would be nice is the actual function prototype. For example, the
previous function prototype was...

def sendMessage(self, topic=ALL_TOPICS, data=None, onTopicNeverCreated=None):

What is the new function prototype? Because that would really

It is now

def sendMessage(self, topic, **kwargs):

The new pubsub provides better mechanisms for handling topic creation
and undefined topics.

Should this discussion be moved to the pubsub forum and we put only the
conclusion of the thread on wxpython mailing list?

Oliver

Oliver Schoenborn wrote:

Should this discussion be moved to the pubsub forum and we put only the
conclusion of the thread on wxpython mailing list?

Robin recently asked the question: "should we make pubsub3 the official wxPython pubsub?"

Given that question, I think the discussion does belong here, or maybe on wxpython-dev.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Josiah Carlson wrote:

You don't need a PEP to get pubsub into Python proper. Basically you
just need to show that it's more or less the default standard library
for handling this particular kind of behavior, that there would be
great benefit to adding it, and someone to commit to maintaining it
for a couple years.

Technically, yes, but:

1) It really does have to be the "default standard library", which pubsub is not, in the least, and I don't think anything else is either, though there are a couple of other contenders.

2) It's still not that simple. For example, numpy certainly meets all those criteria, but has not been included (for good reason), and the inclusion of a simpler nd-array buffer type and protocol has required an involved PEP process.

So, I think it would be nice to get something like pubsub into the standard library, but I think it really would take a PEP, and quite a bit of work to hash out all the conflicting implementations and needs, wants and desires. I'd love it if if someone did that work, but it wont be me!

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Karsten Hilbert wrote:

Fully agree. It having been in wxPython for a number of
years (?) also attests to its maturity, I suppose.

A little archeology digging in SVN shows that it is 6 years old.

http://trac.wxwidgets.org/log/wxWidgets/branches/WX_2_4_BRANCH/wxPython/wxPython/lib/pubsub.py?rev=39667

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

I also doubt a lot of people are using it. Additionally it would need a complete unit-test suite to ensure everything works as expected.

pydispatcher. It also features things like weakref support, keywords etc.. So if python was to include some "event library" it is probably amongst the top candidates.
It would be great if python had a builtin library for events and stuff and I wouldn't mind much whether it's pydispatcher/louie, pubsub or another module. Maybe one of the most difficult parts about getting such a module into python is satisfying the different expectations of them. Maybe one of the packages could be used as the basis and then there could be 2 or 3 layers around it which are suited to specific needs. For example if pydispatcher was the base, then pubsubs "message hierarchy" could be implemented on top of it.
I also suggest adding a simple "Observable" class to pubsub which you can subclass and which provides sendMessage/subscribe/unsubscribe methods and prepends id(obj) to every message it sends. This way the messages are local to one object. There are probably more things that could be implemented on top of the current hierarchy model, for example watching topics with wildcards like 'myWidgets.*.value'.
I also wrote a decorator for pubsub which I use occasionally and might be useful as part of a layer around pubsub:

def expandEventKeywords(func):
     ''' Decorator to turn an event handler taking a single key argument into
         a function taking keywords instead, e.g. instead of

         def myFunc(evt):
             x = evt.arg1
             y = evt.arg2
             ...

         you can use

         @expandEventKeywords
         def myFunc( x, y, ... ):
             # use x and y here directly
             pass
     '''
     def expand(*args):
         evt = args[-1]
         return func( *args[0:-1], **evt.vars )

This is similar to what was posted here before.

There are probably more convenience possibilities than only Observer and the keywords decorator. We should probably collect them and evaluate whether they can/should be part of pubsub. There's not much sense in everybody writing his custom wrappers around pubsub.

-Matthias

···

Am 24.07.2008, 21:33 Uhr, schrieb Christopher Barker <Chris.Barker@noaa.gov>:

As for it having a history in wxPython -- yes, that's true, but how many wxPython apps use it? and how many non-wxPython projects use it? From the look of the activity in the sourceforge project -- not many.

From my experience the most widespread event/messaging module is

As for it having a history in wxPython -- yes, that's true, but how many
wxPython apps use it? and how many non-wxPython projects use it? From the
look of the activity in the sourceforge project -- not many.

I also doubt a lot of people are using it. Additionally it would need a
complete unit-test suite to ensure everything works as expected.

From my experience the most widespread event/messaging module is
pydispatcher. It also features things like weakref support, keywords etc..
So if python was to include some "event library" it is probably amongst the
top candidates.

Looking into pydispatcher, getting pubsub behavior in pydispatcher is
more work than getting pydispatcher behavior in pubsub. Further,
pubsub's ability to define topics for sources and destinations are
actually a publish-subscribe architecture, where as with pydispatcher,
you end up stating (apparently often enough) who the origin sender is.
Part of the publish-subscribe architecture is that it is "loosely
coupled", pubsub fits that, pydispatcher doesn't.

It also turns out that pubsub perfectly encapsulates the origin sender
in the topic tree rather than prepending the id, but post-pending the
"id". For example, any recipient that wants to get topic X.Y, just
subscribes to X.Y . Recipients that only want to get "anonymous"
senders subscribe to X.Y.<None>. Recipients that want to get messages
from individual senders subscribe to X.Y.<id>. But then again, the
X.Y.<id> method requires that the subscriber know about the sender,
which breaks the loose coupling of sender from recipient.

Purity aside, pubsub can (relatively easily) gain
pydispatcher-equivalent functionality with relatively minimal effort
(borrow the table of sources -> ids from pydispatcher).

It would be great if python had a builtin library for events and stuff and I
wouldn't mind much whether it's pydispatcher/louie, pubsub or another
module. Maybe one of the most difficult parts about getting such a module
into python is satisfying the different expectations of them. Maybe one of
the packages could be used as the basis and then there could be 2 or 3
layers around it which are suited to specific needs. For example if
pydispatcher was the base, then pubsubs "message hierarchy" could be
implemented on top of it.
I also suggest adding a simple "Observable" class to pubsub which you can
subclass and which provides sendMessage/subscribe/unsubscribe methods and
prepends id(obj) to every message it sends. This way the messages are local
to one object. There are probably more things that could be implemented on
top of the current hierarchy model, for example watching topics with
wildcards like 'myWidgets.*.value'.

That is also possible, though it also couples your sender to your
recipient ;). Again, all of this is easily added.

I also wrote a decorator for pubsub which I use occasionally and might be
useful as part of a layer around pubsub:

def expandEventKeywords(func):
   ''' Decorator to turn an event handler taking a single key argument into
       a function taking keywords instead, e.g. instead of

       def myFunc(evt):
           x = evt.arg1
           y = evt.arg2
           ...

       you can use

       @expandEventKeywords
       def myFunc( x, y, ... ):
           # use x and y here directly
           pass
   '''
   def expand(*args):
       evt = args[-1]
       return func( *args[0:-1], **evt.vars )

This is similar to what was posted here before.

There are probably more convenience possibilities than only Observer and the
keywords decorator. We should probably collect them and evaluate whether
they can/should be part of pubsub. There's not much sense in everybody
writing his custom wrappers around pubsub.

Agreed.

- Josiah

···

On Thu, Jul 24, 2008 at 1:05 PM, Nitro <nitro@dr-code.org> wrote:

Am 24.07.2008, 21:33 Uhr, schrieb Christopher Barker > <Chris.Barker@noaa.gov>:

I would start using it today (in our wxPython project) if it
was in Python proper. We currently use a homegrown
pre-pydispatcher descendant.

Karsten

···

On Thu, Jul 24, 2008 at 02:32:34PM -0700, Josiah Carlson wrote:

Or how many people use it in their non-wxPython projects who already
have wxPython?

--
GPG key ID E4071346 @ wwwkeys.pgp.net
E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346

If all of your publish/subscribe messages are of the form:

[<type>.]<topic>[|.<None>|.<id>]

And when you publish from an object, you send to:
1. <topic>.<None> and <None>.<topic>
or
2. <topic>.<id> and <type>.<topic>.<id>

Note that this stuff can be automatically done with a very simple
message sending function that does this automatically. Also, the
<topic>.<None> and <None>.<topic> sort-of overlaps, but not in the
case when you want to get all messages from all anonymous senders.

- Josiah

Looking into pydispatcher, getting pubsub behavior in pydispatcher is
more work than getting pydispatcher behavior in pubsub. Further,
pubsub's ability to define topics for sources and destinations are
actually a publish-subscribe architecture, where as with pydispatcher,

Can you elaborate a bit what you mean when you say "define topics for
sources and destinations"?

I was typing too fast :wink: . What I meant to type was that pubsub's
ability to have subscribers subscribe to a topic without knowing about
the sender, and the sender to send messages to a topic without knowing
about the subscribers, is a publish-subscribe architecture. It can't
get much more loosely-coupled than not needing to know at all (other
than the shared topic node).

Agreed. pydispatcher does support this though. See the _Any and _Anonymous senders. This allows you to omit the sender alltogether.

Just to make sure I understand you correctly, Node x has a transform
property. When x.transform has changed, x is notified by the
publishing of a message by x.transform . (as an aside, subscriber ==
recipient, I think you mean "subscriber knows about the 'sender'".

Right. I was also typing too fast :slight_smile:

Indeed, there is nothing *wrong* with x knowing about x.transform, and
there is no need to remove the coupling. But there is also no
inherent benefit to using pydispatcher over pubsub for this example.
Node x can easily subscribe to a particular topic, and receive
messages from that topic when x.transform sends the message.

Yes.

Now say the Node class wants to be informed about all the kinds of messages
that transform produces. Right now this is not possible if I postpend the
id. Prepending the id allows me to register for all messages from that
object, but then again I cannot register to all messages of a specific kind,
regardless of sender. Because of this putting the sender into the topic-tree
is a bad idea imo. The sender is not associated with the topic, it's
orthogonal to it. So mingling its id into the topic is bad.

Indeed, if you prepend the id, you can subscribe to all events from
one object, or you can also create a new Publisher instance, let the
transform property know about it (so that it knows which publisher to
send messages to), and you guarantee locality.

If you want the ability to send messages to all objects of a
particular type, well, it turns out that is easy too :).

If all of your publish/subscribe messages are of the form:

[<type>.]<topic>[|.<None>|.<id>]

And when you publish from an object, you send to:
1. <topic>.<None> and <None>.<topic>
or
2. <topic>.<id> and <type>.<topic>.<id>

Then you can handle "give me stuff from objects of type X", "give me
stuff from objects with id X", "give me stuff from objects of type X
and id Y", etc.

Yes. But then I have to send two messages manually and people listening for None.None or None or ALL_TOPICS will receive the same message twice. With pydispatcher you'd send the message once and then can register on id and/or topic. Of course you could write something like that for pubsub too, but then it doesn't benefit from the hierarchy structure anymore as it's more or less processing flat messages. That's why I was arguing a bit in favour of pydispatcher, because it only deals with arbitrary (see below)/flat topics on top of which you could implement a hierarchy like pubsub has. The basis of an event dispatcher as a python standard library module should be as slim as possible imo and the hierarchy is more work and code if you're mostly processing flat topics in the end.

Additionally pubsub doesn't support arbitrary topics, whereas pydispatcher
does. Fitting this onto pubsub is probably also some work I guess. I think
pubsub has gone one step too far by implementing a topic-tree. Maybe this
"deal with topics" part should be abstracted and made pluggable somehow.

Arbitrary topics? I don't know precisely what you mean. If you mean
that topics are of a hierarchical tree structure, then yes. But
that's actually a *good* feature.

I mean pubsub supports only strings (or tuples thereof) as topics. In pydispatcher any hashable object can be a topic. I do agree that a hierarchy is a good feature and quite powerful.

Maybe we are just experiencing what I mentioned before, my expectations are
varying wildly from yours (at least until we've come to a conclusion of this
discussion) :slight_smile:

Oh, I'm sure our expectations are vastly different; I've never come
across an application where it actually mattered substantially where a
message came from. And when it did, you just pass where it came from
as part of the data.

Yes, this is always possible. I tend to register with senders sometimes and then it's nice to have an explicit mechanism for that. Of course if I wanted to do the whole of type.topic.id thing, then pydispatcher would need a helper function too.

It seems there are many points of view on this topic. It seems that pubsub (with some helper functions) and pydispatcher (with helpers for hierarchy) can do the same things. In the end it probably boils down to taste which to use as the basis for an event module. Pubsub would greatly benefit from some helper functions (judging from my taste) which make common tasks work out of the box. If I have to start thinking like type.topic.id it's getting too much work and the module gets a lot less attractive.

So in conclusion I wouldn't mind which module will get included in python as long as one of them actually does.

Thanks for explaining your point of view so thoroughly,
-Matthias

···

Am 25.07.2008, 01:39 Uhr, schrieb Josiah Carlson <josiah.carlson@gmail.com>:

On Thu, Jul 24, 2008 at 3:29 PM, Nitro <nitro@dr-code.org> wrote:

Am 24.07.2008, 23:31 Uhr, schrieb Josiah Carlson >> <josiah.carlson@gmail.com>:

This is why, when exploring the possibilities of using pubsub, I had
to determine how messages work in my application. Right now I send
very specific messages.

So I would have x respond to a "x.change" message but have x send a
"x.ischanged" message once the change is made.

This may not be the most flexible use of pubsub, but it seems like it
is easy to get into a loop:

Publisher().subscribe(self.OnX,"x.change")

def OnX(self,msg): Publisher.sendMessage("x.change")

Josh

···

On Thu, Jul 24, 2008 at 4:39 PM, Josiah Carlson <josiah.carlson@gmail.com> wrote:

Just to make sure I understand you correctly, Node x has a transform
property. When x.transform has changed, x is notified by the
publishing of a message by x.transform . (as an aside, subscriber ==
recipient, I think you mean "subscriber knows about the 'sender'".

--
Josh English
Joshua.R.English@gmail.com

Looking into pydispatcher, getting pubsub behavior in pydispatcher is
more work than getting pydispatcher behavior in pubsub. Further,
pubsub's ability to define topics for sources and destinations are
actually a publish-subscribe architecture, where as with pydispatcher,

Can you elaborate a bit what you mean when you say "define topics for
sources and destinations"?

I was typing too fast :wink: . What I meant to type was that pubsub's
ability to have subscribers subscribe to a topic without knowing about
the sender, and the sender to send messages to a topic without knowing
about the subscribers, is a publish-subscribe architecture. It can't
get much more loosely-coupled than not needing to know at all (other
than the shared topic node).

Agreed. pydispatcher does support this though. See the _Any and _Anonymous
senders. This allows you to omit the sender alltogether.

Just to make sure I understand you correctly, Node x has a transform
property. When x.transform has changed, x is notified by the
publishing of a message by x.transform . (as an aside, subscriber ==
recipient, I think you mean "subscriber knows about the 'sender'".

Right. I was also typing too fast :slight_smile:

Indeed, there is nothing *wrong* with x knowing about x.transform, and
there is no need to remove the coupling. But there is also no
inherent benefit to using pydispatcher over pubsub for this example.
Node x can easily subscribe to a particular topic, and receive
messages from that topic when x.transform sends the message.

Yes.

Now say the Node class wants to be informed about all the kinds of
messages
that transform produces. Right now this is not possible if I postpend the
id. Prepending the id allows me to register for all messages from that
object, but then again I cannot register to all messages of a specific
kind,
regardless of sender. Because of this putting the sender into the
topic-tree
is a bad idea imo. The sender is not associated with the topic, it's
orthogonal to it. So mingling its id into the topic is bad.

Indeed, if you prepend the id, you can subscribe to all events from
one object, or you can also create a new Publisher instance, let the
transform property know about it (so that it knows which publisher to
send messages to), and you guarantee locality.

If you want the ability to send messages to all objects of a
particular type, well, it turns out that is easy too :).

If all of your publish/subscribe messages are of the form:

[<type>.]<topic>[|.<None>|.<id>]

And when you publish from an object, you send to:
1. <topic>.<None> and <None>.<topic>
or
2. <topic>.<id> and <type>.<topic>.<id>

Then you can handle "give me stuff from objects of type X", "give me
stuff from objects with id X", "give me stuff from objects of type X
and id Y", etc.

Yes. But then I have to send two messages manually and people listening for
None.None or None or ALL_TOPICS will receive the same message twice. With
pydispatcher you'd send the message once and then can register on id and/or
topic. Of course you could write something like that for pubsub too, but
then it doesn't benefit from the hierarchy structure anymore as it's more or
less processing flat messages. That's why I was arguing a bit in favour of
pydispatcher, because it only deals with arbitrary (see below)/flat topics
on top of which you could implement a hierarchy like pubsub has. The basis
of an event dispatcher as a python standard library module should be as slim
as possible imo and the hierarchy is more work and code if you're mostly
processing flat topics in the end.

How often is it that you have *one* receiver taking both "give me a
message from any anonymous sender" and "give me any anonymous message
on topic X"? Because those are the specific use-cases for this. Of
course, I don't have a use for either, so... :wink:

It turns out that without re-implementing the tree structure that
pubsub uses, getting the same behavior with respect to the topic
hierarchy and subscriber calling is expensive (or you have to keep
cycling within pydispatcher to get what you want). Where as when you
have the tree structure already, you can fit pydispatcher in without
much difficulty.

Additionally pubsub doesn't support arbitrary topics, whereas
pydispatcher
does. Fitting this onto pubsub is probably also some work I guess. I
think
pubsub has gone one step too far by implementing a topic-tree. Maybe this
"deal with topics" part should be abstracted and made pluggable somehow.

Arbitrary topics? I don't know precisely what you mean. If you mean
that topics are of a hierarchical tree structure, then yes. But
that's actually a *good* feature.

I mean pubsub supports only strings (or tuples thereof) as topics. In
pydispatcher any hashable object can be a topic. I do agree that a hierarchy
is a good feature and quite powerful.

Technically speaking, pydisptcher uses id(object), which pubsub can
also use. Also, technically, pubsub doesn't actually do typechecks on
objects passed as the contents of the tuple...

import wx.lib.pubsub
def fcn(msg):

... print msg.topic, msg.data
...

wx.lib.pubsub.Publisher.subscribe(fcn, (1, 'is', 'my', 'topic'))
wx.lib.pubsub.Publisher.sendMessage((1, 'is', 'my', 'topic'), "data")

(1, 'is', 'my', 'topic') data

Of course it doesn't do weak referencing of the keys, but that isn't
terribly difficult to support...

import weakref
d = weakref.WeakKeyDictionary()
class foo:

... pass
...

e = foo()
def killtopic(topic):

... class kt:
... def __del__(self):
... print "would have killed topic", topic
... return kt()
...

e = foo()
d[e] = killtopic('some random topic')
del e

would have killed topic some random topic

Now, if we explicitly disallow anything except strings and non-builtin
types, then integer keys can represent id(object), and with the
killtopic mechanism, we can clear out topics if the objects in the
topics no longer exist.

Maybe we are just experiencing what I mentioned before, my expectations
are
varying wildly from yours (at least until we've come to a conclusion of
this
discussion) :slight_smile:

Oh, I'm sure our expectations are vastly different; I've never come
across an application where it actually mattered substantially where a
message came from. And when it did, you just pass where it came from
as part of the data.

Yes, this is always possible. I tend to register with senders sometimes and
then it's nice to have an explicit mechanism for that. Of course if I wanted
to do the whole of type.topic.id thing, then pydispatcher would need a
helper function too.

It seems there are many points of view on this topic. It seems that pubsub
(with some helper functions) and pydispatcher (with helpers for hierarchy)
can do the same things. In the end it probably boils down to taste which to
use as the basis for an event module. Pubsub would greatly benefit from some
helper functions (judging from my taste) which make common tasks work out of
the box. If I have to start thinking like type.topic.id it's getting too
much work and the module gets a lot less attractive.

Oh of course, the users of the module shouldn't have to consider how
it's internally represented, just that during subscription they can
say, "subscribe to topic X and it's descendants", plus the variants
with specific sender instances, types, etc. (though in my opinion the
latter shouldn't be quite so obvious). And with a little bit of
magic, you can also guarantee that during the wrapper's multi-call to
handle all of the options (in the case of the type/instance, etc.),
you don't send the same message to the same subscriber twice.

So in conclusion I wouldn't mind which module will get included in python as
long as one of them actually does.

Thanks for explaining your point of view so thoroughly,

No problem :), thank you for not yelling and screaming at me :wink: .

- Josiah

···

On Thu, Jul 24, 2008 at 5:27 PM, Nitro <nitro@dr-code.org> wrote:

Am 25.07.2008, 01:39 Uhr, schrieb Josiah Carlson <josiah.carlson@gmail.com>:

On Thu, Jul 24, 2008 at 3:29 PM, Nitro <nitro@dr-code.org> wrote:

Am 24.07.2008, 23:31 Uhr, schrieb Josiah Carlson >>> <josiah.carlson@gmail.com>:

Nitro wrote:

could be implemented on top of the current hierarchy model, for example
watching topics with wildcards like 'myWidgets.*.value'.

Isn't this the same as subscribing to the myWidgets topic and have
listener do nothing if the third part of the topic name is 'value'? In
pubsub1 the msg.topic is not the full topic name (IIRC), just the topic
from the level at which the listener was subscribed, but in pubsub3 it
is the full topic.

Oliver

Nitro wrote:

You don't want loose coupling all the time. For example I have a Node
class which has a transform property. When transform changes internally
(maybe transform.position changed) it sends a message that it has
changed. The Node is subscribed to this message and can react
accordingly. The node always knows about transform and it only wants to
respond to the message of exactly that transform. So in this case it's
not bad if the subscriber (the Node) knows about the "recipient".

Data is easily sent along with the message, and it's even cleaner in
pubsub3. You could even have each transform generate its own subtopic,
and subscribe different listeners. E.g.

Node.transform1 generates message transform.1
Node.transform2 generates message transform.2
Node subscribes Node.onChanged1 to transform.1, Node.onChanged2 to
transform.2

Additionally pubsub doesn't support arbitrary topics, whereas
pydispatcher does.

Can you elaborate on arbitrary topics?

Oliver

Timothy Grant wrote:

···

On Thu, Jul 24, 2008 at 5:58 AM, Mike Rooney <mxr@qvii.com > <mailto:mxr@qvii.com>> wrote:

    Oliver Schoenborn wrote:

        Should this discussion be moved to the pubsub forum and we put
        only the
        conclusion of the thread on wxpython mailing list?

        Oliver

    Well, I like it here, personally :slight_smile:

    - Mike

As do I.

All right all right, I get the message! :slight_smile:
Oliver

Josiah Carlson wrote:

I don't know if it would be difficult, but about the only thing
missing from pubsub 1 (available in wxPython today) is keyword
arguments. Though arguably, the only thing missing from pubsub 3
(just released) is positional arguments :wink: .

It's not missing, it's by design: having just one arg is limiting, so I
first looked at adding *arg, **kwarg. But because of the
looser-than-standard coupling between senders and listeners, it is easy
to get the order of unnamed arguments wrong; it is also easy to forget
to give some named arguments because they have default values. So in the
end I opted for allowing only kwargs in the sendMessage, though the
listener can have both (this is inherent to Python).

Moreover, topics specify what the valid names are so that listeners can
be validated at subscription time, another frequent source of bugs.
Finally, the list of args allowed by a topic is a superset of the args
allowed by parent topic, this is very much like a class hierarchy (these
are some of the reasons that finding ways to decorate sendMessage are
not enough to make pubsub3 backward compatible with pubsub1 -- you'd
also have to add a new ListenerValidator to the library (not difficult
but may be gotchas)).

So the following are valid listeners in pubsub3:

listener1()
listener2(arg1)
listener3(arg1, arg2)
listener4(arg1, arg2=None)
(and soon, listener(arg1, **args))

If you pick the following topic tree and argument specification
(subtopics "inherit" arguments from above):

topic1: (no args)
   subtopic1: arg1
      subtopic2: (no extra args)
         subtopic3: arg2

then

listener1 is valid for topic1 only
listener2 and listener4 are valid for topic1.subtopic1 and topic1.subtopic2
listener3 is valid for topic1.subtopic1.subtopic2.subtopic3

This may sound complicated but in fact is it as straightforward as
remember inheritance of methods.

Then again, one of the

known drawbacks of using pubsub is that you don't get a standard
calling like wx.CallAfter(), etc., you instead get a message object
with the data provided.

If I understand what you are refering to, this is supported by pubsub3.

Oliver