Esempio n. 1
0
def disconnect(receiver, signal=Any, sender=Any, weak=True):
	"""Disconnect receiver from sender for signal

	receiver -- the registered receiver to disconnect
	signal -- the registered signal to disconnect
	sender -- the registered sender to disconnect
	weak -- the weakref state to disconnect

	disconnect reverses the process of connect,
	the semantics for the individual elements are
	logically equivalent to a tuple of
	(receiver, signal, sender, weak) used as a key
	to be deleted from the internal routing tables.
	(The actual process is slightly more complex
	but the semantics are basically the same).

	Note:
		Using disconnect is not required to cleanup
		routing when an object is deleted, the framework
		will remove routes for deleted objects
		automatically.  It's only necessary to disconnect
		if you want to stop routing to a live object.
		
	returns None, may raise DispatcherTypeError or
		DispatcherKeyError
	"""
	if signal is None:
		raise errors.DispatcherTypeError(
			'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender)
		)
	if weak: receiver = saferef.safeRef(receiver)
	senderkey = id(sender)
	try:
		signals = connections[senderkey]
		receivers = signals[signal]
	except KeyError:
		raise errors.DispatcherKeyError(
			"""No receivers found for signal %r from sender %r""" %(
				signal,
				sender
			)
		)
	try:
		# also removes from receivers
		_removeOldBackRefs(senderkey, signal, receiver, receivers)
	except ValueError:
		raise errors.DispatcherKeyError(
			"""No connection to receiver %s for signal %s from sender %s""" %(
				receiver,
				signal,
				sender
			)
		)
	_cleanupConnections(senderkey, signal)
Esempio n. 2
0
def connect(receiver, signal=Any, sender=Any, weak=True):
	"""Connect receiver to sender for signal

	receiver -- a callable Python object which is to receive
		messages/signals/events.  Receivers must be hashable
		objects.

		if weak is True, then receiver must be weak-referencable
		(more precisely saferef.safeRef() must be able to create
		a reference to the receiver).
	
		Receivers are fairly flexible in their specification,
		as the machinery in the robustApply module takes care
		of most of the details regarding figuring out appropriate
		subsets of the sent arguments to apply to a given
		receiver.

		Note:
			if receiver is itself a weak reference (a callable),
			it will be de-referenced by the system's machinery,
			so *generally* weak references are not suitable as
			receivers, though some use might be found for the
			facility whereby a higher-level library passes in
			pre-weakrefed receiver references.

	signal -- the signal to which the receiver should respond
	
		if Any, receiver will receive any signal from the
		indicated sender (which might also be Any, but is not
		necessarily Any).
		
		Otherwise must be a hashable Python object other than
		None (DispatcherError raised on None).
		
	sender -- the sender to which the receiver should respond
	
		if Any, receiver will receive the indicated signals
		from any sender.
		
		if Anonymous, receiver will only receive indicated
		signals from send/sendExact which do not specify a
		sender, or specify Anonymous explicitly as the sender.

		Otherwise can be any python object.
		
	weak -- whether to use weak references to the receiver
		By default, the module will attempt to use weak
		references to the receiver objects.  If this parameter
		is false, then strong references will be used.

	returns None, may raise DispatcherTypeError
	"""
	if signal is None:
		raise errors.DispatcherTypeError(
			'Signal cannot be None (receiver=%r sender=%r)'%( receiver,sender)
		)
	if weak:
		receiver = saferef.safeRef(receiver, onDelete=_removeReceiver)
	senderkey = id(sender)
	if connections.has_key(senderkey):
		signals = connections[senderkey]
	else:
		connections[senderkey] = signals = {}
	# Keep track of senders for cleanup.
	# Is Anonymous something we want to clean up?
	if sender not in (None, Anonymous, Any):
		def remove(object, senderkey=senderkey):
			_removeSender(senderkey=senderkey)
		# Skip objects that can not be weakly referenced, which means
		# they won't be automatically cleaned up, but that's too bad.
		try:
			weakSender = weakref.ref(sender, remove)
			senders[senderkey] = weakSender
		except:
			pass
		
	receiverID = id(receiver)
	# get current set, remove any current references to
	# this receiver in the set, including back-references
	if signals.has_key(signal):
		receivers = signals[signal]
		_removeOldBackRefs(senderkey, signal, receiver, receivers)
	else:
		receivers = signals[signal] = []
	try:
		current = sendersBack.get( receiverID )
		if current is None:
			sendersBack[ receiverID ] = current = []
		if senderkey not in current:
			current.append(senderkey)
	except:
		pass

	receivers.append(receiver)