Updated HTML docs

This commit is contained in:
Evennia docbuilder action 2022-06-22 06:30:53 +00:00
parent bd82579bfa
commit 70b4caedb6
105 changed files with 2389 additions and 2138 deletions

View file

@ -57,15 +57,16 @@ the return from the function.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia.utils.funcparser</span> <span class="kn">import</span> <span class="n">FuncParser</span>
<span class="k">def</span> <span class="nf">_power_callable</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="sd">&quot;&quot;&quot;This will be callable as $square(number, power=&lt;num&gt;) in string&quot;&quot;&quot;</span>
<span class="sd">&quot;&quot;&quot;This will be callable as $pow(number, power=&lt;num&gt;) in string&quot;&quot;&quot;</span>
<span class="nb">pow</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;power&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
<span class="k">return</span> <span class="nb">float</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">**</span> <span class="nb">pow</span>
<span class="c1"># create a parser and tell it that &#39;$pow&#39; means using _power_callable</span>
<span class="n">parser</span> <span class="o">=</span> <span class="n">FuncParser</span><span class="p">({</span><span class="s2">&quot;pow&quot;</span><span class="p">:</span> <span class="n">_power_callable</span><span class="p">})</span>
</pre></div>
</div>
<p>Next, just pass a string into the parser, optionally containing <code class="docutils literal notranslate"><span class="pre">$func(...)</span></code> markers:</p>
<p>Next, just pass a string into the parser, containing <code class="docutils literal notranslate"><span class="pre">$func(...)</span></code> markers:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="s2">&quot;We have that 4 x 4 x 4 is $pow(4, power=3).&quot;</span><span class="p">)</span>
<span class="s2">&quot;We have that 4 x 4 x 4 is 64.&quot;</span>
</pre></div>
@ -111,7 +112,7 @@ Evennia expects you to do in a proper text editor, outside of the game, not from
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">funcparser</span>
<span class="n">parser</span> <span class="o">=</span> <span class="n">FuncParser</span><span class="p">(</span><span class="n">callables</span><span class="p">,</span> <span class="o">**</span><span class="n">default_kwargs</span><span class="p">)</span>
<span class="n">parsed_string</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parser</span><span class="p">(</span><span class="n">input_string</span><span class="p">,</span> <span class="n">raise_errors</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">parsed_string</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">input_string</span><span class="p">,</span> <span class="n">raise_errors</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">escape</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">strip</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">return_str</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">**</span><span class="n">reserved_kwargs</span><span class="p">)</span>
@ -131,8 +132,12 @@ If no such variable is defined, <em>every</em> top-level function in the module
an underscore <code class="docutils literal notranslate"><span class="pre">_</span></code>) will be considered a suitable callable. The name of the function will be the <code class="docutils literal notranslate"><span class="pre">$funcname</span></code>
by which it can be called.</p></li>
<li><p>A <code class="docutils literal notranslate"><span class="pre">list</span></code> of modules/paths. This allows you to pull in modules from many sources for your parsing.</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">**default</span></code> kwargs are optional kwargs that will be passed to <em>all</em>
callables every time this parser is used - unless the user overrides it explicitly in
their call. This is great for providing sensible standards that the user can
tweak as needed.</p></li>
</ul>
<p>The other arguments to the parser:</p>
<p><code class="docutils literal notranslate"><span class="pre">FuncParser.parse</span></code> takes further arguments, and can vary for every string parsed.</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">raise_errors</span></code> - By default, any errors from a callable will be quietly ignored and the result
will be that the failing function call will show verbatim. If <code class="docutils literal notranslate"><span class="pre">raise_errors</span></code> is set,
@ -143,12 +148,14 @@ this properly.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">return_str</span></code> - When <code class="docutils literal notranslate"><span class="pre">True</span></code> (default), <code class="docutils literal notranslate"><span class="pre">parser</span></code> always returns a string. If <code class="docutils literal notranslate"><span class="pre">False</span></code>, it may return
the return value of a single function call in the string. This is the same as using the <code class="docutils literal notranslate"><span class="pre">.parse_to_any</span></code>
method.</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">**default/reserved_keywords</span></code> are optional and allow you to pass custom data into <em>every</em> function
call. This is great for including things like the current session or config options. Defaults can be
replaced if the user gives the same-named kwarg in the strings function call. Reserved kwargs are always passed,
ignoring defaults or what the user passed. In addition, the <code class="docutils literal notranslate"><span class="pre">funcparser</span></code> and <code class="docutils literal notranslate"><span class="pre">raise_errors</span></code>
reserved kwargs are always passed - the first is a back-reference to the <code class="docutils literal notranslate"><span class="pre">FuncParser</span></code> instance and the second
is the <code class="docutils literal notranslate"><span class="pre">raise_errors</span></code> boolean passed into <code class="docutils literal notranslate"><span class="pre">FuncParser.parse</span></code>.</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">**reserved_keywords</span></code> are <em>always</em> passed to every callable in the string.
They override any <code class="docutils literal notranslate"><span class="pre">**defaults</span></code> given when instantiating the parser and cannot
be overridden by the user - if they enter the same kwarg it will be ignored.
This is great for providing the current session, settings etc.</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">funcparser</span></code> and <code class="docutils literal notranslate"><span class="pre">raise_errors</span></code>
are always added as reserved keywords - the first is a
back-reference to the <code class="docutils literal notranslate"><span class="pre">FuncParser</span></code> instance and the second
is the <code class="docutils literal notranslate"><span class="pre">raise_errors</span></code> boolean given to <code class="docutils literal notranslate"><span class="pre">FuncParser.parse</span></code>.</p></li>
</ul>
<p>Heres an example of using the default/reserved keywords:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_test</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>
@ -193,7 +200,8 @@ of the string and may or may not raise the exception depending on what you set <
created the parser.</p>
<p>However, if you <em>nest</em> functions, the return of the innermost function may be something other than
a string. Lets introduce the <code class="docutils literal notranslate"><span class="pre">$eval</span></code> function, which evaluates simple expressions using
Pythons <code class="docutils literal notranslate"><span class="pre">literal_eval</span></code> and/or <code class="docutils literal notranslate"><span class="pre">simple_eval</span></code>.</p>
Pythons <code class="docutils literal notranslate"><span class="pre">literal_eval</span></code> and/or <code class="docutils literal notranslate"><span class="pre">simple_eval</span></code>. It returns whatever data type it
evaluates to.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&quot;There&#39;s a $toint($eval(10 * 2.2))% chance of survival.&quot;
</pre></div>
</div>
@ -210,21 +218,67 @@ will be a string:</p>
<span class="s2">&quot;There&#39;s a 22</span><span class="si">% c</span><span class="s2">hance of survival.&quot;</span>
</pre></div>
</div>
<p>However, if you use the <code class="docutils literal notranslate"><span class="pre">parse_to_any</span></code> (or <code class="docutils literal notranslate"><span class="pre">parse(...,</span> <span class="pre">return_str=True)</span></code>) and <em>dont add any extra string around the outermost function call</em>,
<p>However, if you use the <code class="docutils literal notranslate"><span class="pre">parse_to_any</span></code> (or <code class="docutils literal notranslate"><span class="pre">parse(...,</span> <span class="pre">return_str=False)</span></code>) and
<em>dont add any extra string around the outermost function call</em>,
youll get the return type of the outermost callable back:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">parser</span><span class="o">.</span><span class="n">parse_to_any</span><span class="p">(</span><span class="s2">&quot;$toint($eval(10 * 2.2)%&quot;</span><span class="p">)</span>
<span class="s2">&quot;22%&quot;</span>
<span class="n">parser</span><span class="o">.</span><span class="n">parse_to_any</span><span class="p">(</span><span class="s2">&quot;$toint($eval(10 * 2.2)&quot;</span><span class="p">)</span>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">parser</span><span class="o">.</span><span class="n">parse_to_any</span><span class="p">(</span><span class="s2">&quot;$toint($eval(10 * 2.2)&quot;</span><span class="p">)</span>
<span class="mi">22</span>
<span class="n">parser</span><span class="o">.</span><span class="n">parse_to_any</span><span class="p">(</span><span class="s2">&quot;the number $toint($eval(10 * 2.2).&quot;</span><span class="p">)</span>
<span class="s2">&quot;the number 22&quot;</span>
<span class="n">parser</span><span class="o">.</span><span class="n">parse_to_any</span><span class="p">(</span><span class="s2">&quot;$toint($eval(10 * 2.2)%&quot;</span><span class="p">)</span>
<span class="s2">&quot;22%&quot;</span>
</pre></div>
</div>
<section id="escaping-special-character">
<h3>Escaping special character<a class="headerlink" href="#escaping-special-character" title="Permalink to this headline"></a></h3>
<p>When entering funcparser callables in strings, it looks like a regular
function call inside a string:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="s2">&quot;This is a $myfunc(arg1, arg2, kwarg=foo).&quot;</span>
</pre></div>
</div>
<p>Commas (<code class="docutils literal notranslate"><span class="pre">,</span></code>) and equal-signs (<code class="docutils literal notranslate"><span class="pre">=</span></code>) are considered to separate the arguments and
kwargs. In the same way, the right parenthesis (<code class="docutils literal notranslate"><span class="pre">)</span></code>) closes the argument list.
Sometimes you want to include commas in the argument without it breaking the
argument list.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="s2">&quot;There is a $format(beautiful meadow, with dandelions) to the west.&quot;</span>
</pre></div>
</div>
<p>You can escape in various ways.</p>
<ul>
<li><p>Prepending with the escape character <code class="docutils literal notranslate"><span class="pre">\</span></code></p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> ```python
&quot;There is a $format(beautiful meadow\, with dandelions) to the west.&quot;
```
</pre></div>
</div>
</li>
<li><p>Wrapping your strings in quotes. This works like Python, and you can nest
double and single quotes inside each other if so needed. The result will
be a verbatim string that contains everything but the outermost quotes.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> ```python
&quot;There is a $format(&#39;beautiful meadow, with dandelions&#39;) to the west.&quot;
```
</pre></div>
</div>
</li>
<li><p>If you want verbatim quotes in your string, you can escape them too.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span> ```python
&quot;There is a $format(&#39;beautiful meadow, with \&#39;dandelions\&#39;&#39;) to the west.&quot;
```
</pre></div>
</div>
</li>
</ul>
</section>
<section id="safe-convertion-of-inputs">
<h3>Safe convertion of inputs<a class="headerlink" href="#safe-convertion-of-inputs" title="Permalink to this headline"></a></h3>
<p>Since you dont know in which order users may use your callables, they should always check the types
of its inputs and convert to the type the callable needs. Note also that when converting from strings,
there are limits what inputs you can support. This is because FunctionParser strings are often used by
non-developer players/builders and some things (such as complex classes/callables etc) are just not
safe/possible to convert from string representation.</p>
<p>Since you dont know in which order users may use your callables, they should
always check the types of its inputs and convert to the type the callable needs.
Note also that when converting from strings, there are limits what inputs you
can support. This is because FunctionParser strings can be used by
non-developer players/builders and some things (such as complex
classes/callables etc) are just not safe/possible to convert from string
representation.</p>
<p>In <code class="docutils literal notranslate"><span class="pre">evennia.utils.utils</span></code> is a helper called
<a class="reference internal" href="../api/evennia.utils.utils.html#evennia.utils.utils.safe_convert_to_types" title="evennia.utils.utils.safe_convert_to_types"><span class="xref myst py py-func">safe_convert_to_types</span></a>. This function
automates the conversion of simple data types in a safe way:</p>
@ -232,26 +286,28 @@ automates the conversion of simple data types in a safe way:</p>
<span class="k">def</span> <span class="nf">_process_callable</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="sd">&quot;&quot;&quot;</span>
<span class="sd"> A callable with a lot of custom options</span>
<span class="sd"> $process(expression, local, extra=34, extra2=foo)</span>
<span class="sd"> $process(expression, local, extra1=34, extra2=foo)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="n">safe_convert_to_type</span><span class="p">(</span>
<span class="p">((</span><span class="s1">&#39;py&#39;</span><span class="p">,</span> <span class="s1">&#39;py&#39;</span><span class="p">),</span> <span class="p">{</span><span class="s1">&#39;extra1&#39;</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="s1">&#39;extra2&#39;</span><span class="p">:</span> <span class="nb">str</span><span class="p">}),</span>
<span class="p">((</span><span class="s1">&#39;py&#39;</span><span class="p">,</span> <span class="nb">str</span><span class="p">),</span> <span class="p">{</span><span class="s1">&#39;extra1&#39;</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="s1">&#39;extra2&#39;</span><span class="p">:</span> <span class="nb">str</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="c1"># args/kwargs should be correct types now</span>
</pre></div>
</div>
<p>In other words, in the callable <code class="docutils literal notranslate"><span class="pre">$process(expression,</span> <span class="pre">local,</span> <span class="pre">extra1=..,</span> <span class="pre">extra2=...)</span></code>, the first argument will be handled by the py converter
(described below), the second will passed through regular Python <code class="docutils literal notranslate"><span class="pre">str</span></code>,
kwargs will be handled by <code class="docutils literal notranslate"><span class="pre">int</span></code> and <code class="docutils literal notranslate"><span class="pre">str</span></code> respectively. You can supply
your own converter function as long as it takes one argument and returns
the converted result.</p>
<p>In other words,</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="n">safe_convert_to_type</span><span class="p">(</span>
<span class="p">(</span><span class="n">tuple_of_arg_converters</span><span class="p">,</span> <span class="n">dict_of_kwarg_converters</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>
</pre></div>
</div>
<p>Each converter should be a callable taking one argument - this will be the arg/kwarg-value to convert. The
special converter <code class="docutils literal notranslate"><span class="pre">&quot;py&quot;</span></code> will try to convert a string argument to a Python structure with the help of the
<p>The special converter <code class="docutils literal notranslate"><span class="pre">&quot;py&quot;</span></code> will try to convert a string argument to a Python structure with the help of the
following tools (which you may also find useful to experiment with on your own):</p>
<ul class="simple">
<li><p><a class="reference external" href="https://docs.python.org/3.8/library/ast.html#ast.literal_eval">ast.literal_eval</a> is an in-built Python
@ -439,6 +495,7 @@ all the defaults (like <code class="docutils literal notranslate"><span class="p
<li><a class="reference internal" href="#uses-in-default-evennia">Uses in default Evennia</a></li>
<li><a class="reference internal" href="#using-the-funcparser">Using the FuncParser</a></li>
<li><a class="reference internal" href="#defining-custom-callables">Defining custom callables</a><ul>
<li><a class="reference internal" href="#escaping-special-character">Escaping special character</a></li>
<li><a class="reference internal" href="#safe-convertion-of-inputs">Safe convertion of inputs</a></li>
</ul>
</li>