diff --git a/wx/lib/pubsub/__init__.py b/wx/lib/pubsub/__init__.py index bace45fc..a7443ab6 100644 --- a/wx/lib/pubsub/__init__.py +++ b/wx/lib/pubsub/__init__.py @@ -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', diff --git a/wx/lib/pubsub/core/callables.py b/wx/lib/pubsub/core/callables.py index e94032ee..f995ff15 100644 --- a/wx/lib/pubsub/core/callables.py +++ b/wx/lib/pubsub/core/callables.py @@ -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_. diff --git a/wx/lib/pubsub/core/weakmethod.py b/wx/lib/pubsub/core/weakmethod.py index d78af756..8c9750e4 100644 --- a/wx/lib/pubsub/core/weakmethod.py +++ b/wx/lib/pubsub/core/weakmethod.py @@ -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) - + diff --git a/wx/lib/pubsub/setuparg1.py b/wx/lib/pubsub/setuparg1.py index da36a3aa..d88f3d46 100644 --- a/wx/lib/pubsub/setuparg1.py +++ b/wx/lib/pubsub/setuparg1.py @@ -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)