does anyone use pubsub's arg1 messaging protocol?

I’d like to remove support for arg1 protocol in PyPubSub as it complexifies the code and was only meant to be a temporary help to migrate wx apps that used old-style pubsub. You are using arg1 if you have an import of setuparg1 in your app/library. If you do, let me know ASAP. Thanks,

···

Oliver
Open Source contributions: PyPubSub, Lua-iCxx, iof

StackOverflow contributions

I personally haven’t for some time.

But since you’re looking at pubsub arg/kwarg1 protocols/API, I’d like to mention a little recipe that I use to get around an exception I get from the inspect package which I think pubsub uses. I get this exception when I use listener functions with argument annotations.

Also there’s a depreciation warning for Python 3.5 for the inspect package dropping getargspect() or whatever it is called, which I think is used by pubsub. I came across the notice for depreciation for Python 3.5 after I added argument annotations to my listeners.

The inspect package’s depreciation warning for Python 3.5 says it might drop getargspec() and instead to use inspect.getfullargspect() or inspect.getkwargspect(). I am not sure of the function name.

My current workaround is to use a subscribe() decorator which pulls off the annotations and then re-adds them after I pub.sendMessage() in the decorator. The added benefit is that the topic subscription can be before the listener functions def statement and it doesn’t invalidate the pub.subscribe() being used elsewhere.

With additional modification to the subscribe decorator I suspect the inspect module’s use could be removed and the topic tree can be created that way too.

···

py -3.4+

“”"

author: DevPlayer@gmail.com

date: 2015-11-26

license: GNU Lesser General Public License v 3.0

“”"

import functools

from pubsub import pub

def subscribe(topic, publisher:“You do not have to use the default pubsub.pub instance”=None):

“”" A decorator for pubsub listeners with a function(data=None) signature. This template

allows function argument annotations to be used with pubsub v3 without throwing an

exception. Example usage:

@subscribe(‘server’)

def audit(data:‘Capture only metadata of action.’=None):

log_action(data)

@subscribe(‘server.process’)

def process(data:‘State change request.’=None):

do_stuff(data)

pub.sendMessage(‘server.process’, data=a_request)

“”"

def real_decorator(function):

_annotations = function.annotations.copy()

function.annotations.clear()

@functools.wraps(function)

def wrapper(data=None):

return function(data=data)

if publisher is None:

from pubsub import pub

else:

pub = publisher

pub.subscribe(wrapper, topic)

function.annotations.update(_annotations)

return wrapper

return real_decorator

BTW I love how pubsub hides all the complex stuff and makes the API so
clean looking (to me). I was looking to mimic that in a project I was
playing with but couldn't wrap my head around it all. I hope you keep the
old versions around for distribution so I can revisit that in the future.

Hi devplayer, thx for the feedback and code. I will add support for annotated listeners shortly and plan on addressing the inspect function deprecation, I just have to find way to maintain compatibility with Python 2.7. And no worries, the older dists are always available (really old ones get hidden but never deleted).

One note: your wrapper uses data as arg, this suggests that you are using arg1 prototcol. The still-supported protocol is kwargs, which means your data would be send as separate objects using keyword arguments.

Cheers,

Oliver

···

py -3.4+

“”"

author: DevPlayer@gmail.com

date: 2015-11-26

license: GNU Lesser General Public License v 3.0

“”"

import functools

from pubsub import pub

def subscribe(topic, publisher:“You do not have to use the default pubsub.pub instance”=None):

“”" A decorator for pubsub listeners with a function(data=None) signature. This template

allows function argument annotations to be used with pubsub v3 without throwing an

exception. Example usage:

@subscribe(‘server’)

def audit(data:‘Capture only metadata of action.’=None):

log_action(data)

@subscribe(‘server.process’)

def process(data:‘State change request.’=None):

do_stuff(data)

pub.sendMessage(‘server.process’, data=a_request)

“”"

def real_decorator(function):

_annotations = function.annotations.copy()

function.annotations.clear()

@functools.wraps(function)

def wrapper(data=None):

return function(data=data)

if publisher is None:

from pubsub import pub

else:

pub = publisher

pub.subscribe(wrapper, topic)

function.annotations.update(_annotations)

return wrapper

return real_decorator

I’m still using the old arg1 protocol. Not that I couldn’t go through and update, but would just add one more thing to the list :wink:

···

On Thu, Dec 10, 2015 at 9:06 AM, oliver oliver.schoenborn@gmail.com wrote:

Hi devplayer, thx for the feedback and code. I will add support for annotated listeners shortly and plan on addressing the inspect function deprecation, I just have to find way to maintain compatibility with Python 2.7. And no worries, the older dists are always available (really old ones get hidden but never deleted).

One note: your wrapper uses data as arg, this suggests that you are using arg1 prototcol. The still-supported protocol is kwargs, which means your data would be send as separate objects using keyword arguments.

Cheers,

Oliver

On Dec 9, 2015 5:13 PM, “Dev Player” devplayer@gmail.com wrote:

I personally haven’t for some time.

But since you’re looking at pubsub arg/kwarg1 protocols/API, I’d like to mention a little recipe that I use to get around an exception I get from the inspect package which I think pubsub uses. I get this exception when I use listener functions with argument annotations.

Also there’s a depreciation warning for Python 3.5 for the inspect package dropping getargspect() or whatever it is called, which I think is used by pubsub. I came across the notice for depreciation for Python 3.5 after I added argument annotations to my listeners.

The inspect package’s depreciation warning for Python 3.5 says it might drop getargspec() and instead to use inspect.getfullargspect() or inspect.getkwargspect(). I am not sure of the function name.

My current workaround is to use a subscribe() decorator which pulls off the annotations and then re-adds them after I pub.sendMessage() in the decorator. The added benefit is that the topic subscription can be before the listener functions def statement and it doesn’t invalidate the pub.subscribe() being used elsewhere.

With additional modification to the subscribe decorator I suspect the inspect module’s use could be removed and the topic tree can be created that way too.

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

py -3.4+

“”"

author: DevPlayer@gmail.com

date: 2015-11-26

license: GNU Lesser General Public License v 3.0

“”"

import functools

from pubsub import pub

def subscribe(topic, publisher:“You do not have to use the default pubsub.pub instance”=None):

“”" A decorator for pubsub listeners with a function(data=None) signature. This template

allows function argument annotations to be used with pubsub v3 without throwing an

exception. Example usage:

@subscribe(‘server’)

def audit(data:‘Capture only metadata of action.’=None):

log_action(data)

@subscribe(‘server.process’)

def process(data:‘State change request.’=None):

do_stuff(data)

pub.sendMessage(‘server.process’, data=a_request)

“”"

def real_decorator(function):

_annotations = function.annotations.copy()

function.annotations.clear()

@functools.wraps(function)

def wrapper(data=None):

return function(data=data)

if publisher is None:

from pubsub import pub

else:

pub = publisher

pub.subscribe(wrapper, topic)

function.annotations.update(_annotations)

return wrapper

return real_decorator

Daniel Hyams
dhyams@gmail.com

REPOST WITH CORRECTIONS:

Yes, I think. The subscribe decorator I posted above is specific to listener functions with “data=” as a keyword. So this:

    @subscribe('server')
    def audit(data:'Capture only metadata of action.'=None):
        log_action(data)

    @subscribe('server.process')
    def process(data:'State change request.'=None):
        do_stuff(data)

    pub.sendMessage('server.process', data=a_request)

``

is precisely equivalent to this:

    def audit(data=None):
        log_action(data)
    pub.subscribe(audit, "server")

    def process(data=None):
        do_stuff(data)
    pub.subscribe(process, "server.process")

    pub.sendMessage('server.process', data=a_request) # data= is an explicit keyword

``

So to use a listener with a different signature, say

def some_listener(firstname=None, lastname=None):
do_stuff(firstname, lastname)
pub.subscribe(some_listener, ‘database.record.add’)

``

You would have to create a new decorator:

def db_subscribe(topic, publisher:“You do not have to use the default pubsub.pub instance”=None):

def real_decorator(function):
    _annotations = function.__annotations__.copy()
    function.__annotations__.clear()

    @functools.wraps(function)
    def wrapper(firstname=None, lastname=None):
        return function(firstname=firstname, lastname=lastname)
    if publisher is None:
        from pubsub import pub
    else:
        pub = publisher
    pub.subscribe(wrapper, topic)
    function.__annotations__.update(_annotations)
    return wrapper
return real_decorator

``

My brain fails on how to decorate pubsub listeners with annotations and dynamically provided kwargs.

With the decorator recipe I gave this would fail:

@subscribe(‘log.user.deletes’) # SUCCESS correct function signature
def user_deletes(data=None):
do_delete(data)

@subscribe(‘db.user.add’)
def db_user_add(firstname=None, lastname=None): # FAIL wrong function signature
do_stuff()

``

But this wouldn’t fail. it would work.

@subscribe(‘log.user.deletes’) # SUCCESS correct function signature
def user_deletes(data=None):
do_delete(data)

@db_subscribe(‘db.user.add’) # different decorator
def db_user_add(firstname=None, lastname=None): # SUCCESS correct function signature
do_stuff()

``

I blabbed on about this mostly for those who are not familiar with pubsub and partially hoping someone could figure out how to update that decorator to work with listener function signatures more dynamically like pubsub does now with pub.subscribe().

Pubsub 3.4 will not include arg1 (it has been deprecated for almost 2 years now). Mostly small improvements, some simplification of code for maintainability, so you prob won’t be affected :slight_smile:

···

On Thu, Dec 10, 2015 at 9:06 AM, oliver oliver.schoenborn@gmail.com wrote:

Hi devplayer, thx for the feedback and code. I will add support for annotated listeners shortly and plan on addressing the inspect function deprecation, I just have to find way to maintain compatibility with Python 2.7. And no worries, the older dists are always available (really old ones get hidden but never deleted).

One note: your wrapper uses data as arg, this suggests that you are using arg1 prototcol. The still-supported protocol is kwargs, which means your data would be send as separate objects using keyword arguments.

Cheers,

Oliver

On Dec 9, 2015 5:13 PM, “Dev Player” devplayer@gmail.com wrote:

I personally haven’t for some time.

But since you’re looking at pubsub arg/kwarg1 protocols/API, I’d like to mention a little recipe that I use to get around an exception I get from the inspect package which I think pubsub uses. I get this exception when I use listener functions with argument annotations.

Also there’s a depreciation warning for Python 3.5 for the inspect package dropping getargspect() or whatever it is called, which I think is used by pubsub. I came across the notice for depreciation for Python 3.5 after I added argument annotations to my listeners.

The inspect package’s depreciation warning for Python 3.5 says it might drop getargspec() and instead to use inspect.getfullargspect() or inspect.getkwargspect(). I am not sure of the function name.

My current workaround is to use a subscribe() decorator which pulls off the annotations and then re-adds them after I pub.sendMessage() in the decorator. The added benefit is that the topic subscription can be before the listener functions def statement and it doesn’t invalidate the pub.subscribe() being used elsewhere.

With additional modification to the subscribe decorator I suspect the inspect module’s use could be removed and the topic tree can be created that way too.

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.


Daniel Hyams
dhyams@gmail.com

py -3.4+

“”"

author: DevPlayer@gmail.com

date: 2015-11-26

license: GNU Lesser General Public License v 3.0

“”"

import functools

from pubsub import pub

def subscribe(topic, publisher:“You do not have to use the default pubsub.pub instance”=None):

“”" A decorator for pubsub listeners with a function(data=None) signature. This template

allows function argument annotations to be used with pubsub v3 without throwing an

exception. Example usage:

@subscribe(‘server’)

def audit(data:‘Capture only metadata of action.’=None):

log_action(data)

@subscribe(‘server.process’)

def process(data:‘State change request.’=None):

do_stuff(data)

pub.sendMessage(‘server.process’, data=a_request)

“”"

def real_decorator(function):

_annotations = function.annotations.copy()

function.annotations.clear()

@functools.wraps(function)

def wrapper(data=None):

return function(data=data)

if publisher is None:

from pubsub import pub

else:

pub = publisher

pub.subscribe(wrapper, topic)

function.annotations.update(_annotations)

return wrapper

return real_decorator