<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>pydispatch.dispatcher — SQLObject 3.7.0 documentation</title> <link rel="stylesheet" href="../../_static/bizstyle.css" type="text/css" /> <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> <script type="text/javascript" src="../../_static/documentation_options.js"></script> <script type="text/javascript" src="../../_static/jquery.js"></script> <script type="text/javascript" src="../../_static/underscore.js"></script> <script type="text/javascript" src="../../_static/doctools.js"></script> <script type="text/javascript" src="../../_static/bizstyle.js"></script> <link rel="index" title="Index" href="../../genindex.html" /> <link rel="search" title="Search" href="../../search.html" /> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <!--[if lt IE 9]> <script type="text/javascript" src="_static/css3-mediaqueries.js"></script> <![endif]--> </head><body> <div class="related" role="navigation" aria-label="related navigation"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../../genindex.html" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="../../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li class="nav-item nav-item-0"><a href="../../index.html">SQLObject 3.7.0 documentation</a> »</li> <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> »</li> </ul> </div> <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> <div class="sphinxsidebarwrapper"> <div id="searchbox" style="display: none" role="search"> <h3>Quick search</h3> <div class="searchformwrapper"> <form class="search" action="../../search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body" role="main"> <h1>Source code for pydispatch.dispatcher</h1><div class="highlight"><pre> <span></span><span class="sd">"""Multiple-producer-multiple-consumer signal-dispatching</span> <span class="sd">dispatcher is the core of the PyDispatcher system,</span> <span class="sd">providing the primary API and the core logic for the</span> <span class="sd">system.</span> <span class="sd">Module attributes of note:</span> <span class="sd"> Any -- Singleton used to signal either "Any Sender" or</span> <span class="sd"> "Any Signal". See documentation of the _Any class.</span> <span class="sd"> Anonymous -- Singleton used to signal "Anonymous Sender"</span> <span class="sd"> See documentation of the _Anonymous class.</span> <span class="sd">Internal attributes:</span> <span class="sd"> WEAKREF_TYPES -- tuple of types/classes which represent</span> <span class="sd"> weak references to receivers, and thus must be de-</span> <span class="sd"> referenced on retrieval to retrieve the callable</span> <span class="sd"> object</span> <span class="sd"> connections -- { senderkey (id) : { signal : [receivers...]}}</span> <span class="sd"> senders -- { senderkey (id) : weakref(sender) }</span> <span class="sd"> used for cleaning up sender references on sender</span> <span class="sd"> deletion</span> <span class="sd"> sendersBack -- { receiverkey (id) : [senderkey (id)...] }</span> <span class="sd"> used for cleaning up receiver references on receiver</span> <span class="sd"> deletion, (considerably speeds up the cleanup process</span> <span class="sd"> vs. the original code.)</span> <span class="sd">"""</span> <span class="kn">import</span> <span class="nn">weakref</span> <span class="kn">from</span> <span class="nn">pydispatch</span> <span class="k">import</span> <span class="n">saferef</span><span class="p">,</span> <span class="n">robustapply</span><span class="p">,</span> <span class="n">errors</span> <span class="k">class</span> <span class="nc">_Parameter</span><span class="p">:</span> <span class="sd">"""Used to represent default parameter values."""</span> <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span> <span class="k">class</span> <span class="nc">_Any</span><span class="p">(</span><span class="n">_Parameter</span><span class="p">):</span> <span class="sd">"""Singleton used to signal either "Any Sender" or "Any Signal"</span> <span class="sd"> The Any object can be used with connect, disconnect,</span> <span class="sd"> send, or sendExact to signal that the parameter given</span> <span class="sd"> Any should react to all senders/signals, not just</span> <span class="sd"> a particular sender/signal.</span> <span class="sd"> """</span> <span class="n">Any</span> <span class="o">=</span> <span class="n">_Any</span><span class="p">()</span> <span class="k">class</span> <span class="nc">_Anonymous</span><span class="p">(</span><span class="n">_Parameter</span><span class="p">):</span> <span class="sd">"""Singleton used to signal "Anonymous Sender"</span> <span class="sd"> The Anonymous object is used to signal that the sender</span> <span class="sd"> of a message is not specified (as distinct from being</span> <span class="sd"> "any sender"). Registering callbacks for Anonymous</span> <span class="sd"> will only receive messages sent without senders. Sending</span> <span class="sd"> with anonymous will only send messages to those receivers</span> <span class="sd"> registered for Any or Anonymous.</span> <span class="sd"> Note:</span> <span class="sd"> The default sender for connect is Any, while the</span> <span class="sd"> default sender for send is Anonymous. This has</span> <span class="sd"> the effect that if you do not specify any senders</span> <span class="sd"> in either function then all messages are routed</span> <span class="sd"> as though there was a single sender (Anonymous)</span> <span class="sd"> being used everywhere.</span> <span class="sd"> """</span> <span class="n">Anonymous</span> <span class="o">=</span> <span class="n">_Anonymous</span><span class="p">()</span> <span class="n">WEAKREF_TYPES</span> <span class="o">=</span> <span class="p">(</span><span class="n">weakref</span><span class="o">.</span><span class="n">ReferenceType</span><span class="p">,</span> <span class="n">saferef</span><span class="o">.</span><span class="n">BoundMethodWeakref</span><span class="p">)</span> <span class="n">connections</span> <span class="o">=</span> <span class="p">{}</span> <span class="n">senders</span> <span class="o">=</span> <span class="p">{}</span> <span class="n">sendersBack</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">def</span> <span class="nf">connect</span><span class="p">(</span><span class="n">receiver</span><span class="p">,</span> <span class="n">signal</span><span class="o">=</span><span class="n">Any</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">Any</span><span class="p">,</span> <span class="n">weak</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span> <span class="sd">"""Connect receiver to sender for signal</span> <span class="sd"> receiver -- a callable Python object which is to receive</span> <span class="sd"> messages/signals/events. Receivers must be hashable</span> <span class="sd"> objects.</span> <span class="sd"> if weak is True, then receiver must be weak-referencable</span> <span class="sd"> (more precisely saferef.safeRef() must be able to create</span> <span class="sd"> a reference to the receiver).</span> <span class="sd"> </span> <span class="sd"> Receivers are fairly flexible in their specification,</span> <span class="sd"> as the machinery in the robustApply module takes care</span> <span class="sd"> of most of the details regarding figuring out appropriate</span> <span class="sd"> subsets of the sent arguments to apply to a given</span> <span class="sd"> receiver.</span> <span class="sd"> Note:</span> <span class="sd"> if receiver is itself a weak reference (a callable),</span> <span class="sd"> it will be de-referenced by the system's machinery,</span> <span class="sd"> so *generally* weak references are not suitable as</span> <span class="sd"> receivers, though some use might be found for the</span> <span class="sd"> facility whereby a higher-level library passes in</span> <span class="sd"> pre-weakrefed receiver references.</span> <span class="sd"> signal -- the signal to which the receiver should respond</span> <span class="sd"> </span> <span class="sd"> if Any, receiver will receive any signal from the</span> <span class="sd"> indicated sender (which might also be Any, but is not</span> <span class="sd"> necessarily Any).</span> <span class="sd"> </span> <span class="sd"> Otherwise must be a hashable Python object other than</span> <span class="sd"> None (DispatcherError raised on None).</span> <span class="sd"> </span> <span class="sd"> sender -- the sender to which the receiver should respond</span> <span class="sd"> </span> <span class="sd"> if Any, receiver will receive the indicated signals</span> <span class="sd"> from any sender.</span> <span class="sd"> </span> <span class="sd"> if Anonymous, receiver will only receive indicated</span> <span class="sd"> signals from send/sendExact which do not specify a</span> <span class="sd"> sender, or specify Anonymous explicitly as the sender.</span> <span class="sd"> Otherwise can be any python object.</span> <span class="sd"> </span> <span class="sd"> weak -- whether to use weak references to the receiver</span> <span class="sd"> By default, the module will attempt to use weak</span> <span class="sd"> references to the receiver objects. If this parameter</span> <span class="sd"> is false, then strong references will be used.</span> <span class="sd"> returns None, may raise DispatcherTypeError</span> <span class="sd"> """</span> <span class="k">if</span> <span class="n">signal</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="k">raise</span> <span class="n">errors</span><span class="o">.</span><span class="n">DispatcherTypeError</span><span class="p">(</span> <span class="s1">'Signal cannot be None (receiver=</span><span class="si">%r</span><span class="s1"> sender=</span><span class="si">%r</span><span class="s1">)'</span><span class="o">%</span><span class="p">(</span> <span class="n">receiver</span><span class="p">,</span><span class="n">sender</span><span class="p">)</span> <span class="p">)</span> <span class="k">if</span> <span class="n">weak</span><span class="p">:</span> <span class="n">receiver</span> <span class="o">=</span> <span class="n">saferef</span><span class="o">.</span><span class="n">safeRef</span><span class="p">(</span><span class="n">receiver</span><span class="p">,</span> <span class="n">onDelete</span><span class="o">=</span><span class="n">_removeReceiver</span><span class="p">)</span> <span class="n">senderkey</span> <span class="o">=</span> <span class="nb">id</span><span class="p">(</span><span class="n">sender</span><span class="p">)</span> <span class="k">if</span> <span class="n">senderkey</span> <span class="ow">in</span> <span class="n">connections</span><span class="p">:</span> <span class="n">signals</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="n">senderkey</span><span class="p">]</span> <span class="k">else</span><span class="p">:</span> <span class="n">connections</span><span class="p">[</span><span class="n">senderkey</span><span class="p">]</span> <span class="o">=</span> <span class="n">signals</span> <span class="o">=</span> <span class="p">{}</span> <span class="c1"># Keep track of senders for cleanup.</span> <span class="c1"># Is Anonymous something we want to clean up?</span> <span class="k">if</span> <span class="n">sender</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">Anonymous</span><span class="p">,</span> <span class="n">Any</span><span class="p">):</span> <span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="nb">object</span><span class="p">,</span> <span class="n">senderkey</span><span class="o">=</span><span class="n">senderkey</span><span class="p">):</span> <span class="n">_removeSender</span><span class="p">(</span><span class="n">senderkey</span><span class="o">=</span><span class="n">senderkey</span><span class="p">)</span> <span class="c1"># Skip objects that can not be weakly referenced, which means</span> <span class="c1"># they won't be automatically cleaned up, but that's too bad.</span> <span class="k">try</span><span class="p">:</span> <span class="n">weakSender</span> <span class="o">=</span> <span class="n">weakref</span><span class="o">.</span><span class="n">ref</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">remove</span><span class="p">)</span> <span class="n">senders</span><span class="p">[</span><span class="n">senderkey</span><span class="p">]</span> <span class="o">=</span> <span class="n">weakSender</span> <span class="k">except</span><span class="p">:</span> <span class="k">pass</span> <span class="n">receiverID</span> <span class="o">=</span> <span class="nb">id</span><span class="p">(</span><span class="n">receiver</span><span class="p">)</span> <span class="c1"># get current set, remove any current references to</span> <span class="c1"># this receiver in the set, including back-references</span> <span class="k">if</span> <span class="n">signal</span> <span class="ow">in</span> <span class="n">signals</span><span class="p">:</span> <span class="n">receivers</span> <span class="o">=</span> <span class="n">signals</span><span class="p">[</span><span class="n">signal</span><span class="p">]</span> <span class="n">_removeOldBackRefs</span><span class="p">(</span><span class="n">senderkey</span><span class="p">,</span> <span class="n">signal</span><span class="p">,</span> <span class="n">receiver</span><span class="p">,</span> <span class="n">receivers</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="n">receivers</span> <span class="o">=</span> <span class="n">signals</span><span class="p">[</span><span class="n">signal</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">try</span><span class="p">:</span> <span class="n">current</span> <span class="o">=</span> <span class="n">sendersBack</span><span class="o">.</span><span class="n">get</span><span class="p">(</span> <span class="n">receiverID</span> <span class="p">)</span> <span class="k">if</span> <span class="n">current</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">sendersBack</span><span class="p">[</span> <span class="n">receiverID</span> <span class="p">]</span> <span class="o">=</span> <span class="n">current</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">if</span> <span class="n">senderkey</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">current</span><span class="p">:</span> <span class="n">current</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">senderkey</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="k">pass</span> <span class="n">receivers</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">receiver</span><span class="p">)</span> <span class="k">def</span> <span class="nf">disconnect</span><span class="p">(</span><span class="n">receiver</span><span class="p">,</span> <span class="n">signal</span><span class="o">=</span><span class="n">Any</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">Any</span><span class="p">,</span> <span class="n">weak</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span> <span class="sd">"""Disconnect receiver from sender for signal</span> <span class="sd"> receiver -- the registered receiver to disconnect</span> <span class="sd"> signal -- the registered signal to disconnect</span> <span class="sd"> sender -- the registered sender to disconnect</span> <span class="sd"> weak -- the weakref state to disconnect</span> <span class="sd"> disconnect reverses the process of connect,</span> <span class="sd"> the semantics for the individual elements are</span> <span class="sd"> logically equivalent to a tuple of</span> <span class="sd"> (receiver, signal, sender, weak) used as a key</span> <span class="sd"> to be deleted from the internal routing tables.</span> <span class="sd"> (The actual process is slightly more complex</span> <span class="sd"> but the semantics are basically the same).</span> <span class="sd"> Note:</span> <span class="sd"> Using disconnect is not required to cleanup</span> <span class="sd"> routing when an object is deleted, the framework</span> <span class="sd"> will remove routes for deleted objects</span> <span class="sd"> automatically. It's only necessary to disconnect</span> <span class="sd"> if you want to stop routing to a live object.</span> <span class="sd"> </span> <span class="sd"> returns None, may raise DispatcherTypeError or</span> <span class="sd"> DispatcherKeyError</span> <span class="sd"> """</span> <span class="k">if</span> <span class="n">signal</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="k">raise</span> <span class="n">errors</span><span class="o">.</span><span class="n">DispatcherTypeError</span><span class="p">(</span> <span class="s1">'Signal cannot be None (receiver=</span><span class="si">%r</span><span class="s1"> sender=</span><span class="si">%r</span><span class="s1">)'</span><span class="o">%</span><span class="p">(</span> <span class="n">receiver</span><span class="p">,</span><span class="n">sender</span><span class="p">)</span> <span class="p">)</span> <span class="k">if</span> <span class="n">weak</span><span class="p">:</span> <span class="n">receiver</span> <span class="o">=</span> <span class="n">saferef</span><span class="o">.</span><span class="n">safeRef</span><span class="p">(</span><span class="n">receiver</span><span class="p">)</span> <span class="n">senderkey</span> <span class="o">=</span> <span class="nb">id</span><span class="p">(</span><span class="n">sender</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">signals</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="n">senderkey</span><span class="p">]</span> <span class="n">receivers</span> <span class="o">=</span> <span class="n">signals</span><span class="p">[</span><span class="n">signal</span><span class="p">]</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="k">raise</span> <span class="n">errors</span><span class="o">.</span><span class="n">DispatcherKeyError</span><span class="p">(</span> <span class="sd">"""No receivers found for signal %r from sender %r"""</span> <span class="o">%</span><span class="p">(</span> <span class="n">signal</span><span class="p">,</span> <span class="n">sender</span> <span class="p">)</span> <span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="c1"># also removes from receivers</span> <span class="n">_removeOldBackRefs</span><span class="p">(</span><span class="n">senderkey</span><span class="p">,</span> <span class="n">signal</span><span class="p">,</span> <span class="n">receiver</span><span class="p">,</span> <span class="n">receivers</span><span class="p">)</span> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="k">raise</span> <span class="n">errors</span><span class="o">.</span><span class="n">DispatcherKeyError</span><span class="p">(</span> <span class="sd">"""No connection to receiver %s for signal %s from sender %s"""</span> <span class="o">%</span><span class="p">(</span> <span class="n">receiver</span><span class="p">,</span> <span class="n">signal</span><span class="p">,</span> <span class="n">sender</span> <span class="p">)</span> <span class="p">)</span> <span class="n">_cleanupConnections</span><span class="p">(</span><span class="n">senderkey</span><span class="p">,</span> <span class="n">signal</span><span class="p">)</span> <span class="k">def</span> <span class="nf">getReceivers</span><span class="p">(</span> <span class="n">sender</span> <span class="o">=</span> <span class="n">Any</span><span class="p">,</span> <span class="n">signal</span> <span class="o">=</span> <span class="n">Any</span> <span class="p">):</span> <span class="sd">"""Get list of receivers from global tables</span> <span class="sd"> This utility function allows you to retrieve the</span> <span class="sd"> raw list of receivers from the connections table</span> <span class="sd"> for the given sender and signal pair.</span> <span class="sd"> Note:</span> <span class="sd"> there is no guarantee that this is the actual list</span> <span class="sd"> stored in the connections table, so the value</span> <span class="sd"> should be treated as a simple iterable/truth value</span> <span class="sd"> rather than, for instance a list to which you</span> <span class="sd"> might append new records.</span> <span class="sd"> Normally you would use liveReceivers( getReceivers( ...))</span> <span class="sd"> to retrieve the actual receiver objects as an iterable</span> <span class="sd"> object.</span> <span class="sd"> """</span> <span class="k">try</span><span class="p">:</span> <span class="k">return</span> <span class="n">connections</span><span class="p">[</span><span class="nb">id</span><span class="p">(</span><span class="n">sender</span><span class="p">)][</span><span class="n">signal</span><span class="p">]</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="k">return</span> <span class="p">[]</span> <span class="k">def</span> <span class="nf">liveReceivers</span><span class="p">(</span><span class="n">receivers</span><span class="p">):</span> <span class="sd">"""Filter sequence of receivers to get resolved, live receivers</span> <span class="sd"> This is a generator which will iterate over</span> <span class="sd"> the passed sequence, checking for weak references</span> <span class="sd"> and resolving them, then returning all live</span> <span class="sd"> receivers.</span> <span class="sd"> """</span> <span class="k">for</span> <span class="n">receiver</span> <span class="ow">in</span> <span class="n">receivers</span><span class="p">:</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span> <span class="n">receiver</span><span class="p">,</span> <span class="n">WEAKREF_TYPES</span><span class="p">):</span> <span class="c1"># Dereference the weak reference.</span> <span class="n">receiver</span> <span class="o">=</span> <span class="n">receiver</span><span class="p">()</span> <span class="k">if</span> <span class="n">receiver</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="k">yield</span> <span class="n">receiver</span> <span class="k">else</span><span class="p">:</span> <span class="k">yield</span> <span class="n">receiver</span> <span class="k">def</span> <span class="nf">getAllReceivers</span><span class="p">(</span> <span class="n">sender</span> <span class="o">=</span> <span class="n">Any</span><span class="p">,</span> <span class="n">signal</span> <span class="o">=</span> <span class="n">Any</span> <span class="p">):</span> <span class="sd">"""Get list of all receivers from global tables</span> <span class="sd"> This gets all receivers which should receive</span> <span class="sd"> the given signal from sender, each receiver should</span> <span class="sd"> be produced only once by the resulting generator</span> <span class="sd"> """</span> <span class="n">receivers</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">for</span> <span class="nb">set</span> <span class="ow">in</span> <span class="p">(</span> <span class="c1"># Get receivers that receive *this* signal from *this* sender.</span> <span class="n">getReceivers</span><span class="p">(</span> <span class="n">sender</span><span class="p">,</span> <span class="n">signal</span> <span class="p">),</span> <span class="c1"># Add receivers that receive *any* signal from *this* sender.</span> <span class="n">getReceivers</span><span class="p">(</span> <span class="n">sender</span><span class="p">,</span> <span class="n">Any</span> <span class="p">),</span> <span class="c1"># Add receivers that receive *this* signal from *any* sender.</span> <span class="n">getReceivers</span><span class="p">(</span> <span class="n">Any</span><span class="p">,</span> <span class="n">signal</span> <span class="p">),</span> <span class="c1"># Add receivers that receive *any* signal from *any* sender.</span> <span class="n">getReceivers</span><span class="p">(</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Any</span> <span class="p">),</span> <span class="p">):</span> <span class="k">for</span> <span class="n">receiver</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">:</span> <span class="k">if</span> <span class="n">receiver</span><span class="p">:</span> <span class="c1"># filter out dead instance-method weakrefs</span> <span class="k">try</span><span class="p">:</span> <span class="k">if</span> <span class="n">receiver</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">receivers</span><span class="p">:</span> <span class="n">receivers</span><span class="p">[</span><span class="n">receiver</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">yield</span> <span class="n">receiver</span> <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> <span class="c1"># dead weakrefs raise TypeError on hash...</span> <span class="k">pass</span> <div class="viewcode-block" id="send"><a class="viewcode-back" href="../../api/sqlobject.events.html#sqlobject.events.send">[docs]</a><span class="k">def</span> <span class="nf">send</span><span class="p">(</span><span class="n">signal</span><span class="o">=</span><span class="n">Any</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">Anonymous</span><span class="p">,</span> <span class="o">*</span><span class="n">arguments</span><span class="p">,</span> <span class="o">**</span><span class="n">named</span><span class="p">):</span> <span class="sd">"""Send signal from sender to all connected receivers.</span> <span class="sd"> </span> <span class="sd"> signal -- (hashable) signal value, see connect for details</span> <span class="sd"> sender -- the sender of the signal</span> <span class="sd"> </span> <span class="sd"> if Any, only receivers registered for Any will receive</span> <span class="sd"> the message.</span> <span class="sd"> if Anonymous, only receivers registered to receive</span> <span class="sd"> messages from Anonymous or Any will receive the message</span> <span class="sd"> Otherwise can be any python object (normally one</span> <span class="sd"> registered with a connect if you actually want</span> <span class="sd"> something to occur).</span> <span class="sd"> arguments -- positional arguments which will be passed to</span> <span class="sd"> *all* receivers. Note that this may raise TypeErrors</span> <span class="sd"> if the receivers do not allow the particular arguments.</span> <span class="sd"> Note also that arguments are applied before named</span> <span class="sd"> arguments, so they should be used with care.</span> <span class="sd"> named -- named arguments which will be filtered according</span> <span class="sd"> to the parameters of the receivers to only provide those</span> <span class="sd"> acceptable to the receiver.</span> <span class="sd"> Return a list of tuple pairs [(receiver, response), ... ]</span> <span class="sd"> if any receiver raises an error, the error propagates back</span> <span class="sd"> through send, terminating the dispatch loop, so it is quite</span> <span class="sd"> possible to not have all receivers called if a raises an</span> <span class="sd"> error.</span> <span class="sd"> """</span> <span class="c1"># Call each receiver with whatever arguments it can accept.</span> <span class="c1"># Return a list of tuple pairs [(receiver, response), ... ].</span> <span class="n">responses</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">receiver</span> <span class="ow">in</span> <span class="n">liveReceivers</span><span class="p">(</span><span class="n">getAllReceivers</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">signal</span><span class="p">)):</span> <span class="n">response</span> <span class="o">=</span> <span class="n">robustapply</span><span class="o">.</span><span class="n">robustApply</span><span class="p">(</span> <span class="n">receiver</span><span class="p">,</span> <span class="n">signal</span><span class="o">=</span><span class="n">signal</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">sender</span><span class="p">,</span> <span class="o">*</span><span class="n">arguments</span><span class="p">,</span> <span class="o">**</span><span class="n">named</span> <span class="p">)</span> <span class="n">responses</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">receiver</span><span class="p">,</span> <span class="n">response</span><span class="p">))</span> <span class="k">return</span> <span class="n">responses</span> <span class="k">def</span> <span class="nf">sendExact</span><span class="p">(</span> <span class="n">signal</span><span class="o">=</span><span class="n">Any</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">Anonymous</span><span class="p">,</span> <span class="o">*</span><span class="n">arguments</span><span class="p">,</span> <span class="o">**</span><span class="n">named</span> <span class="p">):</span></div> <span class="sd">"""Send signal only to those receivers registered for exact message</span> <span class="sd"> sendExact allows for avoiding Any/Anonymous registered</span> <span class="sd"> handlers, sending only to those receivers explicitly</span> <span class="sd"> registered for a particular signal on a particular</span> <span class="sd"> sender.</span> <span class="sd"> """</span> <span class="n">responses</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">receiver</span> <span class="ow">in</span> <span class="n">liveReceivers</span><span class="p">(</span><span class="n">getReceivers</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">signal</span><span class="p">)):</span> <span class="n">response</span> <span class="o">=</span> <span class="n">robustapply</span><span class="o">.</span><span class="n">robustApply</span><span class="p">(</span> <span class="n">receiver</span><span class="p">,</span> <span class="n">signal</span><span class="o">=</span><span class="n">signal</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">sender</span><span class="p">,</span> <span class="o">*</span><span class="n">arguments</span><span class="p">,</span> <span class="o">**</span><span class="n">named</span> <span class="p">)</span> <span class="n">responses</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">receiver</span><span class="p">,</span> <span class="n">response</span><span class="p">))</span> <span class="k">return</span> <span class="n">responses</span> <span class="k">def</span> <span class="nf">_removeReceiver</span><span class="p">(</span><span class="n">receiver</span><span class="p">):</span> <span class="sd">"""Remove receiver from connections."""</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">sendersBack</span><span class="p">:</span> <span class="c1"># During module cleanup the mapping will be replaced with None</span> <span class="k">return</span> <span class="kc">False</span> <span class="n">backKey</span> <span class="o">=</span> <span class="nb">id</span><span class="p">(</span><span class="n">receiver</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">backSet</span> <span class="o">=</span> <span class="n">sendersBack</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">backKey</span><span class="p">)</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="k">return</span> <span class="kc">False</span> <span class="k">else</span><span class="p">:</span> <span class="k">for</span> <span class="n">senderkey</span> <span class="ow">in</span> <span class="n">backSet</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="n">signals</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">connections</span><span class="p">[</span><span class="n">senderkey</span><span class="p">]</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="k">pass</span> <span class="k">else</span><span class="p">:</span> <span class="k">for</span> <span class="n">signal</span> <span class="ow">in</span> <span class="n">signals</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="n">receivers</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="n">senderkey</span><span class="p">][</span><span class="n">signal</span><span class="p">]</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="k">pass</span> <span class="k">else</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="n">receivers</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span> <span class="n">receiver</span> <span class="p">)</span> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span> <span class="k">pass</span> <span class="n">_cleanupConnections</span><span class="p">(</span><span class="n">senderkey</span><span class="p">,</span> <span class="n">signal</span><span class="p">)</span> <span class="k">def</span> <span class="nf">_cleanupConnections</span><span class="p">(</span><span class="n">senderkey</span><span class="p">,</span> <span class="n">signal</span><span class="p">):</span> <span class="sd">"""Delete any empty signals for senderkey. Delete senderkey if empty."""</span> <span class="k">try</span><span class="p">:</span> <span class="n">receivers</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="n">senderkey</span><span class="p">][</span><span class="n">signal</span><span class="p">]</span> <span class="k">except</span><span class="p">:</span> <span class="k">pass</span> <span class="k">else</span><span class="p">:</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">receivers</span><span class="p">:</span> <span class="c1"># No more connected receivers. Therefore, remove the signal.</span> <span class="k">try</span><span class="p">:</span> <span class="n">signals</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="n">senderkey</span><span class="p">]</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="k">pass</span> <span class="k">else</span><span class="p">:</span> <span class="k">del</span> <span class="n">signals</span><span class="p">[</span><span class="n">signal</span><span class="p">]</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">signals</span><span class="p">:</span> <span class="c1"># No more signal connections. Therefore, remove the sender.</span> <span class="n">_removeSender</span><span class="p">(</span><span class="n">senderkey</span><span class="p">)</span> <span class="k">def</span> <span class="nf">_removeSender</span><span class="p">(</span><span class="n">senderkey</span><span class="p">):</span> <span class="sd">"""Remove senderkey from connections."""</span> <span class="n">_removeBackrefs</span><span class="p">(</span><span class="n">senderkey</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="k">del</span> <span class="n">connections</span><span class="p">[</span><span class="n">senderkey</span><span class="p">]</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="k">pass</span> <span class="c1"># Senderkey will only be in senders dictionary if sender </span> <span class="c1"># could be weakly referenced.</span> <span class="k">try</span><span class="p">:</span> <span class="k">del</span> <span class="n">senders</span><span class="p">[</span><span class="n">senderkey</span><span class="p">]</span> <span class="k">except</span><span class="p">:</span> <span class="k">pass</span> <span class="k">def</span> <span class="nf">_removeBackrefs</span><span class="p">(</span> <span class="n">senderkey</span><span class="p">):</span> <span class="sd">"""Remove all back-references to this senderkey"""</span> <span class="k">try</span><span class="p">:</span> <span class="n">signals</span> <span class="o">=</span> <span class="n">connections</span><span class="p">[</span><span class="n">senderkey</span><span class="p">]</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="n">signals</span> <span class="o">=</span> <span class="kc">None</span> <span class="k">else</span><span class="p">:</span> <span class="n">items</span> <span class="o">=</span> <span class="n">signals</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">def</span> <span class="nf">allReceivers</span><span class="p">(</span> <span class="p">):</span> <span class="k">for</span> <span class="n">signal</span><span class="p">,</span><span class="nb">set</span> <span class="ow">in</span> <span class="n">items</span><span class="p">:</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">:</span> <span class="k">yield</span> <span class="n">item</span> <span class="k">for</span> <span class="n">receiver</span> <span class="ow">in</span> <span class="n">allReceivers</span><span class="p">():</span> <span class="n">_killBackref</span><span class="p">(</span> <span class="n">receiver</span><span class="p">,</span> <span class="n">senderkey</span> <span class="p">)</span> <span class="k">def</span> <span class="nf">_removeOldBackRefs</span><span class="p">(</span><span class="n">senderkey</span><span class="p">,</span> <span class="n">signal</span><span class="p">,</span> <span class="n">receiver</span><span class="p">,</span> <span class="n">receivers</span><span class="p">):</span> <span class="sd">"""Kill old sendersBack references from receiver</span> <span class="sd"> This guards against multiple registration of the same</span> <span class="sd"> receiver for a given signal and sender leaking memory</span> <span class="sd"> as old back reference records build up.</span> <span class="sd"> Also removes old receiver instance from receivers</span> <span class="sd"> """</span> <span class="k">try</span><span class="p">:</span> <span class="n">index</span> <span class="o">=</span> <span class="n">receivers</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">receiver</span><span class="p">)</span> <span class="c1"># need to scan back references here and remove senderkey</span> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="k">return</span> <span class="kc">False</span> <span class="k">else</span><span class="p">:</span> <span class="n">oldReceiver</span> <span class="o">=</span> <span class="n">receivers</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="k">del</span> <span class="n">receivers</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="n">found</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">signals</span> <span class="o">=</span> <span class="n">connections</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">signal</span><span class="p">)</span> <span class="k">if</span> <span class="n">signals</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="k">for</span> <span class="n">sig</span><span class="p">,</span><span class="n">recs</span> <span class="ow">in</span> <span class="n">connections</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">signal</span><span class="p">,{})</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> <span class="k">if</span> <span class="n">sig</span> <span class="o">!=</span> <span class="n">signal</span><span class="p">:</span> <span class="k">for</span> <span class="n">rec</span> <span class="ow">in</span> <span class="n">recs</span><span class="p">:</span> <span class="k">if</span> <span class="n">rec</span> <span class="ow">is</span> <span class="n">oldReceiver</span><span class="p">:</span> <span class="n">found</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">break</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">found</span><span class="p">:</span> <span class="n">_killBackref</span><span class="p">(</span> <span class="n">oldReceiver</span><span class="p">,</span> <span class="n">senderkey</span> <span class="p">)</span> <span class="k">return</span> <span class="kc">True</span> <span class="k">return</span> <span class="kc">False</span> <span class="k">def</span> <span class="nf">_killBackref</span><span class="p">(</span> <span class="n">receiver</span><span class="p">,</span> <span class="n">senderkey</span> <span class="p">):</span> <span class="sd">"""Do the actual removal of back reference from receiver to senderkey"""</span> <span class="n">receiverkey</span> <span class="o">=</span> <span class="nb">id</span><span class="p">(</span><span class="n">receiver</span><span class="p">)</span> <span class="nb">set</span> <span class="o">=</span> <span class="n">sendersBack</span><span class="o">.</span><span class="n">get</span><span class="p">(</span> <span class="n">receiverkey</span><span class="p">,</span> <span class="p">()</span> <span class="p">)</span> <span class="k">while</span> <span class="n">senderkey</span> <span class="ow">in</span> <span class="nb">set</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="nb">set</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span> <span class="n">senderkey</span> <span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="k">break</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">set</span><span class="p">:</span> <span class="k">try</span><span class="p">:</span> <span class="k">del</span> <span class="n">sendersBack</span><span class="p">[</span> <span class="n">receiverkey</span> <span class="p">]</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="k">pass</span> <span class="k">return</span> <span class="kc">True</span> </pre></div> </div> </div> </div> <div class="clearer"></div> </div> <div class="related" role="navigation" aria-label="related navigation"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../../genindex.html" title="General Index" >index</a></li> <li class="right" > <a href="../../py-modindex.html" title="Python Module Index" >modules</a> |</li> <li class="nav-item nav-item-0"><a href="../../index.html">SQLObject 3.7.0 documentation</a> »</li> <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> »</li> </ul> </div> <div class="footer" role="contentinfo"> © Copyright 2004-2018, Ian Bicking and contributors. Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.4. </div> </body> </html>