CINXE.COM
PEP 663 – Standardizing Enum str(), repr(), and format() behaviors | 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 663 – Standardizing Enum str(), repr(), and format() behaviors | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0663/"> <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 663 – Standardizing Enum str(), repr(), and format() behaviors | peps.python.org'> <meta property="og:description" content="Update the repr(), str(), and format() of the various Enum types to better match their intended purpose. For example, IntEnum will have its str() change to match its format(), while a user-mixed int-enum will have its format() match its str(). In all ..."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0663/"> <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="Update the repr(), str(), and format() of the various Enum types to better match their intended purpose. For example, IntEnum will have its str() change to match its format(), while a user-mixed int-enum will have its format() match its str(). In all ..."> <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 663</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 663 – Standardizing Enum str(), repr(), and format() behaviors</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Ethan Furman <ethan at stoneleaf.us></dd> <dt class="field-even">Discussions-To<span class="colon">:</span></dt> <dd class="field-even"><a class="reference external" href="https://mail.python.org/archives/list/python-dev@python.org/">Python-Dev list</a></dd> <dt class="field-odd">Status<span class="colon">:</span></dt> <dd class="field-odd"><abbr title="Formally declined and will not be accepted">Rejected</abbr></dd> <dt class="field-even">Type<span class="colon">:</span></dt> <dd class="field-even"><abbr title="Non-normative PEP containing background, guidelines or other information relevant to the Python ecosystem">Informational</abbr></dd> <dt class="field-odd">Created<span class="colon">:</span></dt> <dd class="field-odd">30-Jun-2021</dd> <dt class="field-even">Python-Version<span class="colon">:</span></dt> <dd class="field-even">3.11</dd> <dt class="field-odd">Post-History<span class="colon">:</span></dt> <dd class="field-odd">20-Jul-2021, 02-Nov-2021</dd> <dt class="field-even">Resolution<span class="colon">:</span></dt> <dd class="field-even"><a class="reference external" href="https://mail.python.org/archives/list/python-dev@python.org/message/RN3WCRZSTQR55DOHJTZ2KIO6CZPJPCU7/">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="#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="#copyright">Copyright</a></li> </ul> </details></section> <section id="abstract"> <h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2> <p>Update the <code class="docutils literal notranslate"><span class="pre">repr()</span></code>, <code class="docutils literal notranslate"><span class="pre">str()</span></code>, and <code class="docutils literal notranslate"><span class="pre">format()</span></code> of the various Enum types to better match their intended purpose. For example, <code class="docutils literal notranslate"><span class="pre">IntEnum</span></code> will have its <code class="docutils literal notranslate"><span class="pre">str()</span></code> change to match its <code class="docutils literal notranslate"><span class="pre">format()</span></code>, while a user-mixed int-enum will have its <code class="docutils literal notranslate"><span class="pre">format()</span></code> match its <code class="docutils literal notranslate"><span class="pre">str()</span></code>. In all cases, an enum’s <code class="docutils literal notranslate"><span class="pre">str()</span></code> and <code class="docutils literal notranslate"><span class="pre">format()</span></code> will be the same (unless the user overrides <code class="docutils literal notranslate"><span class="pre">format()</span></code>).</p> <p>Add a global enum decorator which changes the <code class="docutils literal notranslate"><span class="pre">str()</span></code> and <code class="docutils literal notranslate"><span class="pre">repr()</span></code> (and <code class="docutils literal notranslate"><span class="pre">format()</span></code>) of the decorated enum to be a valid global reference: i.e. <code class="docutils literal notranslate"><span class="pre">re.IGNORECASE</span></code> instead of <code class="docutils literal notranslate"><span class="pre"><RegexFlag.IGNORECASE:</span> <span class="pre">2></span></code>.</p> </section> <section id="motivation"> <h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2> <p>Having the <code class="docutils literal notranslate"><span class="pre">str()</span></code> of <code class="docutils literal notranslate"><span class="pre">IntEnum</span></code> and <code class="docutils literal notranslate"><span class="pre">IntFlag</span></code> not be the value causes bugs and extra work when replacing existing constants.</p> <p>Having the <code class="docutils literal notranslate"><span class="pre">str()</span></code> and <code class="docutils literal notranslate"><span class="pre">format()</span></code> of an enum member be different can be confusing.</p> <p>The addition of <code class="docutils literal notranslate"><span class="pre">StrEnum</span></code> with its requirement to have its <code class="docutils literal notranslate"><span class="pre">str()</span></code> be its <code class="docutils literal notranslate"><span class="pre">value</span></code> is inconsistent with other provided Enum’s <code class="docutils literal notranslate"><span class="pre">str</span></code>.</p> <p>The iteration of <code class="docutils literal notranslate"><span class="pre">Flag</span></code> members, which directly affects their <code class="docutils literal notranslate"><span class="pre">repr()</span></code>, is inelegant at best, and buggy at worst.</p> </section> <section id="rationale"> <h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2> <p>Enums are becoming more common in the standard library; being able to recognize enum members by their <code class="docutils literal notranslate"><span class="pre">repr()</span></code>, and having that <code class="docutils literal notranslate"><span class="pre">repr()</span></code> be easy to parse, is useful and can save time and effort in understanding and debugging code.</p> <p>However, the enums with mixed-in data types (<code class="docutils literal notranslate"><span class="pre">IntEnum</span></code>, <code class="docutils literal notranslate"><span class="pre">IntFlag</span></code>, and the new <code class="docutils literal notranslate"><span class="pre">StrEnum</span></code>) need to be more backwards compatible with the constants they are replacing – specifically, <code class="docutils literal notranslate"><span class="pre">str(replacement_enum_member)</span> <span class="pre">==</span> <span class="pre">str(original_constant)</span></code> should be true (and the same for <code class="docutils literal notranslate"><span class="pre">format()</span></code>).</p> <p>IntEnum, IntFlag, and StrEnum should be as close to a drop-in replacement of existing integer and string constants as is possible. Towards that goal, the <code class="docutils literal notranslate"><span class="pre">str()</span></code> output of each should be its inherent value; e.g. if <code class="docutils literal notranslate"><span class="pre">Color</span></code> is an <code class="docutils literal notranslate"><span class="pre">IntEnum</span></code>:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">Color</span><span class="o">.</span><span class="n">RED</span> <span class="go"><Color.RED: 1></span> <span class="gp">>>> </span><span class="nb">str</span><span class="p">(</span><span class="n">Color</span><span class="o">.</span><span class="n">RED</span><span class="p">)</span> <span class="go">'1'</span> <span class="gp">>>> </span><span class="nb">format</span><span class="p">(</span><span class="n">Color</span><span class="o">.</span><span class="n">RED</span><span class="p">)</span> <span class="go">'1'</span> </pre></div> </div> <p>Note that <code class="docutils literal notranslate"><span class="pre">format()</span></code> already produces the correct output, only <code class="docutils literal notranslate"><span class="pre">str()</span></code> needs updating.</p> <p>As much as possible, the <code class="docutils literal notranslate"><span class="pre">str()</span></code>, <code class="docutils literal notranslate"><span class="pre">repr()</span></code>, and <code class="docutils literal notranslate"><span class="pre">format()</span></code> of enum members should be standardized across the standard library. However, up to Python 3.10 several enums in the standard library have a custom <code class="docutils literal notranslate"><span class="pre">str()</span></code> and/or <code class="docutils literal notranslate"><span class="pre">repr()</span></code>.</p> <p>The <code class="docutils literal notranslate"><span class="pre">repr()</span></code> of Flag currently includes aliases, which it should not; fixing that will, of course, already change its <code class="docutils literal notranslate"><span class="pre">repr()</span></code> in certain cases.</p> </section> <section id="specification"> <h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2> <p>There are three broad categories of enum usage:</p> <ul class="simple"> <li>simple: <code class="docutils literal notranslate"><span class="pre">Enum</span></code> or <code class="docutils literal notranslate"><span class="pre">Flag</span></code> a new enum class is created with no data type mixins</li> <li>drop-in replacement: <code class="docutils literal notranslate"><span class="pre">IntEnum</span></code>, <code class="docutils literal notranslate"><span class="pre">IntFlag</span></code>, <code class="docutils literal notranslate"><span class="pre">StrEnum</span></code> a new enum class is created which also subclasses <code class="docutils literal notranslate"><span class="pre">int</span></code> or <code class="docutils literal notranslate"><span class="pre">str</span></code> and uses <code class="docutils literal notranslate"><span class="pre">int.__str__</span></code> or <code class="docutils literal notranslate"><span class="pre">str.__str__</span></code></li> <li>user-mixed enums and flags the user creates their own integer-, float-, str-, whatever-enums instead of using enum.IntEnum, etc.</li> </ul> <p>There are also two styles:</p> <ul class="simple"> <li>normal: the enumeration members remain in their classes and are accessed as <code class="docutils literal notranslate"><span class="pre">classname.membername</span></code>, and the class name shows in their <code class="docutils literal notranslate"><span class="pre">repr()</span></code> and <code class="docutils literal notranslate"><span class="pre">str()</span></code> (where appropriate)</li> <li>global: the enumeration members are copied into their module’s global namespace, and their module name shows in their <code class="docutils literal notranslate"><span class="pre">repr()</span></code> and <code class="docutils literal notranslate"><span class="pre">str()</span></code> (where appropriate)</li> </ul> <p>Some sample enums:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># module: tools.py</span> <span class="k">class</span><span class="w"> </span><span class="nc">Hue</span><span class="p">(</span><span class="n">Enum</span><span class="p">):</span> <span class="c1"># or IntEnum</span> <span class="n">LIGHT</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span> <span class="n">NORMAL</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">DARK</span> <span class="o">=</span> <span class="o">+</span><span class="mi">1</span> <span class="k">class</span><span class="w"> </span><span class="nc">Color</span><span class="p">(</span><span class="n">Flag</span><span class="p">):</span> <span class="c1"># or IntFlag</span> <span class="n">RED</span> <span class="o">=</span> <span class="mi">1</span> <span class="n">GREEN</span> <span class="o">=</span> <span class="mi">2</span> <span class="n">BLUE</span> <span class="o">=</span> <span class="mi">4</span> <span class="k">class</span><span class="w"> </span><span class="nc">Grey</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">Enum</span><span class="p">):</span> <span class="c1"># or (int, Flag)</span> <span class="n">BLACK</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">WHITE</span> <span class="o">=</span> <span class="mi">1</span> </pre></div> </div> <p>Using the above enumerations, the following two tables show the old and new output (blank cells indicate no change):</p> <table class="docutils align-default"> <tbody> <tr class="row-odd"><td>style</td> <td colspan="2">category</td> <td>enum repr()</td> <td>enum str()</td> <td>enum format()</td> </tr> <tr class="row-even"><td rowspan="6">normal</td> <td rowspan="2">simple</td> <td>3.10</td> <td></td> <td></td> <td></td> </tr> <tr class="row-odd"><td>new</td> <td></td> <td></td> <td></td> </tr> <tr class="row-even"><td rowspan="2">user mixed</td> <td>3.10</td> <td></td> <td></td> <td>1</td> </tr> <tr class="row-odd"><td>new</td> <td></td> <td></td> <td>Grey.WHITE</td> </tr> <tr class="row-even"><td rowspan="2">int drop-in</td> <td>3.10</td> <td></td> <td>Hue.LIGHT</td> <td></td> </tr> <tr class="row-odd"><td>new</td> <td></td> <td>-1</td> <td></td> </tr> <tr class="row-even"><td rowspan="6">global</td> <td rowspan="2">simple</td> <td>3.10</td> <td><Hue.LIGHT: -1></td> <td>Hue.LIGHT</td> <td>Hue.LIGHT</td> </tr> <tr class="row-odd"><td>new</td> <td>tools.LIGHT</td> <td>LIGHT</td> <td>LIGHT</td> </tr> <tr class="row-even"><td rowspan="2">user mixed</td> <td>3.10</td> <td><Grey.WHITE: 1</td> <td>Grey.WHITE</td> <td>Grey.WHITE</td> </tr> <tr class="row-odd"><td>new</td> <td>tools.WHITE</td> <td>WHITE</td> <td>WHITE</td> </tr> <tr class="row-even"><td rowspan="2">int drop-in</td> <td>3.10</td> <td><Hue.LIGHT: -1></td> <td>Hue.LIGHT</td> <td></td> </tr> <tr class="row-odd"><td>new</td> <td>tools.LIGHT</td> <td>-1</td> <td></td> </tr> </tbody> </table> <table class="docutils align-default"> <tbody> <tr class="row-odd"><td>style</td> <td colspan="2">category</td> <td>flag repr()</td> <td>flag str()</td> <td>flag format()</td> </tr> <tr class="row-even"><td rowspan="6">normal</td> <td rowspan="2">simple</td> <td>3.10</td> <td><Color.RED|GREEN: 3></td> <td>Color.RED|GREEN</td> <td>Color.RED|GREEN</td> </tr> <tr class="row-odd"><td>new</td> <td><Color(3): RED|GREEN></td> <td>Color.RED|Color.GREEN</td> <td>Color.RED|Color.GREEN</td> </tr> <tr class="row-even"><td rowspan="2">user mixed</td> <td>3.10</td> <td><Grey.WHITE: 1></td> <td></td> <td>1</td> </tr> <tr class="row-odd"><td>new</td> <td><Grey(1): WHITE></td> <td></td> <td>Grey.WHITE</td> </tr> <tr class="row-even"><td rowspan="2">int drop-in</td> <td>3.10</td> <td><Color.RED|GREEN: 3></td> <td>Color.RED|GREEN</td> <td></td> </tr> <tr class="row-odd"><td>new</td> <td><Color(3): RED|GREEN></td> <td>3</td> <td></td> </tr> <tr class="row-even"><td rowspan="6">global</td> <td rowspan="2">simple</td> <td>3.10</td> <td><Color.RED|GREEN: 3></td> <td>Color.RED|GREEN</td> <td>Color.RED|GREEN</td> </tr> <tr class="row-odd"><td>new</td> <td>tools.RED|tools.GREEN</td> <td>RED|GREEN</td> <td>RED|GREEN</td> </tr> <tr class="row-even"><td rowspan="2">user mixed</td> <td>3.10</td> <td><Grey.WHITE: 1></td> <td>Grey.WHITE</td> <td>1</td> </tr> <tr class="row-odd"><td>new</td> <td>tools.WHITE</td> <td>WHITE</td> <td>WHITE</td> </tr> <tr class="row-even"><td rowspan="2">int drop-in</td> <td>3.10</td> <td><Color.RED|GREEN: 3></td> <td>Color.RED|GREEN</td> <td></td> </tr> <tr class="row-odd"><td>new</td> <td>tools.RED|tools.GREEN</td> <td>3</td> <td></td> </tr> </tbody> </table> <p>These two tables show the final result:</p> <table class="docutils align-default"> <tbody> <tr class="row-odd"><td>style</td> <td>category</td> <td>enum repr()</td> <td>enum str()</td> <td>enum format()</td> </tr> <tr class="row-even"><td rowspan="3">normal</td> <td>simple</td> <td><Hue.LIGHT: -1></td> <td>Hue.LIGHT</td> <td>Hue.LIGHT</td> </tr> <tr class="row-odd"><td>user mixed</td> <td><Grey.WHITE: 1></td> <td>Grey.WHITE</td> <td>Grey.WHITE</td> </tr> <tr class="row-even"><td>int drop-in</td> <td><Hue.LIGHT: -1></td> <td>-1</td> <td>-1</td> </tr> <tr class="row-odd"><td rowspan="3">global</td> <td>simple</td> <td>tools.LIGHT</td> <td>LIGHT</td> <td>LIGHT</td> </tr> <tr class="row-even"><td>user mixed</td> <td>tools.WHITE</td> <td>WHITE</td> <td>WHITE</td> </tr> <tr class="row-odd"><td>int drop-in</td> <td>tools.LIGHT</td> <td>-1</td> <td>-1</td> </tr> </tbody> </table> <table class="docutils align-default"> <tbody> <tr class="row-odd"><td>style</td> <td>category</td> <td>flag repr()</td> <td>flag str()</td> <td>flag format()</td> </tr> <tr class="row-even"><td rowspan="3">normal</td> <td>simple</td> <td><Color(3): RED|GREEN></td> <td>Color.RED|Color.GREEN</td> <td>Color.RED|Color.GREEN</td> </tr> <tr class="row-odd"><td>user mixed</td> <td><Grey(1): WHITE></td> <td>Grey.WHITE</td> <td>Grey.WHITE</td> </tr> <tr class="row-even"><td>int drop-in</td> <td><Color(3): RED|GREEN></td> <td>3</td> <td>3</td> </tr> <tr class="row-odd"><td rowspan="3">global</td> <td>simple</td> <td>tools.RED|tools.GREEN</td> <td>RED|GREEN</td> <td>RED|GREEN</td> </tr> <tr class="row-even"><td>user mixed</td> <td>tools.WHITE</td> <td>WHITE</td> <td>WHITE</td> </tr> <tr class="row-odd"><td>int drop-in</td> <td>tools.RED|tools.GREEN</td> <td>3</td> <td>3</td> </tr> </tbody> </table> <p>As can be seen, <code class="docutils literal notranslate"><span class="pre">repr()</span></code> is primarily affected by whether the members are global, while <code class="docutils literal notranslate"><span class="pre">str()</span></code> is affected by being global or by being a drop-in replacement, with the drop-in replacement status having a higher priority. Also, the basic <code class="docutils literal notranslate"><span class="pre">repr()</span></code> and <code class="docutils literal notranslate"><span class="pre">str()</span></code> have changed for flags as the old style was flawed.</p> </section> <section id="backwards-compatibility"> <h2><a class="toc-backref" href="#backwards-compatibility" role="doc-backlink">Backwards Compatibility</a></h2> <p>Backwards compatibility of stringified objects is not guaranteed across major Python versions, and there will be backwards compatibility breaks where software uses the <code class="docutils literal notranslate"><span class="pre">repr()</span></code>, <code class="docutils literal notranslate"><span class="pre">str()</span></code>, and <code class="docutils literal notranslate"><span class="pre">format()</span></code> output of enums in tests, documentation, data structures, and/or code generation.</p> <p>Normal usage of enum members will not change: <code class="docutils literal notranslate"><span class="pre">re.ASCII</span></code> can still be used as <code class="docutils literal notranslate"><span class="pre">re.ASCII</span></code> and will still compare equal to <code class="docutils literal notranslate"><span class="pre">256</span></code>.</p> <p>If the previous output needs to be maintained, for example to ensure compatibility between different Python versions, software projects will need to create their own enum base class with the appropriate methods overridden.</p> <p>Note that by changing the <code class="docutils literal notranslate"><span class="pre">str()</span></code> of the drop-in category, we will actually prevent future breakage when <code class="docutils literal notranslate"><span class="pre">IntEnum</span></code>, et al, are used to replace existing constants.</p> </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> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0663.rst">https://github.com/python/peps/blob/main/peps/pep-0663.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0663.rst">2025-02-01 08:59:27 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="#copyright">Copyright</a></li> </ul> <br> <a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0663.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>