CINXE.COM
PEP 553 – Built-in breakpoint() | peps.python.org
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="color-scheme" content="light dark"> <title>PEP 553 – Built-in breakpoint() | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0553/"> <link rel="stylesheet" href="../_static/style.css" type="text/css"> <link rel="stylesheet" href="../_static/mq.css" type="text/css"> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light"> <link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark"> <link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss"> <meta property="og:title" content='PEP 553 – Built-in breakpoint() | peps.python.org'> <meta property="og:description" content="This PEP proposes adding a new built-in function called breakpoint() which enters a Python debugger at the point of the call. Additionally, two new names are added to the sys module to make the choice of which debugger is entered configurable."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0553/"> <meta property="og:site_name" content="Python Enhancement Proposals (PEPs)"> <meta property="og:image" content="https://peps.python.org/_static/og-image.png"> <meta property="og:image:alt" content="Python PEPs"> <meta property="og:image:width" content="200"> <meta property="og:image:height" content="200"> <meta name="description" content="This PEP proposes adding a new built-in function called breakpoint() which enters a Python debugger at the point of the call. Additionally, two new names are added to the sys module to make the choice of which debugger is entered configurable."> <meta name="theme-color" content="#3776ab"> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all"> <title>Following system colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="9"></circle> <path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path> </svg> </symbol> <symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all"> <title>Selected dark colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path> </svg> </symbol> <symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all"> <title>Selected light colour scheme</title> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> </symbol> </svg> <script> document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto" </script> <section id="pep-page-section"> <header> <h1>Python Enhancement Proposals</h1> <ul class="breadcrumbs"> <li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> » </li> <li><a href="../pep-0000/">PEP Index</a> » </li> <li>PEP 553</li> </ul> <button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())"> <svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg> <svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg> <span class="visually-hidden">Toggle light / dark / auto colour theme</span> </button> </header> <article> <section id="pep-content"> <h1 class="page-title">PEP 553 – Built-in breakpoint()</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Barry Warsaw <barry at python.org></dd> <dt class="field-even">Status<span class="colon">:</span></dt> <dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd> <dt class="field-odd">Type<span class="colon">:</span></dt> <dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd> <dt class="field-even">Created<span class="colon">:</span></dt> <dd class="field-even">05-Sep-2017</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">3.7</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even">05-Sep-2017, 07-Sep-2017, 13-Sep-2017</dd> <dt class="field-odd">Resolution<span class="colon">:</span></dt> <dd class="field-odd"><a class="reference external" href="https://mail.python.org/pipermail/python-dev/2017-October/149705.html">Python-Dev message</a></dd> </dl> <hr class="docutils" /> <section id="contents"> <details><summary>Table of Contents</summary><ul class="simple"> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#proposal">Proposal</a></li> <li><a class="reference internal" href="#environment-variable">Environment variable</a></li> <li><a class="reference internal" href="#implementation">Implementation</a></li> <li><a class="reference internal" href="#rejected-alternatives">Rejected alternatives</a><ul> <li><a class="reference internal" href="#a-new-keyword">A new keyword</a></li> <li><a class="reference internal" href="#sys-breakpoint">sys.breakpoint()</a></li> </ul> </li> <li><a class="reference internal" href="#version-history">Version History</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> </details></section> <section id="abstract"> <h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2> <p>This PEP proposes adding a new built-in function called <code class="docutils literal notranslate"><span class="pre">breakpoint()</span></code> which enters a Python debugger at the point of the call. Additionally, two new names are added to the <code class="docutils literal notranslate"><span class="pre">sys</span></code> module to make the choice of which debugger is entered configurable.</p> </section> <section id="rationale"> <h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2> <p>Python has long had a great debugger in its standard library called <code class="docutils literal notranslate"><span class="pre">pdb</span></code>. Setting a break point is commonly written like this:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">foo</span><span class="p">()</span> <span class="kn">import</span><span class="w"> </span><span class="nn">pdb</span><span class="p">;</span> <span class="n">pdb</span><span class="o">.</span><span class="n">set_trace</span><span class="p">()</span> <span class="n">bar</span><span class="p">()</span> </pre></div> </div> <p>Thus after executing <code class="docutils literal notranslate"><span class="pre">foo()</span></code> and before executing <code class="docutils literal notranslate"><span class="pre">bar()</span></code>, Python will enter the debugger. However this idiom has several disadvantages.</p> <ul class="simple"> <li>It’s a lot to type (27 characters).</li> <li>It’s easy to typo. The PEP author often mistypes this line, e.g. omitting the semicolon, or typing a dot instead of an underscore.</li> <li>It ties debugging directly to the choice of pdb. There might be other debugging options, say if you’re using an IDE or some other development environment.</li> <li>Python linters (e.g. flake8 <a class="reference internal" href="#linters" id="id1"><span>[linters]</span></a>) complain about this line because it contains two statements. Breaking the idiom up into two lines complicates its use because there are more opportunities for mistakes at clean up time. I.e. you might forget to delete one of those lines when you no longer need to debug the code.</li> </ul> <p>Python developers also have many other debuggers to choose from, but remembering how to invoke them can be problematic. For example, even when IDEs have user interface for setting breakpoints, it may still be more convenient to just edit the code. The APIs for entering the debugger programmatically are inconsistent, so it can be difficult to remember exactly what to type.</p> <p>We can solve all these problems by providing a universal API for entering the debugger, as proposed in this PEP.</p> </section> <section id="proposal"> <h2><a class="toc-backref" href="#proposal" role="doc-backlink">Proposal</a></h2> <p>The JavaScript language provides a <code class="docutils literal notranslate"><span class="pre">debugger</span></code> statement <a class="reference internal" href="#js-debugger" id="id2"><span>[js-debugger]</span></a> which enters the debugger at the point where the statement appears.</p> <p>This PEP proposes a new built-in function called <code class="docutils literal notranslate"><span class="pre">breakpoint()</span></code> which enters a Python debugger at the call site. Thus the example above would be written like so:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">foo</span><span class="p">()</span> <span class="nb">breakpoint</span><span class="p">()</span> <span class="n">bar</span><span class="p">()</span> </pre></div> </div> <p>Further, this PEP proposes two new name bindings for the <code class="docutils literal notranslate"><span class="pre">sys</span></code> module, called <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook()</span></code> and <code class="docutils literal notranslate"><span class="pre">sys.__breakpointhook__</span></code>. By default, <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook()</span></code> implements the actual importing and entry into <code class="docutils literal notranslate"><span class="pre">pdb.set_trace()</span></code>, and it can be set to a different function to change the debugger that <code class="docutils literal notranslate"><span class="pre">breakpoint()</span></code> enters.</p> <p><code class="docutils literal notranslate"><span class="pre">sys.__breakpointhook__</span></code> is initialized to the same function as <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook()</span></code> so that you can always easily reset <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook()</span></code> to the default value (e.g. by doing <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook</span> <span class="pre">=</span> <span class="pre">sys.__breakpointhook__</span></code>). This is exactly the same as how the existing <code class="docutils literal notranslate"><span class="pre">sys.displayhook()</span></code> / <code class="docutils literal notranslate"><span class="pre">sys.__displayhook__</span></code> and <code class="docutils literal notranslate"><span class="pre">sys.excepthook()</span></code> / <code class="docutils literal notranslate"><span class="pre">sys.__excepthook__</span></code> work <a class="reference internal" href="#hooks" id="id3"><span>[hooks]</span></a>.</p> <p>The signature of the built-in is <code class="docutils literal notranslate"><span class="pre">breakpoint(*args,</span> <span class="pre">**kws)</span></code>. The positional and keyword arguments are passed straight through to <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook()</span></code> and the signatures must match or a <code class="docutils literal notranslate"><span class="pre">TypeError</span></code> will be raised. The return from <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook()</span></code> is passed back up to, and returned from <code class="docutils literal notranslate"><span class="pre">breakpoint()</span></code>.</p> <p>The rationale for this is based on the observation that the underlying debuggers may accept additional optional arguments. For example, IPython allows you to specify a string that gets printed when the break point is entered <a class="reference internal" href="#ipython-embed" id="id4"><span>[ipython-embed]</span></a>. As of Python 3.7, the pdb module also supports an optional <code class="docutils literal notranslate"><span class="pre">header</span></code> argument <a class="reference internal" href="#pdb-header" id="id5"><span>[pdb-header]</span></a>.</p> </section> <section id="environment-variable"> <h2><a class="toc-backref" href="#environment-variable" role="doc-backlink">Environment variable</a></h2> <p>The default implementation of <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook()</span></code> consults a new environment variable called <code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT</span></code>. This environment variable can have various values:</p> <ul class="simple"> <li><code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT=0</span></code> disables debugging. Specifically, with this value <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook()</span></code> returns <code class="docutils literal notranslate"><span class="pre">None</span></code> immediately.</li> <li><code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT=</span></code> (i.e. the empty string). This is the same as not setting the environment variable at all, in which case <code class="docutils literal notranslate"><span class="pre">pdb.set_trace()</span></code> is run as usual.</li> <li><code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT=some.importable.callable</span></code>. In this case, <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook()</span></code> imports the <code class="docutils literal notranslate"><span class="pre">some.importable</span></code> module and gets the <code class="docutils literal notranslate"><span class="pre">callable</span></code> object from the resulting module, which it then calls. The value may be a string with no dots, in which case it names a built-in callable, e.g. <code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT=int</span></code>. (Guido has expressed the preference for normal Python dotted-paths, not setuptools-style entry point syntax <a class="reference internal" href="#syntax" id="id6"><span>[syntax]</span></a>.)</li> </ul> <p>This environment variable allows external processes to control how breakpoints are handled. Some uses cases include:</p> <ul class="simple"> <li>Completely disabling all accidental <code class="docutils literal notranslate"><span class="pre">breakpoint()</span></code> calls pushed to production. This could be accomplished by setting <code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT=0</span></code> in the execution environment. Another suggestion by reviewers of the PEP was to set <code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT=sys.exit</span></code> in this case.</li> <li>IDE integration with specialized debuggers for embedded execution. The IDE would run the program in its debugging environment with <code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT</span></code> set to their internal debugging hook.</li> </ul> <p><code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT</span></code> is re-interpreted every time <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook()</span></code> is reached. This allows processes to change its value during the execution of a program and have <code class="docutils literal notranslate"><span class="pre">breakpoint()</span></code> respond to those changes. It is not considered a performance critical section since entering a debugger by definition stops execution. Thus, programs can do the following:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s1">'PYTHONBREAKPOINT'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'foo.bar.baz'</span> <span class="nb">breakpoint</span><span class="p">()</span> <span class="c1"># Imports foo.bar and calls foo.bar.baz()</span> </pre></div> </div> <p>Overriding <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook</span></code> defeats the default consultation of <code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT</span></code>. It is up to the overriding code to consult <code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT</span></code> if they want.</p> <p>If access to the <code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT</span></code> callable fails in any way (e.g. the import fails, or the resulting module does not contain the callable), a <code class="docutils literal notranslate"><span class="pre">RuntimeWarning</span></code> is issued, and no breakpoint function is called.</p> <p>Note that as with all other <code class="docutils literal notranslate"><span class="pre">PYTHON*</span></code> environment variables, <code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT</span></code> is ignored when the interpreter is started with <code class="docutils literal notranslate"><span class="pre">-E</span></code>. This means the default behavior will occur (i.e. <code class="docutils literal notranslate"><span class="pre">pdb.set_trace()</span></code> will run). There was some discussion about alternatively treating <code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT=0</span></code> when <code class="docutils literal notranslate"><span class="pre">-E</span></code> as in effect, but the opinions were inconclusive, so it was decided that this wasn’t special enough for a special case.</p> </section> <section id="implementation"> <h2><a class="toc-backref" href="#implementation" role="doc-backlink">Implementation</a></h2> <p>A pull request exists with the proposed implementation <a class="reference internal" href="#impl" id="id7"><span>[impl]</span></a>.</p> <p>While the actual implementation is in C, the Python pseudo-code for this feature looks roughly like the following:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># In builtins.</span> <span class="k">def</span><span class="w"> </span><span class="nf">breakpoint</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">kws</span><span class="p">):</span> <span class="kn">import</span><span class="w"> </span><span class="nn">sys</span> <span class="n">missing</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span> <span class="n">hook</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">sys</span><span class="p">,</span> <span class="s1">'breakpointhook'</span><span class="p">,</span> <span class="n">missing</span><span class="p">)</span> <span class="k">if</span> <span class="n">hook</span> <span class="ow">is</span> <span class="n">missing</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s1">'lost sys.breakpointhook'</span><span class="p">)</span> <span class="k">return</span> <span class="n">hook</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">kws</span><span class="p">)</span> <span class="c1"># In sys.</span> <span class="k">def</span><span class="w"> </span><span class="nf">breakpointhook</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">kws</span><span class="p">):</span> <span class="kn">import</span><span class="w"> </span><span class="nn">importlib</span><span class="o">,</span><span class="w"> </span><span class="nn">os</span><span class="o">,</span><span class="w"> </span><span class="nn">warnings</span> <span class="n">hookname</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s1">'PYTHONBREAKPOINT'</span><span class="p">)</span> <span class="k">if</span> <span class="n">hookname</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">hookname</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> <span class="n">hookname</span> <span class="o">=</span> <span class="s1">'pdb.set_trace'</span> <span class="k">elif</span> <span class="n">hookname</span> <span class="o">==</span> <span class="s1">'0'</span><span class="p">:</span> <span class="k">return</span> <span class="kc">None</span> <span class="n">modname</span><span class="p">,</span> <span class="n">dot</span><span class="p">,</span> <span class="n">funcname</span> <span class="o">=</span> <span class="n">hookname</span><span class="o">.</span><span class="n">rpartition</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)</span> <span class="k">if</span> <span class="n">dot</span> <span class="o">==</span> <span class="s1">''</span><span class="p">:</span> <span class="n">modname</span> <span class="o">=</span> <span class="s1">'builtins'</span> <span class="k">try</span><span class="p">:</span> <span class="n">module</span> <span class="o">=</span> <span class="n">importlib</span><span class="o">.</span><span class="n">import_module</span><span class="p">(</span><span class="n">modname</span><span class="p">)</span> <span class="n">hook</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">funcname</span><span class="p">)</span> <span class="k">except</span><span class="p">:</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s1">'Ignoring unimportable $PYTHONBREAKPOINT: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> <span class="n">hookname</span><span class="p">),</span> <span class="ne">RuntimeWarning</span><span class="p">)</span> <span class="k">return</span> <span class="kc">None</span> <span class="k">return</span> <span class="n">hook</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">kws</span><span class="p">)</span> <span class="n">__breakpointhook__</span> <span class="o">=</span> <span class="n">breakpointhook</span> </pre></div> </div> </section> <section id="rejected-alternatives"> <h2><a class="toc-backref" href="#rejected-alternatives" role="doc-backlink">Rejected alternatives</a></h2> <section id="a-new-keyword"> <h3><a class="toc-backref" href="#a-new-keyword" role="doc-backlink">A new keyword</a></h3> <p>Originally, the author considered a new keyword, or an extension to an existing keyword such as <code class="docutils literal notranslate"><span class="pre">break</span> <span class="pre">here</span></code>. This is rejected on several fronts.</p> <ul class="simple"> <li>A brand new keyword would require a <code class="docutils literal notranslate"><span class="pre">__future__</span></code> to enable it since almost any new keyword could conflict with existing code. This negates the ease with which you can enter the debugger.</li> <li>An extended keyword such as <code class="docutils literal notranslate"><span class="pre">break</span> <span class="pre">here</span></code>, while more readable and not requiring a <code class="docutils literal notranslate"><span class="pre">__future__</span></code> would tie the keyword extension to this new feature, preventing more useful extensions such as those proposed in <a class="pep reference internal" href="../pep-0548/" title="PEP 548 – More Flexible Loop Control">PEP 548</a>.</li> <li>A new keyword would require a modified grammar and likely a new bytecode. Each of these makes the implementation more complex. A new built-in breaks no existing code (since any existing module global would just shadow the built-in) and is quite easy to implement.</li> </ul> </section> <section id="sys-breakpoint"> <h3><a class="toc-backref" href="#sys-breakpoint" role="doc-backlink">sys.breakpoint()</a></h3> <p>Why not <code class="docutils literal notranslate"><span class="pre">sys.breakpoint()</span></code>? Requiring an import to invoke the debugger is explicitly rejected because <code class="docutils literal notranslate"><span class="pre">sys</span></code> is not imported in every module. That just requires more typing and would lead to:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">sys</span><span class="p">;</span> <span class="n">sys</span><span class="o">.</span><span class="n">breakpoint</span><span class="p">()</span> </pre></div> </div> <p>which inherits several of the problems this PEP aims to solve.</p> </section> </section> <section id="version-history"> <h2><a class="toc-backref" href="#version-history" role="doc-backlink">Version History</a></h2> <ul class="simple"> <li>2019-10-13<ul> <li>Add missing <code class="docutils literal notranslate"><span class="pre">return</span> <span class="pre">None</span></code> in <code class="docutils literal notranslate"><span class="pre">except</span></code> clause to pseudo-code.</li> </ul> </li> <li>2017-09-13<ul> <li>The <code class="docutils literal notranslate"><span class="pre">PYTHONBREAKPOINT</span></code> environment variable is made a first class feature.</li> </ul> </li> <li>2017-09-07<ul> <li><code class="docutils literal notranslate"><span class="pre">debug()</span></code> renamed to <code class="docutils literal notranslate"><span class="pre">breakpoint()</span></code></li> <li>Signature changed to <code class="docutils literal notranslate"><span class="pre">breakpoint(*args,</span> <span class="pre">**kws)</span></code> which is passed straight through to <code class="docutils literal notranslate"><span class="pre">sys.breakpointhook()</span></code>.</li> </ul> </li> </ul> </section> <section id="references"> <h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2> <div role="list" class="citation-list"> <div class="citation" id="ipython-embed" role="doc-biblioentry"> <dt class="label" id="ipython-embed">[<a href="#id4">ipython-embed</a>]</dt> <dd><a class="reference external" href="http://ipython.readthedocs.io/en/stable/api/generated/IPython.terminal.embed.html">http://ipython.readthedocs.io/en/stable/api/generated/IPython.terminal.embed.html</a></div> <div class="citation" id="pdb-header" role="doc-biblioentry"> <dt class="label" id="pdb-header">[<a href="#id5">pdb-header</a>]</dt> <dd><a class="reference external" href="https://docs.python.org/3.7/library/pdb.html#pdb.set_trace">https://docs.python.org/3.7/library/pdb.html#pdb.set_trace</a></div> <div class="citation" id="linters" role="doc-biblioentry"> <dt class="label" id="linters">[<a href="#id1">linters</a>]</dt> <dd><a class="reference external" href="http://flake8.readthedocs.io/en/latest/">http://flake8.readthedocs.io/en/latest/</a></div> <div class="citation" id="js-debugger" role="doc-biblioentry"> <dt class="label" id="js-debugger">[<a href="#id2">js-debugger</a>]</dt> <dd><a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger</a></div> <div class="citation" id="hooks" role="doc-biblioentry"> <dt class="label" id="hooks">[<a href="#id3">hooks</a>]</dt> <dd><a class="reference external" href="https://docs.python.org/3/library/sys.html#sys.displayhook">https://docs.python.org/3/library/sys.html#sys.displayhook</a></div> <div class="citation" id="syntax" role="doc-biblioentry"> <dt class="label" id="syntax">[<a href="#id6">syntax</a>]</dt> <dd><a class="reference external" href="http://setuptools.readthedocs.io/en/latest/setuptools.html?highlight=console#automatic-script-creation">http://setuptools.readthedocs.io/en/latest/setuptools.html?highlight=console#automatic-script-creation</a></div> <div class="citation" id="impl" role="doc-biblioentry"> <dt class="label" id="impl">[<a href="#id7">impl</a>]</dt> <dd><a class="reference external" href="https://github.com/python/cpython/pull/3355">https://github.com/python/cpython/pull/3355</a></div> </div> </section> <section id="copyright"> <h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2> <p>This document has been placed in the public domain.</p> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0553.rst">https://github.com/python/peps/blob/main/peps/pep-0553.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0553.rst">2025-02-01 08:55:40 GMT</a></p> </article> <nav id="pep-sidebar"> <h2>Contents</h2> <ul> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#proposal">Proposal</a></li> <li><a class="reference internal" href="#environment-variable">Environment variable</a></li> <li><a class="reference internal" href="#implementation">Implementation</a></li> <li><a class="reference internal" href="#rejected-alternatives">Rejected alternatives</a><ul> <li><a class="reference internal" href="#a-new-keyword">A new keyword</a></li> <li><a class="reference internal" href="#sys-breakpoint">sys.breakpoint()</a></li> </ul> </li> <li><a class="reference internal" href="#version-history">Version History</a></li> <li><a class="reference internal" href="#references">References</a></li> <li><a class="reference internal" href="#copyright">Copyright</a></li> </ul> <br> <a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0553.rst">Page Source (GitHub)</a> </nav> </section> <script src="../_static/colour_scheme.js"></script> <script src="../_static/wrap_tables.js"></script> <script src="../_static/sticky_banner.js"></script> </body> </html>