evennia/docs/latest/_modules/weakref.html
Evennia docbuilder action 76d95c253e Updated HTML docs.
2026-01-12 16:26:53 +00:00

838 lines
No EOL
97 KiB
HTML

<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>weakref &#8212; Evennia latest documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=d75fae25" />
<link rel="stylesheet" type="text/css" href="../_static/nature.css?v=279e0f84" />
<link rel="stylesheet" type="text/css" href="../_static/custom.css?v=e4a91a55" />
<script src="../_static/documentation_options.js?v=c6e86fd7"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="icon" href="../_static/favicon.ico"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
</head><body>
<div class="related" role="navigation" aria-label="Related">
<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">Evennia</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Module code</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">weakref</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for weakref</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;Weak reference support for Python.</span>
<span class="sd">This module is an implementation of PEP 205:</span>
<span class="sd">https://peps.python.org/pep-0205/</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="c1"># Naming convention: Variables named &quot;wr&quot; are weak reference objects;</span>
<span class="c1"># they are called this instead of &quot;ref&quot; to avoid name collisions with</span>
<span class="c1"># the module-global ref() function imported from _weakref.</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">_weakref</span><span class="w"> </span><span class="kn">import</span> <span class="p">(</span>
<span class="n">getweakrefcount</span><span class="p">,</span>
<span class="n">getweakrefs</span><span class="p">,</span>
<span class="n">ref</span><span class="p">,</span>
<span class="n">proxy</span><span class="p">,</span>
<span class="n">CallableProxyType</span><span class="p">,</span>
<span class="n">ProxyType</span><span class="p">,</span>
<span class="n">ReferenceType</span><span class="p">,</span>
<span class="n">_remove_dead_weakref</span><span class="p">)</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">_weakrefset</span><span class="w"> </span><span class="kn">import</span> <span class="n">WeakSet</span><span class="p">,</span> <span class="n">_IterationGuard</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">_collections_abc</span> <span class="c1"># Import after _weakref to avoid circular import.</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">sys</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">itertools</span>
<span class="n">ProxyTypes</span> <span class="o">=</span> <span class="p">(</span><span class="n">ProxyType</span><span class="p">,</span> <span class="n">CallableProxyType</span><span class="p">)</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;ref&quot;</span><span class="p">,</span> <span class="s2">&quot;proxy&quot;</span><span class="p">,</span> <span class="s2">&quot;getweakrefcount&quot;</span><span class="p">,</span> <span class="s2">&quot;getweakrefs&quot;</span><span class="p">,</span>
<span class="s2">&quot;WeakKeyDictionary&quot;</span><span class="p">,</span> <span class="s2">&quot;ReferenceType&quot;</span><span class="p">,</span> <span class="s2">&quot;ProxyType&quot;</span><span class="p">,</span>
<span class="s2">&quot;CallableProxyType&quot;</span><span class="p">,</span> <span class="s2">&quot;ProxyTypes&quot;</span><span class="p">,</span> <span class="s2">&quot;WeakValueDictionary&quot;</span><span class="p">,</span>
<span class="s2">&quot;WeakSet&quot;</span><span class="p">,</span> <span class="s2">&quot;WeakMethod&quot;</span><span class="p">,</span> <span class="s2">&quot;finalize&quot;</span><span class="p">]</span>
<span class="n">_collections_abc</span><span class="o">.</span><span class="n">MutableSet</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">WeakSet</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">WeakMethod</span><span class="p">(</span><span class="n">ref</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A custom `weakref.ref` subclass which simulates a weak reference to</span>
<span class="sd"> a bound method, working around the lifetime problem of bound methods.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="vm">__slots__</span> <span class="o">=</span> <span class="s2">&quot;_func_ref&quot;</span><span class="p">,</span> <span class="s2">&quot;_meth_type&quot;</span><span class="p">,</span> <span class="s2">&quot;_alive&quot;</span><span class="p">,</span> <span class="s2">&quot;__weakref__&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">meth</span><span class="p">,</span> <span class="n">callback</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">meth</span><span class="o">.</span><span class="vm">__self__</span>
<span class="n">func</span> <span class="o">=</span> <span class="n">meth</span><span class="o">.</span><span class="vm">__func__</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">&quot;argument should be a bound method, not </span><span class="si">{}</span><span class="s2">&quot;</span>
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">meth</span><span class="p">)))</span> <span class="kn">from</span><span class="w"> </span><span class="kc">None</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_cb</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
<span class="c1"># The self-weakref trick is needed to avoid creating a reference</span>
<span class="c1"># cycle.</span>
<span class="bp">self</span> <span class="o">=</span> <span class="n">self_wr</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_alive</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_alive</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">callback</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">callback</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="bp">self</span> <span class="o">=</span> <span class="n">ref</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">_cb</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_func_ref</span> <span class="o">=</span> <span class="n">ref</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="n">_cb</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_meth_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">meth</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_alive</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">self_wr</span> <span class="o">=</span> <span class="n">ref</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="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">obj</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__call__</span><span class="p">()</span>
<span class="n">func</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_func_ref</span><span class="p">()</span>
<span class="k">if</span> <span class="n">obj</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">func</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_meth_type</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="n">obj</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">WeakMethod</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_alive</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">other</span><span class="o">.</span><span class="n">_alive</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span> <span class="ow">is</span> <span class="n">other</span>
<span class="k">return</span> <span class="n">ref</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_func_ref</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_func_ref</span>
<span class="k">return</span> <span class="bp">NotImplemented</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">WeakMethod</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_alive</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">other</span><span class="o">.</span><span class="n">_alive</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">other</span>
<span class="k">return</span> <span class="n">ref</span><span class="o">.</span><span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_func_ref</span> <span class="o">!=</span> <span class="n">other</span><span class="o">.</span><span class="n">_func_ref</span>
<span class="k">return</span> <span class="bp">NotImplemented</span>
<span class="fm">__hash__</span> <span class="o">=</span> <span class="n">ref</span><span class="o">.</span><span class="fm">__hash__</span>
<span class="k">class</span><span class="w"> </span><span class="nc">WeakValueDictionary</span><span class="p">(</span><span class="n">_collections_abc</span><span class="o">.</span><span class="n">MutableMapping</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Mapping class that references values weakly.</span>
<span class="sd"> Entries in the dictionary will be discarded when no strong</span>
<span class="sd"> reference to the value exists anymore</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># We inherit the constructor without worrying about the input</span>
<span class="c1"># dictionary; since it uses our .update() method, we get the right</span>
<span class="c1"># checks (if the other dictionary is a WeakValueDictionary,</span>
<span class="c1"># objects are unwrapped on the way out, and we always wrap on the</span>
<span class="c1"># way in).</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="o">=</span><span class="p">(),</span> <span class="o">/</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
<span class="k">def</span><span class="w"> </span><span class="nf">remove</span><span class="p">(</span><span class="n">wr</span><span class="p">,</span> <span class="n">selfref</span><span class="o">=</span><span class="n">ref</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="n">_atomic_removal</span><span class="o">=</span><span class="n">_remove_dead_weakref</span><span class="p">):</span>
<span class="bp">self</span> <span class="o">=</span> <span class="n">selfref</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_iterating</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">wr</span><span class="o">.</span><span class="n">key</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># Atomic removal is necessary since this function</span>
<span class="c1"># can be called asynchronously by the GC</span>
<span class="n">_atomic_removal</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">wr</span><span class="o">.</span><span class="n">key</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_remove</span> <span class="o">=</span> <span class="n">remove</span>
<span class="c1"># A list of keys to be removed</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span> <span class="o">=</span> <span class="p">[]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_iterating</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_commit_removals</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_atomic_removal</span><span class="o">=</span><span class="n">_remove_dead_weakref</span><span class="p">):</span>
<span class="n">pop</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="o">.</span><span class="n">pop</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
<span class="c1"># We shouldn&#39;t encounter any KeyError, because this method should</span>
<span class="c1"># always be called *before* mutating the dict.</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">pop</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">_atomic_removal</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="n">o</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]()</span>
<span class="k">if</span> <span class="n">o</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">o</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__delitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__contains__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">o</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</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">return</span> <span class="n">o</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s2">&quot;&lt;</span><span class="si">%s</span><span class="s2"> at </span><span class="si">%#x</span><span class="s2">&gt;&quot;</span> <span class="o">%</span> <span class="p">(</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="p">,</span> <span class="nb">id</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">KeyedRef</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remove</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">copy</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="n">new</span> <span class="o">=</span> <span class="n">WeakValueDictionary</span><span class="p">()</span>
<span class="k">with</span> <span class="n">_IterationGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">wr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">o</span> <span class="o">=</span> <span class="n">wr</span><span class="p">()</span>
<span class="k">if</span> <span class="n">o</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">new</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">o</span>
<span class="k">return</span> <span class="n">new</span>
<span class="n">__copy__</span> <span class="o">=</span> <span class="n">copy</span>
<span class="k">def</span><span class="w"> </span><span class="nf">__deepcopy__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">memo</span><span class="p">):</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">copy</span><span class="w"> </span><span class="kn">import</span> <span class="n">deepcopy</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="n">new</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">()</span>
<span class="k">with</span> <span class="n">_IterationGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">wr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">o</span> <span class="o">=</span> <span class="n">wr</span><span class="p">()</span>
<span class="k">if</span> <span class="n">o</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">new</span><span class="p">[</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">memo</span><span class="p">)]</span> <span class="o">=</span> <span class="n">o</span>
<span class="k">return</span> <span class="n">new</span>
<span class="k">def</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">wr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</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="n">default</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">o</span> <span class="o">=</span> <span class="n">wr</span><span class="p">()</span>
<span class="k">if</span> <span class="n">o</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="c1"># This should only happen</span>
<span class="k">return</span> <span class="n">default</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">o</span>
<span class="k">def</span><span class="w"> </span><span class="nf">items</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="k">with</span> <span class="n">_IterationGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">wr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">wr</span><span class="p">()</span>
<span class="k">if</span> <span class="n">v</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">k</span><span class="p">,</span> <span class="n">v</span>
<span class="k">def</span><span class="w"> </span><span class="nf">keys</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="k">with</span> <span class="n">_IterationGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">wr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="n">wr</span><span class="p">()</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">k</span>
<span class="fm">__iter__</span> <span class="o">=</span> <span class="n">keys</span>
<span class="k">def</span><span class="w"> </span><span class="nf">itervaluerefs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Return an iterator that yields the weak references to the values.</span>
<span class="sd"> The references are not guaranteed to be &#39;live&#39; at the time</span>
<span class="sd"> they are used, so the result of calling the references needs</span>
<span class="sd"> to be checked before being used. This can be used to avoid</span>
<span class="sd"> creating references that will cause the garbage collector to</span>
<span class="sd"> keep the values around longer than needed.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="k">with</span> <span class="n">_IterationGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">yield from</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
<span class="k">def</span><span class="w"> </span><span class="nf">values</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="k">with</span> <span class="n">_IterationGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">wr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">wr</span><span class="p">()</span>
<span class="k">if</span> <span class="n">obj</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">obj</span>
<span class="k">def</span><span class="w"> </span><span class="nf">popitem</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">key</span><span class="p">,</span> <span class="n">wr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">popitem</span><span class="p">()</span>
<span class="n">o</span> <span class="o">=</span> <span class="n">wr</span><span class="p">()</span>
<span class="k">if</span> <span class="n">o</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="n">key</span><span class="p">,</span> <span class="n">o</span>
<span class="k">def</span><span class="w"> </span><span class="nf">pop</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">o</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">key</span><span class="p">)()</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="n">o</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">o</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">o</span>
<span class="k">def</span><span class="w"> </span><span class="nf">setdefault</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">o</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]()</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="n">o</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">o</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">KeyedRef</span><span class="p">(</span><span class="n">default</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remove</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
<span class="k">return</span> <span class="n">default</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">o</span>
<span class="k">def</span><span class="w"> </span><span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
<span class="k">if</span> <span class="n">other</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="s2">&quot;items&quot;</span><span class="p">):</span>
<span class="n">other</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">o</span> <span class="ow">in</span> <span class="n">other</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">d</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">KeyedRef</span><span class="p">(</span><span class="n">o</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remove</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">o</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">d</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">KeyedRef</span><span class="p">(</span><span class="n">o</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remove</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">valuerefs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Return a list of weak references to the values.</span>
<span class="sd"> The references are not guaranteed to be &#39;live&#39; at the time</span>
<span class="sd"> they are used, so the result of calling the references needs</span>
<span class="sd"> to be checked before being used. This can be used to avoid</span>
<span class="sd"> creating references that will cause the garbage collector to</span>
<span class="sd"> keep the values around longer than needed.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_commit_removals</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__ior__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">_collections_abc</span><span class="o">.</span><span class="n">Mapping</span><span class="p">):</span>
<span class="n">c</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="n">c</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="n">c</span>
<span class="k">return</span> <span class="bp">NotImplemented</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__ror__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">_collections_abc</span><span class="o">.</span><span class="n">Mapping</span><span class="p">):</span>
<span class="n">c</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">()</span>
<span class="n">c</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">return</span> <span class="n">c</span>
<span class="k">return</span> <span class="bp">NotImplemented</span>
<span class="k">class</span><span class="w"> </span><span class="nc">KeyedRef</span><span class="p">(</span><span class="n">ref</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Specialized reference that includes a key corresponding to the value.</span>
<span class="sd"> This is used in the WeakValueDictionary to avoid having to create</span>
<span class="sd"> a function object for each key stored in the mapping. A shared</span>
<span class="sd"> callback object can use the &#39;key&#39; attribute of a KeyedRef instead</span>
<span class="sd"> of getting a reference to the key from an enclosing scope.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="vm">__slots__</span> <span class="o">=</span> <span class="s2">&quot;key&quot;</span><span class="p">,</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="nb">type</span><span class="p">,</span> <span class="n">ob</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="bp">self</span> <span class="o">=</span> <span class="n">ref</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="nb">type</span><span class="p">,</span> <span class="n">ob</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="n">key</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ob</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">ob</span><span class="p">,</span> <span class="n">callback</span><span class="p">)</span>
<div class="viewcode-block" id="WeakKeyDictionary">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary">[docs]</a>
<span class="k">class</span><span class="w"> </span><span class="nc">WeakKeyDictionary</span><span class="p">(</span><span class="n">_collections_abc</span><span class="o">.</span><span class="n">MutableMapping</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot; Mapping class that references keys weakly.</span>
<span class="sd"> Entries in the dictionary will be discarded when there is no</span>
<span class="sd"> longer a strong reference to the key. This can be used to</span>
<span class="sd"> associate additional data with an object owned by other parts of</span>
<span class="sd"> an application without adding attributes to those objects. This</span>
<span class="sd"> can be especially useful with objects that override attribute</span>
<span class="sd"> accesses.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="WeakKeyDictionary.__init__">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary.__init__">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">dict</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">def</span><span class="w"> </span><span class="nf">remove</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">selfref</span><span class="o">=</span><span class="n">ref</span><span class="p">(</span><span class="bp">self</span><span class="p">)):</span>
<span class="bp">self</span> <span class="o">=</span> <span class="n">selfref</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_iterating</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">k</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">k</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="bp">self</span><span class="o">.</span><span class="n">_remove</span> <span class="o">=</span> <span class="n">remove</span>
<span class="c1"># A list of dead weakrefs (keys to be removed)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span> <span class="o">=</span> <span class="p">[]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_iterating</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dirty_len</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="nb">dict</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="nb">dict</span><span class="p">)</span></div>
<span class="k">def</span><span class="w"> </span><span class="nf">_commit_removals</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># NOTE: We don&#39;t need to call this method before mutating the dict,</span>
<span class="c1"># because a dead weakref never compares equal to a live weakref,</span>
<span class="c1"># even if they happened to refer to equal objects.</span>
<span class="c1"># However, it means keys may already have been removed.</span>
<span class="n">pop</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="o">.</span><span class="n">pop</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">pop</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">del</span> <span class="n">d</span><span class="p">[</span><span class="n">key</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">def</span><span class="w"> </span><span class="nf">_scrub_removals</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span> <span class="o">=</span> <span class="p">[</span><span class="n">k</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span> <span class="k">if</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">d</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dirty_len</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__delitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dirty_len</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">ref</span><span class="p">(</span><span class="n">key</span><span class="p">)]</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">ref</span><span class="p">(</span><span class="n">key</span><span class="p">)]</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dirty_len</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">:</span>
<span class="c1"># self._pending_removals may still contain keys which were</span>
<span class="c1"># explicitly removed, we have to scrub them (see issue #21173).</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_scrub_removals</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_pending_removals</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s2">&quot;&lt;</span><span class="si">%s</span><span class="s2"> at </span><span class="si">%#x</span><span class="s2">&gt;&quot;</span> <span class="o">%</span> <span class="p">(</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="p">,</span> <span class="nb">id</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">ref</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remove</span><span class="p">)]</span> <span class="o">=</span> <span class="n">value</span>
<div class="viewcode-block" id="WeakKeyDictionary.copy">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary.copy">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">copy</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">new</span> <span class="o">=</span> <span class="n">WeakKeyDictionary</span><span class="p">()</span>
<span class="k">with</span> <span class="n">_IterationGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">o</span> <span class="o">=</span> <span class="n">key</span><span class="p">()</span>
<span class="k">if</span> <span class="n">o</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">new</span><span class="p">[</span><span class="n">o</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
<span class="k">return</span> <span class="n">new</span></div>
<span class="n">__copy__</span> <span class="o">=</span> <span class="n">copy</span>
<span class="k">def</span><span class="w"> </span><span class="nf">__deepcopy__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">memo</span><span class="p">):</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">copy</span><span class="w"> </span><span class="kn">import</span> <span class="n">deepcopy</span>
<span class="n">new</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">()</span>
<span class="k">with</span> <span class="n">_IterationGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">o</span> <span class="o">=</span> <span class="n">key</span><span class="p">()</span>
<span class="k">if</span> <span class="n">o</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">new</span><span class="p">[</span><span class="n">o</span><span class="p">]</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">memo</span><span class="p">)</span>
<span class="k">return</span> <span class="n">new</span>
<div class="viewcode-block" id="WeakKeyDictionary.get">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary.get">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">ref</span><span class="p">(</span><span class="n">key</span><span class="p">),</span><span class="n">default</span><span class="p">)</span></div>
<span class="k">def</span><span class="w"> </span><span class="fm">__contains__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">wr</span> <span class="o">=</span> <span class="n">ref</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">return</span> <span class="n">wr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
<div class="viewcode-block" id="WeakKeyDictionary.items">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary.items">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">items</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">with</span> <span class="n">_IterationGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">wr</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">wr</span><span class="p">()</span>
<span class="k">if</span> <span class="n">key</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">key</span><span class="p">,</span> <span class="n">value</span></div>
<div class="viewcode-block" id="WeakKeyDictionary.keys">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary.keys">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">keys</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">with</span> <span class="n">_IterationGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">wr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">wr</span><span class="p">()</span>
<span class="k">if</span> <span class="n">obj</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">obj</span></div>
<span class="fm">__iter__</span> <span class="o">=</span> <span class="n">keys</span>
<div class="viewcode-block" id="WeakKeyDictionary.values">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary.values">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">values</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">with</span> <span class="n">_IterationGuard</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">for</span> <span class="n">wr</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="n">wr</span><span class="p">()</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">value</span></div>
<div class="viewcode-block" id="WeakKeyDictionary.keyrefs">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary.keyrefs">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">keyrefs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Return a list of weak references to the keys.</span>
<span class="sd"> The references are not guaranteed to be &#39;live&#39; at the time</span>
<span class="sd"> they are used, so the result of calling the references needs</span>
<span class="sd"> to be checked before being used. This can be used to avoid</span>
<span class="sd"> creating references that will cause the garbage collector to</span>
<span class="sd"> keep the keys around longer than needed.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span></div>
<div class="viewcode-block" id="WeakKeyDictionary.popitem">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary.popitem">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">popitem</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dirty_len</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">popitem</span><span class="p">()</span>
<span class="n">o</span> <span class="o">=</span> <span class="n">key</span><span class="p">()</span>
<span class="k">if</span> <span class="n">o</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="n">o</span><span class="p">,</span> <span class="n">value</span></div>
<div class="viewcode-block" id="WeakKeyDictionary.pop">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary.pop">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">pop</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_dirty_len</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">ref</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span></div>
<div class="viewcode-block" id="WeakKeyDictionary.setdefault">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary.setdefault">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">setdefault</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">ref</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remove</span><span class="p">),</span><span class="n">default</span><span class="p">)</span></div>
<div class="viewcode-block" id="WeakKeyDictionary.update">
<a class="viewcode-back" href="../api/evennia.commands.cmdset.html#evennia.commands.cmdset.WeakKeyDictionary.update">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">dict</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="n">d</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
<span class="k">if</span> <span class="nb">dict</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="nb">dict</span><span class="p">,</span> <span class="s2">&quot;items&quot;</span><span class="p">):</span>
<span class="nb">dict</span> <span class="o">=</span> <span class="nb">type</span><span class="p">({})(</span><span class="nb">dict</span><span class="p">)</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="nb">dict</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">d</span><span class="p">[</span><span class="n">ref</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remove</span><span class="p">)]</span> <span class="o">=</span> <span class="n">value</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">kwargs</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span></div>
<span class="k">def</span><span class="w"> </span><span class="fm">__ior__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__or__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">_collections_abc</span><span class="o">.</span><span class="n">Mapping</span><span class="p">):</span>
<span class="n">c</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="n">c</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">return</span> <span class="n">c</span>
<span class="k">return</span> <span class="bp">NotImplemented</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__ror__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">_collections_abc</span><span class="o">.</span><span class="n">Mapping</span><span class="p">):</span>
<span class="n">c</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">()</span>
<span class="n">c</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="n">c</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">return</span> <span class="n">c</span>
<span class="k">return</span> <span class="bp">NotImplemented</span></div>
<span class="k">class</span><span class="w"> </span><span class="nc">finalize</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Class for finalization of weakrefable objects</span>
<span class="sd"> finalize(obj, func, *args, **kwargs) returns a callable finalizer</span>
<span class="sd"> object which will be called when obj is garbage collected. The</span>
<span class="sd"> first time the finalizer is called it evaluates func(*arg, **kwargs)</span>
<span class="sd"> and returns the result. After this the finalizer is dead, and</span>
<span class="sd"> calling it just returns None.</span>
<span class="sd"> When the program exits any remaining finalizers for which the</span>
<span class="sd"> atexit attribute is true will be run in reverse order of creation.</span>
<span class="sd"> By default atexit is true.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Finalizer objects don&#39;t have any state of their own. They are</span>
<span class="c1"># just used as keys to lookup _Info objects in the registry. This</span>
<span class="c1"># ensures that they cannot be part of a ref-cycle.</span>
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">()</span>
<span class="n">_registry</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">_shutdown</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">_index_iter</span> <span class="o">=</span> <span class="n">itertools</span><span class="o">.</span><span class="n">count</span><span class="p">()</span>
<span class="n">_dirty</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">_registered_with_atexit</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">class</span><span class="w"> </span><span class="nc">_Info</span><span class="p">:</span>
<span class="vm">__slots__</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;weakref&quot;</span><span class="p">,</span> <span class="s2">&quot;func&quot;</span><span class="p">,</span> <span class="s2">&quot;args&quot;</span><span class="p">,</span> <span class="s2">&quot;kwargs&quot;</span><span class="p">,</span> <span class="s2">&quot;atexit&quot;</span><span class="p">,</span> <span class="s2">&quot;index&quot;</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="o">/</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_registered_with_atexit</span><span class="p">:</span>
<span class="c1"># We may register the exit function more than once because</span>
<span class="c1"># of a thread race, but that is harmless</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">atexit</span>
<span class="n">atexit</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_exitfunc</span><span class="p">)</span>
<span class="n">finalize</span><span class="o">.</span><span class="n">_registered_with_atexit</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_Info</span><span class="p">()</span>
<span class="n">info</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">obj</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
<span class="n">info</span><span class="o">.</span><span class="n">func</span> <span class="o">=</span> <span class="n">func</span>
<span class="n">info</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span>
<span class="n">info</span><span class="o">.</span><span class="n">kwargs</span> <span class="o">=</span> <span class="n">kwargs</span> <span class="ow">or</span> <span class="kc">None</span>
<span class="n">info</span><span class="o">.</span><span class="n">atexit</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">info</span><span class="o">.</span><span class="n">index</span> <span class="o">=</span> <span class="nb">next</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_index_iter</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_registry</span><span class="p">[</span><span class="bp">self</span><span class="p">]</span> <span class="o">=</span> <span class="n">info</span>
<span class="n">finalize</span><span class="o">.</span><span class="n">_dirty</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;If alive then mark as dead and return func(*args, **kwargs);</span>
<span class="sd"> otherwise return None&quot;&quot;&quot;</span>
<span class="n">info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_registry</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="k">if</span> <span class="n">info</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_shutdown</span><span class="p">:</span>
<span class="k">return</span> <span class="n">info</span><span class="o">.</span><span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">info</span><span class="o">.</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="p">(</span><span class="n">info</span><span class="o">.</span><span class="n">kwargs</span> <span class="ow">or</span> <span class="p">{}))</span>
<span class="k">def</span><span class="w"> </span><span class="nf">detach</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;If alive then mark as dead and return (obj, func, args, kwargs);</span>
<span class="sd"> otherwise return None&quot;&quot;&quot;</span>
<span class="n">info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_registry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">info</span> <span class="ow">and</span> <span class="n">info</span><span class="o">.</span><span class="n">weakref</span><span class="p">()</span>
<span class="k">if</span> <span class="n">obj</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_registry</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">info</span><span class="o">.</span><span class="n">func</span><span class="p">,</span> <span class="n">info</span><span class="o">.</span><span class="n">args</span><span class="p">,</span> <span class="n">info</span><span class="o">.</span><span class="n">kwargs</span> <span class="ow">or</span> <span class="p">{})</span>
<span class="k">def</span><span class="w"> </span><span class="nf">peek</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;If alive then return (obj, func, args, kwargs);</span>
<span class="sd"> otherwise return None&quot;&quot;&quot;</span>
<span class="n">info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_registry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">info</span> <span class="ow">and</span> <span class="n">info</span><span class="o">.</span><span class="n">weakref</span><span class="p">()</span>
<span class="k">if</span> <span class="n">obj</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">info</span><span class="o">.</span><span class="n">func</span><span class="p">,</span> <span class="n">info</span><span class="o">.</span><span class="n">args</span><span class="p">,</span> <span class="n">info</span><span class="o">.</span><span class="n">kwargs</span> <span class="ow">or</span> <span class="p">{})</span>
<span class="nd">@property</span>
<span class="k">def</span><span class="w"> </span><span class="nf">alive</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Whether finalizer is alive&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_registry</span>
<span class="nd">@property</span>
<span class="k">def</span><span class="w"> </span><span class="nf">atexit</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Whether finalizer should be called at exit&quot;&quot;&quot;</span>
<span class="n">info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_registry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">info</span><span class="p">)</span> <span class="ow">and</span> <span class="n">info</span><span class="o">.</span><span class="n">atexit</span>
<span class="nd">@atexit</span><span class="o">.</span><span class="n">setter</span>
<span class="k">def</span><span class="w"> </span><span class="nf">atexit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="n">info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_registry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">if</span> <span class="n">info</span><span class="p">:</span>
<span class="n">info</span><span class="o">.</span><span class="n">atexit</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_registry</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">info</span> <span class="ow">and</span> <span class="n">info</span><span class="o">.</span><span class="n">weakref</span><span class="p">()</span>
<span class="k">if</span> <span class="n">obj</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="s1">&#39;&lt;</span><span class="si">%s</span><span class="s1"> object at </span><span class="si">%#x</span><span class="s1">; dead&gt;&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="nb">id</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="s1">&#39;&lt;</span><span class="si">%s</span><span class="s1"> object at </span><span class="si">%#x</span><span class="s1">; for </span><span class="si">%r</span><span class="s1"> at </span><span class="si">%#x</span><span class="s1">&gt;&#39;</span> <span class="o">%</span> \
<span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="nb">id</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="nb">id</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
<span class="nd">@classmethod</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_select_for_exit</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
<span class="c1"># Return live finalizers marked for exit, oldest first</span>
<span class="n">L</span> <span class="o">=</span> <span class="p">[(</span><span class="n">f</span><span class="p">,</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="p">(</span><span class="n">f</span><span class="p">,</span><span class="n">i</span><span class="p">)</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_registry</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">i</span><span class="o">.</span><span class="n">atexit</span><span class="p">]</span>
<span class="n">L</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">item</span><span class="p">:</span><span class="n">item</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">index</span><span class="p">)</span>
<span class="k">return</span> <span class="p">[</span><span class="n">f</span> <span class="k">for</span> <span class="p">(</span><span class="n">f</span><span class="p">,</span><span class="n">i</span><span class="p">)</span> <span class="ow">in</span> <span class="n">L</span><span class="p">]</span>
<span class="nd">@classmethod</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_exitfunc</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
<span class="c1"># At shutdown invoke finalizers for which atexit is true.</span>
<span class="c1"># This is called once all other non-daemonic threads have been</span>
<span class="c1"># joined.</span>
<span class="n">reenable_gc</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_registry</span><span class="p">:</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">gc</span>
<span class="k">if</span> <span class="n">gc</span><span class="o">.</span><span class="n">isenabled</span><span class="p">():</span>
<span class="n">reenable_gc</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">gc</span><span class="o">.</span><span class="n">disable</span><span class="p">()</span>
<span class="n">pending</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">if</span> <span class="n">pending</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">finalize</span><span class="o">.</span><span class="n">_dirty</span><span class="p">:</span>
<span class="n">pending</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_select_for_exit</span><span class="p">()</span>
<span class="n">finalize</span><span class="o">.</span><span class="n">_dirty</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">pending</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">f</span> <span class="o">=</span> <span class="n">pending</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># gc is disabled, so (assuming no daemonic</span>
<span class="c1"># threads) the following is the only line in</span>
<span class="c1"># this function which might trigger creation</span>
<span class="c1"># of a new finalizer</span>
<span class="n">f</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">sys</span><span class="o">.</span><span class="n">excepthook</span><span class="p">(</span><span class="o">*</span><span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">())</span>
<span class="k">assert</span> <span class="n">f</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_registry</span>
<span class="k">finally</span><span class="p">:</span>
<span class="c1"># prevent any more finalizers from executing during shutdown</span>
<span class="n">finalize</span><span class="o">.</span><span class="n">_shutdown</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="n">reenable_gc</span><span class="p">:</span>
<span class="n">gc</span><span class="o">.</span><span class="n">enable</span><span class="p">()</span>
</pre></div>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/evennia_logo.png" alt="Logo of Evennia"/>
</a></p>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Doc Versions</h3>
<ul>
<li>
<a href="https://www.evennia.com/docs/latest/index.html">latest (main branch)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/5.x/index.html">v5.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/4.x/index.html">v4.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/3.x/index.html">v3.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/2.x/index.html">v2.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/1.x/index.html">v1.0.0 branch (outdated)</a>
</li>
<li>
<a href="https://www.evennia.com/docs/0.x/index.html">v0.9.5 branch (outdated)</a>
</li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="Related">
<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">Evennia</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">weakref</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2024, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
</div>
</body>
</html>