mirror of
https://github.com/evennia/evennia.git
synced 2026-03-17 13:26:30 +01:00
423 lines
No EOL
36 KiB
HTML
423 lines
No EOL
36 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" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
|
||
<title>Debugging — 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" />
|
||
<link rel="next" title="Unit Testing" href="Unit-Testing.html" />
|
||
<link rel="prev" title="Coding using Version Control" href="Version-Control.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="right" >
|
||
<a href="Unit-Testing.html" title="Unit Testing"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="Version-Control.html" title="Coding using Version Control"
|
||
accesskey="P">previous</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" accesskey="U">Coding and development help</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Debugging</a></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<section class="tex2jax_ignore mathjax_ignore" id="debugging">
|
||
<h1>Debugging<a class="headerlink" href="#debugging" title="Link to this heading">¶</a></h1>
|
||
<p>Sometimes, an error is not trivial to resolve. A few simple <code class="docutils literal notranslate"><span class="pre">print</span></code> statements is not enough to find the cause of the issue. The traceback is not informative or even non-existing.</p>
|
||
<p>Running a <em>debugger</em> can then be very helpful and save a lot of time. Debugging means running Evennia under control of a special <em>debugger</em> program. This allows you to stop the action at a given point, view the current state and step forward through the program to see how its logic works.</p>
|
||
<p>Evennia natively supports these debuggers:</p>
|
||
<ul class="simple">
|
||
<li><p><a class="reference external" href="https://docs.python.org/2/library/pdb.html">Pdb</a> is a part of the Python distribution and
|
||
available out-of-the-box.</p></li>
|
||
<li><p><a class="reference external" href="https://pypi.org/project/pudb/">PuDB</a> is a third-party debugger that has a slightly more
|
||
‘graphical’, curses-based user interface than pdb. It is installed with <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">pudb</span></code>.</p></li>
|
||
</ul>
|
||
<section id="debugging-evennia">
|
||
<h2>Debugging Evennia<a class="headerlink" href="#debugging-evennia" title="Link to this heading">¶</a></h2>
|
||
<p>To run Evennia with the debugger, follow these steps:</p>
|
||
<ol class="arabic">
|
||
<li><p>Find the point in the code where you want to have more insight. Add the following line at that
|
||
point.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">set_trace</span><span class="p">;</span><span class="n">set_trace</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</li>
|
||
<li><p>(Re-)start Evennia in interactive (foreground) mode with <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">istart</span></code>. This is important - without this step the debugger will not start correctly - it will start in this interactive terminal.</p></li>
|
||
<li><p>Perform the steps that will trigger the line where you added the <code class="docutils literal notranslate"><span class="pre">set_trace()</span></code> call. The debugger will start in the terminal from which Evennia was interactively started.</p></li>
|
||
</ol>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">evennia.set_trace</span></code> function takes the following arguments:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span> <span class="n">evennia</span><span class="o">.</span><span class="n">set_trace</span><span class="p">(</span><span class="n">debugger</span><span class="o">=</span><span class="s1">'auto'</span><span class="p">,</span> <span class="n">term_size</span><span class="o">=</span><span class="p">(</span><span class="mi">140</span><span class="p">,</span> <span class="mi">40</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Here, <code class="docutils literal notranslate"><span class="pre">debugger</span></code> is one of <code class="docutils literal notranslate"><span class="pre">pdb</span></code>, <code class="docutils literal notranslate"><span class="pre">pudb</span></code> or <code class="docutils literal notranslate"><span class="pre">auto</span></code>. If <code class="docutils literal notranslate"><span class="pre">auto</span></code>, use <code class="docutils literal notranslate"><span class="pre">pudb</span></code> if available, otherwise use <code class="docutils literal notranslate"><span class="pre">pdb</span></code>. The <code class="docutils literal notranslate"><span class="pre">term_size</span></code> tuple sets the viewport size for <code class="docutils literal notranslate"><span class="pre">pudb</span></code> only (it’s ignored by <code class="docutils literal notranslate"><span class="pre">pdb</span></code>).</p>
|
||
</section>
|
||
<section id="a-simple-example-using-pdb">
|
||
<h2>A simple example using pdb<a class="headerlink" href="#a-simple-example-using-pdb" title="Link to this heading">¶</a></h2>
|
||
<p>The debugger is useful in different cases, but to begin with, let’s see it working in a command.
|
||
Add the following test command (which has a range of deliberate errors) and also add it to your
|
||
default cmdset. Then restart Evennia in interactive mode with <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">istart</span></code>.</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># In file commands/command.py</span>
|
||
|
||
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">CmdTest</span><span class="p">(</span><span class="n">Command</span><span class="p">):</span>
|
||
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> A test command just to test pdb.</span>
|
||
|
||
<span class="sd"> Usage:</span>
|
||
<span class="sd"> test</span>
|
||
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="n">key</span> <span class="o">=</span> <span class="s2">"test"</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">set_trace</span><span class="p">;</span> <span class="n">set_trace</span><span class="p">()</span> <span class="c1"># <--- start of debugger</span>
|
||
<span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</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">msg</span><span class="p">(</span><span class="s2">"You've found </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">()))</span>
|
||
|
||
</pre></div>
|
||
</div>
|
||
<p>If you type <code class="docutils literal notranslate"><span class="pre">test</span></code> in your game, everything will freeze. You won’t get any feedback from the game, and you won’t be able to enter any command (nor anyone else). It’s because the debugger has started in your console, and you will find it here. Below is an example with <code class="docutils literal notranslate"><span class="pre">pdb</span></code>.</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">...</span>
|
||
<span class="o">></span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">79</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
|
||
<span class="o">-></span> <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
|
||
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">pdb</span></code> notes where it has stopped execution and, what line is about to be executed (in our case, <code class="docutils literal notranslate"><span class="pre">obj</span> <span class="pre">=</span> <span class="pre">self.search(self.args)</span></code>), and ask what you would like to do.</p>
|
||
<section id="listing-surrounding-lines-of-code">
|
||
<h3>Listing surrounding lines of code<a class="headerlink" href="#listing-surrounding-lines-of-code" title="Link to this heading">¶</a></h3>
|
||
<p>When you have the <code class="docutils literal notranslate"><span class="pre">pdb</span></code> prompt <code class="docutils literal notranslate"><span class="pre">(Pdb)</span></code>, you can type in different commands to explore the code. The first one you should know is <code class="docutils literal notranslate"><span class="pre">list</span></code> (you can type <code class="docutils literal notranslate"><span class="pre">l</span></code> for short):</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">l</span>
|
||
<span class="mi">43</span>
|
||
<span class="mi">44</span> <span class="n">key</span> <span class="o">=</span> <span class="s2">"test"</span>
|
||
<span class="mi">45</span>
|
||
<span class="mi">46</span> <span class="k">def</span><span class="w"> </span><span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="mi">47</span> <span class="kn">from</span><span class="w"> </span><span class="nn">evennia</span><span class="w"> </span><span class="kn">import</span> <span class="n">set_trace</span><span class="p">;</span> <span class="n">set_trace</span><span class="p">()</span> <span class="c1"># <--- start of debugger</span>
|
||
<span class="mi">48</span> <span class="o">-></span> <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
|
||
<span class="mi">49</span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"You've found </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">()))</span>
|
||
<span class="mi">50</span>
|
||
<span class="mi">51</span> <span class="c1"># -------------------------------------------------------------</span>
|
||
<span class="mi">52</span> <span class="c1">#</span>
|
||
<span class="mi">53</span> <span class="c1"># The default commands inherit from</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Okay, this didn’t do anything spectacular, but when you become more confident with <code class="docutils literal notranslate"><span class="pre">pdb</span></code> and find yourself in lots of different files, you sometimes need to see what’s around in code. Notice that there is a little arrow (<code class="docutils literal notranslate"><span class="pre">-></span></code>) before the line that is about to be executed.</p>
|
||
<p>This is important: <strong>about to be</strong>, not <strong>has just been</strong>. You need to tell <code class="docutils literal notranslate"><span class="pre">pdb</span></code> to go on (we’ll soon see how).</p>
|
||
</section>
|
||
<section id="examining-variables">
|
||
<h3>Examining variables<a class="headerlink" href="#examining-variables" title="Link to this heading">¶</a></h3>
|
||
<p><code class="docutils literal notranslate"><span class="pre">pdb</span></code> allows you to examine variables (or really, to run any Python instruction). It is very useful to know the values of variables at a specific line. To see a variable, just type its name (as if you were in the Python interpreter:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="bp">self</span>
|
||
<span class="o"><</span><span class="n">commands</span><span class="o">.</span><span class="n">command</span><span class="o">.</span><span class="n">CmdTest</span> <span class="nb">object</span> <span class="n">at</span> <span class="mh">0x045A0990</span><span class="o">></span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
|
||
<span class="sa">u</span><span class="s1">''</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
|
||
<span class="o"><</span><span class="n">Character</span><span class="p">:</span> <span class="n">XXX</span><span class="o">></span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>If you try to see the variable <code class="docutils literal notranslate"><span class="pre">obj</span></code>, you’ll get an error:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">obj</span>
|
||
<span class="o">***</span> <span class="ne">NameError</span><span class="p">:</span> <span class="n">name</span> <span class="s1">'obj'</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">defined</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>That figures, since at this point, we haven’t created the variable yet.</p>
|
||
<blockquote>
|
||
<div><p>Examining variable in this way is quite powerful. You can even run Python code and keep on
|
||
executing, which can help to check that your fix is actually working when you have identified an
|
||
error. If you have variable names that will conflict with <code class="docutils literal notranslate"><span class="pre">pdb</span></code> commands (like a <code class="docutils literal notranslate"><span class="pre">list</span></code>
|
||
variable), you can prefix your variable with <code class="docutils literal notranslate"><span class="pre">!</span></code>, to tell <code class="docutils literal notranslate"><span class="pre">pdb</span></code> that what follows is Python code.</p>
|
||
</div></blockquote>
|
||
</section>
|
||
<section id="executing-the-current-line">
|
||
<h3>Executing the current line<a class="headerlink" href="#executing-the-current-line" title="Link to this heading">¶</a></h3>
|
||
<p>It’s time we asked <code class="docutils literal notranslate"><span class="pre">pdb</span></code> to execute the current line. To do so, use the <code class="docutils literal notranslate"><span class="pre">next</span></code> command. You can
|
||
shorten it by just typing <code class="docutils literal notranslate"><span class="pre">n</span></code>:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">n</span>
|
||
<span class="ne">AttributeError</span><span class="p">:</span> <span class="s2">"'CmdTest' object has no attribute 'search'"</span>
|
||
<span class="o">></span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">79</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
|
||
<span class="o">-></span> <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">Pdb</span></code> is complaining that you try to call the <code class="docutils literal notranslate"><span class="pre">search</span></code> method on a command… whereas there’s no <code class="docutils literal notranslate"><span class="pre">search</span></code> method on commands. The character executing the command is in <code class="docutils literal notranslate"><span class="pre">self.caller</span></code>, so we might change our line:</p>
|
||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="letting-the-program-run">
|
||
<h3>Letting the program run<a class="headerlink" href="#letting-the-program-run" title="Link to this heading">¶</a></h3>
|
||
<p><code class="docutils literal notranslate"><span class="pre">pdb</span></code> is waiting to execute the same instruction… it provoked an error but it’s ready to try again, just in case. We have fixed it in theory, but we need to reload, so we need to enter a command. To tell <code class="docutils literal notranslate"><span class="pre">pdb</span></code> to terminate and keep on running the program, use the <code class="docutils literal notranslate"><span class="pre">continue</span></code> (or <code class="docutils literal notranslate"><span class="pre">c</span></code>) command:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">c</span>
|
||
<span class="o">...</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>You see an error being caught, that’s the error we have fixed… or hope to have. Let’s reload the game and try again. You need to run <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">istart</span></code> again and then run <code class="docutils literal notranslate"><span class="pre">test</span></code> to get into the command again.</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">79</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
|
||
<span class="o">-></span> <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
|
||
|
||
</pre></div>
|
||
</div>
|
||
<p><code class="docutils literal notranslate"><span class="pre">pdb</span></code> is about to run the line again.</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">n</span>
|
||
<span class="o">></span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">80</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
|
||
<span class="o">-></span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"You've found </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">()))</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This time the line ran without error. Let’s see what is in the <code class="docutils literal notranslate"><span class="pre">obj</span></code> variable:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">obj</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="nb">print</span> <span class="n">obj</span>
|
||
<span class="kc">None</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>We have entered the <code class="docutils literal notranslate"><span class="pre">test</span></code> command without parameter, so no object could be found in the search
|
||
(<code class="docutils literal notranslate"><span class="pre">self.args</span></code> is an empty string).</p>
|
||
<p>Let’s allow the command to continue and try to use an object name as parameter (although, we should
|
||
fix that bug too, it would be better):</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">c</span>
|
||
<span class="o">...</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Notice that you’ll have an error in the game this time. Let’s try with a valid parameter. I have another character, <code class="docutils literal notranslate"><span class="pre">barkeep</span></code>, in this room:</p>
|
||
<p><code class="docutils literal notranslate"><span class="pre">test</span> <span class="pre">barkeep</span></code></p>
|
||
<p>And again, the command freezes, and we have the debugger opened in the console.</p>
|
||
<p>Let’s execute this line right away:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">></span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">79</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
|
||
<span class="o">-></span> <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">)</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">n</span>
|
||
<span class="o">></span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">80</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
|
||
<span class="o">-></span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"You've found </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">()))</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">obj</span>
|
||
<span class="o"><</span><span class="n">Character</span><span class="p">:</span> <span class="n">barkeep</span><span class="o">></span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>At least this time we have found the object. Let’s process…</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">Pdb</span><span class="p">)</span> <span class="n">n</span>
|
||
<span class="ne">TypeError</span><span class="p">:</span> <span class="s1">'get_display_name() takes exactly 2 arguments (1 given)'</span>
|
||
<span class="o">></span> <span class="o">.../</span><span class="n">mygame</span><span class="o">/</span><span class="n">commands</span><span class="o">/</span><span class="n">command</span><span class="o">.</span><span class="n">py</span><span class="p">(</span><span class="mi">80</span><span class="p">)</span><span class="n">func</span><span class="p">()</span>
|
||
<span class="o">-></span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">"You've found </span><span class="si">{}</span><span class="s2">."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">()))</span>
|
||
<span class="p">(</span><span class="n">Pdb</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>As an exercise, fix this error, reload and run the debugger again. Nothing better than some experimenting!</p>
|
||
<p>Your debugging will often follow the same strategy:</p>
|
||
<ol class="arabic simple">
|
||
<li><p>Receive an error you don’t understand.</p></li>
|
||
<li><p>Put a breaking point <strong>BEFORE</strong> the error occurs.</p></li>
|
||
<li><p>Run <code class="docutils literal notranslate"><span class="pre">evennia</span> <span class="pre">istart</span></code></p></li>
|
||
<li><p>Run the code again and see the debugger open.</p></li>
|
||
<li><p>Run the program line by line, examining variables, checking the logic of instructions.</p></li>
|
||
<li><p>Continue and try again, each step a bit further toward the truth and the working feature.</p></li>
|
||
</ol>
|
||
</section>
|
||
</section>
|
||
<section id="cheat-sheet-of-pdb-pudb-commands">
|
||
<h2>Cheat-sheet of pdb/pudb commands<a class="headerlink" href="#cheat-sheet-of-pdb-pudb-commands" title="Link to this heading">¶</a></h2>
|
||
<p>PuDB and Pdb share the same commands. The only real difference is how it’s presented. The <code class="docutils literal notranslate"><span class="pre">look</span></code>
|
||
command is not needed much in <code class="docutils literal notranslate"><span class="pre">pudb</span></code> since it displays the code directly in its user interface.</p>
|
||
<table class="docutils align-default">
|
||
<thead>
|
||
<tr class="row-odd"><th class="head"><p>Pdb/PuDB command</p></th>
|
||
<th class="head"><p>To do what</p></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="row-even"><td><p>list (or l)</p></td>
|
||
<td><p>List the lines around the point of execution (not needed for <code class="docutils literal notranslate"><span class="pre">pudb</span></code>, it will show</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>this directly).</p></td>
|
||
<td><p></p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>print (or p)</p></td>
|
||
<td><p>Display one or several variables.</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">!</span></code></p></td>
|
||
<td><p>Run Python code (using a <code class="docutils literal notranslate"><span class="pre">!</span></code> is often optional).</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>continue (or c)</p></td>
|
||
<td><p>Continue execution and terminate the debugger for this time.</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p>next (or n)</p></td>
|
||
<td><p>Execute the current line and goes to the next one.</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p>step (or s)</p></td>
|
||
<td><p>Step inside of a function or method to examine it.</p></td>
|
||
</tr>
|
||
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre"><RETURN></span></code></p></td>
|
||
<td><p>Repeat the last command (don’t type <code class="docutils literal notranslate"><span class="pre">n</span></code> repeatedly, just type it once and then press</p></td>
|
||
</tr>
|
||
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre"><RETURN></span></code> to repeat it).</p></td>
|
||
<td><p></p></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>If you want to learn more about debugging with Pdb, you will find an <a class="reference external" href="https://pymotw.com/3/pdb/">interesting tutorial on that topic here</a>.</p>
|
||
</section>
|
||
<section id="debugging-with-debugpy">
|
||
<h2>Debugging with debugpy<a class="headerlink" href="#debugging-with-debugpy" title="Link to this heading">¶</a></h2>
|
||
<p>If you use Visual Studio Code and would like to debug Evennia using a graphical debugger, please follow the instructions here:</p>
|
||
<p><a class="reference external" href="https://github.com/evennia/evennia/tree/main/evennia/contrib/utils/debugpy">debugpy contrib</a></p>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
<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><a href="../index.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">Debugging</a><ul>
|
||
<li><a class="reference internal" href="#debugging-evennia">Debugging Evennia</a></li>
|
||
<li><a class="reference internal" href="#a-simple-example-using-pdb">A simple example using pdb</a><ul>
|
||
<li><a class="reference internal" href="#listing-surrounding-lines-of-code">Listing surrounding lines of code</a></li>
|
||
<li><a class="reference internal" href="#examining-variables">Examining variables</a></li>
|
||
<li><a class="reference internal" href="#executing-the-current-line">Executing the current line</a></li>
|
||
<li><a class="reference internal" href="#letting-the-program-run">Letting the program run</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#cheat-sheet-of-pdb-pudb-commands">Cheat-sheet of pdb/pudb commands</a></li>
|
||
<li><a class="reference internal" href="#debugging-with-debugpy">Debugging with debugpy</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<div>
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="Version-Control.html"
|
||
title="previous chapter">Coding using Version Control</a></p>
|
||
</div>
|
||
<div>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="Unit-Testing.html"
|
||
title="next chapter">Unit Testing</a></p>
|
||
</div>
|
||
<div role="note" aria-label="source link">
|
||
<!--h3>This Page</h3-->
|
||
<ul class="this-page-menu">
|
||
<li><a href="../_sources/Coding/Debugging.md.txt"
|
||
rel="nofollow">Show Page Source</a></li>
|
||
</ul>
|
||
</div><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="right" >
|
||
<a href="Unit-Testing.html" title="Unit Testing"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="Version-Control.html" title="Coding using Version Control"
|
||
>previous</a> |</li>
|
||
<li class="nav-item nav-item-0"><a href="../index.html">Evennia</a> »</li>
|
||
<li class="nav-item nav-item-1"><a href="Coding-Overview.html" >Coding and development help</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Debugging</a></li>
|
||
</ul>
|
||
</div>
|
||
<div class="footer" role="contentinfo">
|
||
© Copyright 2024, The Evennia developer community.
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
|
||
</div>
|
||
</body>
|
||
</html> |