CINXE.COM
PEP 760 – No More Bare Excepts | 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 760 – No More Bare Excepts | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0760/"> <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 760 – No More Bare Excepts | peps.python.org'> <meta property="og:description" content="This PEP proposes disallowing bare except: clauses in Python’s exception-handling syntax. Currently, Python allows catching all exceptions with a bare except: clause, which can lead to overly broad exception handling and mask important errors. This PEP ..."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0760/"> <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 disallowing bare except: clauses in Python’s exception-handling syntax. Currently, Python allows catching all exceptions with a bare except: clause, which can lead to overly broad exception handling and mask important errors. This PEP ..."> <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 760</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 760 – No More Bare Excepts</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Pablo Galindo <pablogsal at python.org>, Brett Cannon <brett at python.org></dd> <dt class="field-even">Status<span class="colon">:</span></dt> <dd class="field-even"><abbr title="Removed from consideration by sponsor or authors">Withdrawn</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">02-Oct-2024</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">3.14</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even"><a class="reference external" href="https://discuss.python.org/t/pep-760-no-more-bare-excepts/67182" title="Discourse thread">09-Oct-2024</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="#motivation">Motivation</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#specification">Specification</a></li> <li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li> <li><a class="reference internal" href="#security-implications">Security Implications</a></li> <li><a class="reference internal" href="#how-to-teach-this">How to Teach This</a></li> <li><a class="reference internal" href="#rejected-ideas">Rejected ideas</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 disallowing bare <code class="docutils literal notranslate"><span class="pre">except:</span></code> clauses in Python’s exception-handling syntax. Currently, Python allows catching all exceptions with a bare <code class="docutils literal notranslate"><span class="pre">except:</span></code> clause, which can lead to overly broad exception handling and mask important errors. This PEP suggests requiring explicit exception types in all except clauses, promoting more precise and intentional error handling.</p> </section> <section id="motivation"> <h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2> <p>The current syntax allows for catching all exceptions with a bare <code class="docutils literal notranslate"><span class="pre">except:</span></code> clause:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span> <span class="n">risky_operation</span><span class="p">()</span> <span class="k">except</span><span class="p">:</span> <span class="n">handle_any_error</span><span class="p">()</span> </pre></div> </div> <p>While this syntax can be convenient for a “catch all” handler, it often leads to poor coding practices:</p> <ol class="arabic simple"> <li>It can mask important errors that should be propagated.</li> <li>It makes debugging more difficult by catching and potentially hiding unexpected exceptions.</li> <li>It goes against the Python principle of explicit over implicit.</li> </ol> <p>Various linters <a class="footnote-reference brackets" href="#id9" id="id1">[1]</a> <a class="footnote-reference brackets" href="#id10" id="id2">[2]</a> <a class="footnote-reference brackets" href="#id11" id="id3">[3]</a> and style guides (including <a class="pep reference internal" href="../pep-0008/" title="PEP 8 – Style Guide for Python Code">PEP 8</a>) <a class="footnote-reference brackets" href="#id12" id="id4">[4]</a> <a class="footnote-reference brackets" href="#id13" id="id5">[5]</a> <a class="footnote-reference brackets" href="#id14" id="id6">[6]</a> <a class="footnote-reference brackets" href="#id15" id="id7">[7]</a> discourage bare <code class="docutils literal notranslate"><span class="pre">except</span></code> clauses.</p> <p>By requiring explicit exception types, we can encourage more thoughtful and precise error handling:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span> <span class="n">risky_operation</span><span class="p">()</span> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> <span class="n">handle_expected_error</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> </pre></div> </div> <p>Another view of this problem is that bare except handlers are ambiguous regarding the intended handling of terminating exceptions, as the intention could have been either:</p> <ul class="simple"> <li>Only catch non-terminating exceptions (<code class="docutils literal notranslate"><span class="pre">except</span> <span class="pre">Exception:</span></code>). If this was the intention, using a bare <code class="docutils literal notranslate"><span class="pre">except:</span></code> is an outright bug, since that isn’t what it means.</li> <li>Catch all exceptions, including terminating ones (<code class="docutils literal notranslate"><span class="pre">except</span> <span class="pre">BaseException:</span></code>). using bare <code class="docutils literal notranslate"><span class="pre">except:</span></code> here it is at least correct, but readers need to check to be sure it isn’t an instance of the first case.</li> </ul> <p>Since both possible intentions have available unambiguous spellings, the ambiguous form is redundant and that’s why we propose to disallow it.</p> </section> <section id="rationale"> <h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2> <p>The decision to disallow bare except clauses is based on the following considerations:</p> <ol class="arabic simple"> <li>Requiring specific exception types makes the programmer’s intentions clear and encourages thinking about what exceptions might occur.</li> <li>Catching only specific exceptions makes identifying and debugging unexpected errors easier.</li> <li>Preventing overly broad exception handling reduces the risk of silently ignoring critical errors.</li> <li>Many style guides and linters already discourage the use of bare except clauses.</li> </ol> </section> <section id="specification"> <h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2> <p>The syntax for the except clause will be modified to require an exception type. The grammar will be updated to remove the possibility of adding an empty expression in except clauses.</p> <p>This change disallows the bare <code class="docutils literal notranslate"><span class="pre">except:</span></code> syntax. All except clauses must specify at least one exception type:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span> <span class="o">...</span> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="o">...</span> <span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">RuntimeError</span><span class="p">):</span> <span class="o">...</span> <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span> <span class="o">...</span> <span class="c1"># Still allowed, but catches all exceptions explicitly</span> </pre></div> </div> <p>The semantics of exception handling remain unchanged, except that it will no longer be possible to catch all exceptions without explicitly specifying <code class="docutils literal notranslate"><span class="pre">BaseException</span></code> or a similarly broad exception type.</p> </section> <section id="backwards-compatibility"> <h2><a class="toc-backref" href="#backwards-compatibility" role="doc-backlink">Backwards Compatibility</a></h2> <p>This change is not backwards compatible. Existing code that uses bare <code class="docutils literal notranslate"><span class="pre">except:</span></code> clauses will need to be modified. To ease the transition:</p> <ol class="arabic simple"> <li>A deprecation warning will be issued for bare except clauses in Python 3.14.</li> <li>The syntax will be fully disallowed in Python 3.17.</li> <li>A <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">__future__</span> <span class="pre">import</span> <span class="pre">strict_excepts</span></code> will be provided to invalidate bare except handlers in earlier versions of Python.</li> </ol> <p>A tool will be provided to automatically update code to replace bare <code class="docutils literal notranslate"><span class="pre">except:</span></code> with <code class="docutils literal notranslate"><span class="pre">except</span> <span class="pre">BaseException:</span></code>.</p> </section> <section id="security-implications"> <h2><a class="toc-backref" href="#security-implications" role="doc-backlink">Security Implications</a></h2> <p>This change has no security implications.</p> </section> <section id="how-to-teach-this"> <h2><a class="toc-backref" href="#how-to-teach-this" role="doc-backlink">How to Teach This</a></h2> <p>For new Python users, exception handling should be taught with explicit exception types from the start:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span> <span class="n">result</span> <span class="o">=</span> <span class="n">risky_operation</span><span class="p">()</span> <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="n">handle_value_error</span><span class="p">()</span> <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span> <span class="n">handle_type_error</span><span class="p">()</span> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> <span class="n">handle_unexpected_error</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> </pre></div> </div> <p>For experienced users, the change can be introduced as a best practice that is now enforced by the language. The following points should be emphasized:</p> <ol class="arabic simple"> <li>Always catch specific exceptions when possible.</li> <li>Use <code class="docutils literal notranslate"><span class="pre">except</span> <span class="pre">Exception:</span></code> as a last resort for truly unexpected errors.</li> <li>Never silence exceptions without careful consideration.</li> </ol> <p>Documentation should guide common exception hierarchies and how to choose appropriate exception types to catch.</p> </section> <section id="rejected-ideas"> <h2><a class="toc-backref" href="#rejected-ideas" role="doc-backlink">Rejected ideas</a></h2> <ul> <li>There are genuine cases where the use of bare <code class="docutils literal notranslate"><span class="pre">except:</span></code> handlers are correct. one of the examples that have been raised from Mailman <a class="footnote-reference brackets" href="#id16" id="id8">[8]</a> involves handling transactions in the face of any exception:<blockquote> <div><div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="nd">@contextmanager</span> <span class="k">def</span><span class="w"> </span><span class="nf">transaction</span><span class="p">():</span> <span class="w"> </span><span class="sd">"""Context manager for ensuring the transaction is complete."""</span> <span class="k">try</span><span class="p">:</span> <span class="k">yield</span> <span class="k">except</span><span class="p">:</span> <span class="n">config</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">abort</span><span class="p">()</span> <span class="k">raise</span> <span class="k">else</span><span class="p">:</span> <span class="n">config</span><span class="o">.</span><span class="n">db</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span> </pre></div> </div> </div></blockquote> <p>This code guarantees that no matter what exception occurs, any open transaction will be aborted, while in the successful condition, the transaction will be committed.</p> <p>We do believe that although there are cases such like this one where bare <code class="docutils literal notranslate"><span class="pre">except:</span></code> handlers are correct, it would be better to actually be explicit and use <code class="docutils literal notranslate"><span class="pre">except</span> <span class="pre">BaseException:</span></code> for the reasons indicated in the “Motivation” section.</p> </li> </ul> </section> <section id="copyright"> <h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2> <p>This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.</p> <aside class="footnote-list brackets"> <aside class="footnote brackets" id="id9" role="doc-footnote"> <dt class="label" id="id9">[<a href="#id1">1</a>]</dt> <dd><a class="reference external" href="https://pylint.pycqa.org/en/latest/user_guide/messages/warning/bare-except.html">https://pylint.pycqa.org/en/latest/user_guide/messages/warning/bare-except.html</a></aside> <aside class="footnote brackets" id="id10" role="doc-footnote"> <dt class="label" id="id10">[<a href="#id2">2</a>]</dt> <dd><a class="reference external" href="https://www.flake8rules.com/rules/E722.html">https://www.flake8rules.com/rules/E722.html</a></aside> <aside class="footnote brackets" id="id11" role="doc-footnote"> <dt class="label" id="id11">[<a href="#id3">3</a>]</dt> <dd><a class="reference external" href="https://docs.astral.sh/ruff/rules/bare-except/">https://docs.astral.sh/ruff/rules/bare-except/</a></aside> <aside class="footnote brackets" id="id12" role="doc-footnote"> <dt class="label" id="id12">[<a href="#id4">4</a>]</dt> <dd><a class="reference external" href="https://google.github.io/styleguide/pyguide.html#24-exceptions">https://google.github.io/styleguide/pyguide.html#24-exceptions</a></aside> <aside class="footnote brackets" id="id13" role="doc-footnote"> <dt class="label" id="id13">[<a href="#id5">5</a>]</dt> <dd><a class="reference external" href="https://chromium.googlesource.com/chromiumos/platform/factory/+/HEAD/CODING_STYLE.md#Avoid-bare_except">https://chromium.googlesource.com/chromiumos/platform/factory/+/HEAD/CODING_STYLE.md#Avoid-bare_except</a></aside> <aside class="footnote brackets" id="id14" role="doc-footnote"> <dt class="label" id="id14">[<a href="#id6">6</a>]</dt> <dd><a class="reference external" href="https://4.docs.plone.org/develop/plone-coredev/style.html#concrete-rules">https://4.docs.plone.org/develop/plone-coredev/style.html#concrete-rules</a></aside> <aside class="footnote brackets" id="id15" role="doc-footnote"> <dt class="label" id="id15">[<a href="#id7">7</a>]</dt> <dd><a class="reference external" href="https://docs.openedx.org/en/latest/developers/references/developer_guide/style_guides/python-guidelines.html">https://docs.openedx.org/en/latest/developers/references/developer_guide/style_guides/python-guidelines.html</a></aside> <aside class="footnote brackets" id="id16" role="doc-footnote"> <dt class="label" id="id16">[<a href="#id8">8</a>]</dt> <dd><a class="reference external" href="https://gitlab.com/mailman/mailman/-/blob/master/src/mailman/database/transaction.py#L27">https://gitlab.com/mailman/mailman/-/blob/master/src/mailman/database/transaction.py#L27</a></aside> </aside> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0760.rst">https://github.com/python/peps/blob/main/peps/pep-0760.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0760.rst">2025-02-01 07:28:42 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="#motivation">Motivation</a></li> <li><a class="reference internal" href="#rationale">Rationale</a></li> <li><a class="reference internal" href="#specification">Specification</a></li> <li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li> <li><a class="reference internal" href="#security-implications">Security Implications</a></li> <li><a class="reference internal" href="#how-to-teach-this">How to Teach This</a></li> <li><a class="reference internal" href="#rejected-ideas">Rejected ideas</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-0760.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>