mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-05 11:30:06 +01:00
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:
@@ -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',
|
||||
|
||||
@@ -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_.
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user