v3.3.0 at sf.net/projects/pubsub

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@75762 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Oliver Schoenborn
2014-02-01 22:36:11 +00:00
parent 309a66960b
commit cedf2ecb4e
4 changed files with 67 additions and 58 deletions

View File

@@ -3,17 +3,12 @@ Pubsub package initialization.
:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved.
:license: BSD, see LICENSE_BSD_Simple.txt for details.
Last change info:
- $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"
_PREVIOUS_RELEASE_DATE = "2013-09-15"
_PREVIOUS_RELEASE_VER = "3.2.1b"
__version__ = "3.3.0rc1"
__version__ = "3.3.0"
__all__ = [
'pub',

View File

@@ -14,7 +14,7 @@ CallArgsInfo regarding its autoTopicArgName data member.
from inspect import getargspec, ismethod, isfunction
from .. import py2and3
from .. import py2and3
AUTO_TOPIC = '## your listener wants topic name ## (string unlikely to be used by caller)'
@@ -32,7 +32,7 @@ def getModule(obj):
def getID(callable_):
"""Get name and module name for a callable, ie function, bound
method or callable instance, by inspecting the callable. E.g.
method or callable instance, by inspecting the callable. E.g.
getID(Foo.bar) returns ('Foo.bar', 'a.b') if Foo.bar was
defined in module a.b. """
sc = callable_
@@ -45,13 +45,13 @@ def getID(callable_):
else: # must be a functor (instance of a class that has __call__ method)
module = getModule(sc)
id = sc.__class__.__name__
return id, module
def getRawFunction(callable_):
"""Given a callable, return (offset, func) where func is the
function corresponding to callable, and offset is 0 or 1 to
function corresponding to callable, and offset is 0 or 1 to
indicate whether the function's first argument is 'self' (1)
or not (0). Raises ValueError if callable_ is not of a
recognized type (function, method or has __call__ method)."""
@@ -72,19 +72,19 @@ def getRawFunction(callable_):
else:
msg = 'type "%s" not supported' % type(callable_).__name__
raise ValueError(msg)
return func, firstArg
class ListenerMismatchError(ValueError):
"""
Raised when an attempt is made to subscribe a listener to
Raised when an attempt is made to subscribe a listener to
a topic, but listener does not satisfy the topic's message data
specification (MDS). This specification is inferred from the first
listener subscribed to a topic, or from an imported topic tree
specification (see pub.addTopicDefnProvider()).
"""
def __init__(self, msg, listener, *args):
idStr, module = getID(listener)
msg = 'Listener "%s" (from module "%s") inadequate: %s' % (idStr, module, msg)
@@ -93,17 +93,17 @@ class ListenerMismatchError(ValueError):
self.args = args
self.module = module
self.idStr = idStr
def __str__(self):
return self.msg
class CallArgsInfo:
"""
Represent the "signature" or protocol of a listener in the context of
topics.
Represent the "signature" or protocol of a listener in the context of
topics.
"""
def __init__(self, func, firstArgIdx): #args, firstArgIdx, defaultVals, acceptsAllKwargs=False):
"""Inputs:
- Args and defaultVals are the complete set of arguments and
@@ -112,8 +112,8 @@ class CallArgsInfo:
args that is of use, so it is typically 0 if listener is a function,
and 1 if listener is a method.
- The acceptsAllKwargs should be true
if the listener has **kwargs in its protocol.
if the listener has **kwargs in its protocol.
After construction,
- self.allParams will contain the subset of 'args' without first
firstArgIdx items,
@@ -121,7 +121,7 @@ class CallArgsInfo:
(ie self.allParams[:self.numRequired] are the required args names);
- self.acceptsAllKwargs = acceptsAllKwargs
- self.autoTopicArgName will be the name of argument
in which to put the topic object for which pubsub message is
in which to put the topic object for which pubsub message is
sent, or None. This is identified by the argument that has a
default value of AUTO_TOPIC.
@@ -141,7 +141,7 @@ class CallArgsInfo:
self.acceptsAllKwargs = (varOptParamName is not None)
self.acceptsAllUnnamedArgs = (varParamName is not None)
self.allParams = allParams
del self.allParams[0:firstArgIdx] # does nothing if firstArgIdx == 0
@@ -173,7 +173,7 @@ class CallArgsInfo:
firstKwargIdx = self.numRequired
self.autoTopicArgName = self.allParams.pop(firstKwargIdx + indx)
break
def getArgs(callable_):
"""Returns an instance of CallArgsInfo for the given callable_.

View File

@@ -1,7 +1,7 @@
"""
This module provides a basic "weak method" implementation, WeakMethod. It uses
weakref.WeakRef which, used on its own, produces weak methods that are dead on
creation, not very useful. Use the getWeakRef(object) module function to create the
This module provides a basic "weak method" implementation, WeakMethod. It uses
weakref.WeakRef which, used on its own, produces weak methods that are dead on
creation, not very useful. Use the getWeakRef(object) module function to create the
proper type of weak reference (weakref.WeakRef or WeakMethod) for given object.
:copyright: Copyright since 2006 by Oliver Schoenborn, all rights reserved.
@@ -17,26 +17,26 @@ from weakref import ref as WeakRef
class WeakMethod:
"""Represent a weak bound method, i.e. a method which doesn't keep alive the
"""Represent a weak bound method, i.e. a method which doesn't keep alive the
object that it is bound to. """
def __init__(self, method, notifyDead = None):
"""The method must be bound. notifyDead will be called when
"""The method must be bound. notifyDead will be called when
object that method is bound to dies. """
assert ismethod(method)
if method.__self__ is None:
raise ValueError('Unbound methods cannot be weak-referenced.')
self.notifyDead = None
if notifyDead is None:
self.objRef = WeakRef(method.__self__)
else:
self.notifyDead = notifyDead
self.objRef = WeakRef(method.__self__, self.__onNotifyDeadObj)
self.fun = method.__func__
self.cls = method.__self__.__class__
def __onNotifyDeadObj(self, ref):
if self.notifyDead:
try:
@@ -46,9 +46,9 @@ class WeakMethod:
traceback.print_exc()
def __call__(self):
"""Returns a MethodType if object for method still alive.
Otherwise return None. Note that MethodType causes a
strong reference to object to be created, so shouldn't save
"""Returns a MethodType if object for method still alive.
Otherwise return None. Note that MethodType causes a
strong reference to object to be created, so shouldn't save
the return value of this call. Note also that this __call__
is required only for compatibility with WeakRef.ref(), otherwise
there would be more efficient ways of providing this functionality."""
@@ -56,33 +56,33 @@ class WeakMethod:
return None
else:
return MethodType(self.fun, self.objRef())
def __eq__(self, method2):
"""Two WeakMethod objects compare equal if they refer to the same method
of the same instance. Thanks to Josiah Carlson for patch and clarifications
on how dict uses eq/cmp and hashing. """
if not isinstance(method2, WeakMethod):
return False
return ( self.fun is method2.fun
and self.objRef() is method2.objRef()
return False
return ( self.fun is method2.fun
and self.objRef() is method2.objRef()
and self.objRef() is not None )
def __hash__(self):
"""Hash is an optimization for dict searches, it need not
"""Hash is an optimization for dict searches, it need not
return different numbers for every different object. Some objects
are not hashable (eg objects of classes derived from dict) so no
hash(objRef()) in there, and hash(self.cls) would only be useful
in the rare case where instance method was rebound. """
return hash(self.fun)
def __repr__(self):
dead = ''
if self.objRef() is None:
if self.objRef() is None:
dead = '; DEAD'
obj = '<%s at %s%s>' % (self.__class__, id(self), dead)
return obj
def refs(self, weakRef):
"""Return true if we are storing same object referred to by weakRef."""
return self.objRef == weakRef
@@ -97,6 +97,6 @@ def getWeakRef(obj, notifyDead=None):
createRef = WeakMethod
else:
createRef = WeakRef
return createRef(obj, notifyDead)

View File

@@ -3,17 +3,17 @@ Setup pubsub for the *arg1* message protocol. In a default pubsub installation
the default protocol is *kargs*.
This module must be imported before the first ``from pubsub import pub``
statement in the application. Once :mod:pub has been imported, the messaging
protocol cannot be changed (i.e., importing it after the first
``from pubsub import pub`` statement has undefined behavior).
statement in the application. Once :mod:pub has been imported, the messaging
protocol must not be changed (i.e., importing it after the first
``from pubsub import pub`` statement has undefined behavior).
::
from .. import setuparg1
from .. import pub
The *arg1* protocol is identical to the legacy messaging protocol from
first version of pubsub (when it was still part of wxPython) and
is *deprecated*. This module is therefore *deprecated*.
The *arg1* protocol is identical to the legacy messaging protocol from
first version of pubsub (when it was still part of wxPython) and
is *deprecated*. This module is therefore *deprecated*.
"""
"""
@@ -24,10 +24,24 @@ is *deprecated*. This module is therefore *deprecated*.
from . import policies
policies.msgDataProtocol = 'arg1'
import sys
sys.stdout.write("""
======================================================================
*** ATTENTION ***
This messaging protocol is deprecated. This module, and hence arg1
messaging protocol, will be removed in v3.4 of PyPubSub. Please make
the necessary changes to your code so that it no longer requires this
module. The pypubsub documentation provides steps that may be useful
to minimize the chance of introducing bugs in your application.
======================================================================
""")
def enforceArgName(commonName):
"""This will configure pubsub to require that all listeners use
the same argument name (*commonName*) as first parameter. This
is a ueful first step in migrating an application that has been
"""This will configure pubsub to require that all listeners use
the same argument name (*commonName*) as first parameter. This
is a ueful first step in migrating an application that has been
using *arg1* protocol to the more powerful *kwargs* protocol. """
policies.setMsgDataArgName(1, commonName)