CINXE.COM
PEP 3126 – Remove Implicit String Concatenation | 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 3126 – Remove Implicit String Concatenation | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-3126/"> <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 3126 – Remove Implicit String Concatenation | peps.python.org'> <meta property="og:description" content="Python inherited many of its parsing rules from C. While this has been generally useful, there are some individual rules which are less useful for python, and should be eliminated."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-3126/"> <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="Python inherited many of its parsing rules from C. While this has been generally useful, there are some individual rules which are less useful for python, and should be eliminated."> <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 3126</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 3126 – Remove Implicit String Concatenation</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Jim J. Jewett <JimJJewett at gmail.com>, Raymond Hettinger <python at rcn.com></dd> <dt class="field-even">Status<span class="colon">:</span></dt> <dd class="field-even"><abbr title="Formally declined and will not be accepted">Rejected</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">29-Apr-2007</dd> <dt class="field-odd">Post-History<span class="colon">:</span></dt> <dd class="field-odd">29-Apr-2007, 30-Apr-2007, 07-May-2007</dd> </dl> <hr class="docutils" /> <section id="contents"> <details><summary>Table of Contents</summary><ul class="simple"> <li><a class="reference internal" href="#rejection-notice">Rejection Notice</a></li> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#motivation">Motivation</a><ul> <li><a class="reference internal" href="#history-or-future">History or Future</a></li> <li><a class="reference internal" href="#problem">Problem</a></li> </ul> </li> <li><a class="reference internal" href="#solution">Solution</a></li> <li><a class="reference internal" href="#concerns">Concerns</a><ul> <li><a class="reference internal" href="#operator-precedence">Operator Precedence</a></li> <li><a class="reference internal" href="#long-commands">Long Commands</a></li> <li><a class="reference internal" href="#regular-expressions">Regular Expressions</a></li> <li><a class="reference internal" href="#internationalization">Internationalization</a></li> </ul> </li> <li><a class="reference internal" href="#transition">Transition</a></li> <li><a class="reference internal" href="#open-issues">Open Issues</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="rejection-notice"> <h2><a class="toc-backref" href="#rejection-notice" role="doc-backlink">Rejection Notice</a></h2> <p>This PEP is rejected. There wasn’t enough support in favor, the feature to be removed isn’t all that harmful, and there are some use cases that would become harder.</p> </section> <section id="abstract"> <h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2> <p>Python inherited many of its parsing rules from C. While this has been generally useful, there are some individual rules which are less useful for python, and should be eliminated.</p> <p>This PEP proposes to eliminate implicit string concatenation based only on the adjacency of literals.</p> <p>Instead of:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s2">"abc"</span> <span class="s2">"def"</span> <span class="o">==</span> <span class="s2">"abcdef"</span> </pre></div> </div> <p>authors will need to be explicit, and either add the strings:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s2">"abc"</span> <span class="o">+</span> <span class="s2">"def"</span> <span class="o">==</span> <span class="s2">"abcdef"</span> </pre></div> </div> <p>or join them:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s2">"abc"</span><span class="p">,</span> <span class="s2">"def"</span><span class="p">])</span> <span class="o">==</span> <span class="s2">"abcdef"</span> </pre></div> </div> </section> <section id="motivation"> <h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2> <p>One goal for Python 3000 should be to simplify the language by removing unnecessary features. Implicit string concatenation should be dropped in favor of existing techniques. This will simplify the grammar and simplify a user’s mental picture of Python. The latter is important for letting the language “fit in your head”. A large group of current users do not even know about implicit concatenation. Of those who do know about it, a large portion never use it or habitually avoid it. Of those who both know about it and use it, very few could state with confidence the implicit operator precedence and under what circumstances it is computed when the definition is compiled versus when it is run.</p> <section id="history-or-future"> <h3><a class="toc-backref" href="#history-or-future" role="doc-backlink">History or Future</a></h3> <p>Many Python parsing rules are intentionally compatible with C. This is a useful default, but Special Cases need to be justified based on their utility in Python. We should no longer assume that python programmers will also be familiar with C, so compatibility between languages should be treated as a tie-breaker, rather than a justification.</p> <p>In C, implicit concatenation is the only way to join strings without using a (run-time) function call to store into a variable. In Python, the strings can be joined (and still recognized as immutable) using more standard Python idioms, such <code class="docutils literal notranslate"><span class="pre">+</span></code> or <code class="docutils literal notranslate"><span class="pre">"".join</span></code>.</p> </section> <section id="problem"> <h3><a class="toc-backref" href="#problem" role="doc-backlink">Problem</a></h3> <p>Implicit String concatenation leads to tuples and lists which are shorter than they appear; this is turn can lead to confusing, or even silent, errors. For example, given a function which accepts several parameters, but offers a default value for some of them:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">fmt</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span> <span class="nb">print</span> <span class="n">fmt</span> <span class="o">%</span> <span class="n">args</span> </pre></div> </div> <p>This looks like a valid call, but isn’t:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">f</span><span class="p">(</span><span class="s2">"User </span><span class="si">%s</span><span class="s2"> got a message </span><span class="si">%s</span><span class="s2">"</span><span class="p">,</span> <span class="go"> "Bob"</span> <span class="go"> "Time for dinner")</span> <span class="gt">Traceback (most recent call last):</span> File <span class="nb">"<pyshell#8>"</span>, line <span class="m">2</span>, in <span class="n"><module></span> <span class="w"> </span><span class="s2">"Bob"</span> File <span class="nb">"<pyshell#3>"</span>, line <span class="m">2</span>, in <span class="n">f</span> <span class="w"> </span><span class="nb">print</span> <span class="n">fmt</span> <span class="o">%</span> <span class="n">args</span> <span class="gr">TypeError</span>: <span class="n">not enough arguments for format string</span> </pre></div> </div> <p>Calls to this function can silently do the wrong thing:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">g</span><span class="p">(</span><span class="n">arg1</span><span class="p">,</span> <span class="n">arg2</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> <span class="o">...</span> <span class="c1"># silently transformed into the possibly very different</span> <span class="c1"># g("arg1 on this linearg2 on this line", None)</span> <span class="n">g</span><span class="p">(</span><span class="s2">"arg1 on this line"</span> <span class="s2">"arg2 on this line"</span><span class="p">)</span> </pre></div> </div> <p>To quote Jason Orendorff [#Orendorff]</p> <blockquote> <div>Oh. I just realized this happens a lot out here. Where I work, we use scons, and each SConscript has a long list of filenames:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sourceFiles</span> <span class="o">=</span> <span class="p">[</span> <span class="s1">'foo.c'</span> <span class="s1">'bar.c'</span><span class="p">,</span> <span class="c1">#...many lines omitted...</span> <span class="s1">'q1000x.c'</span><span class="p">]</span> </pre></div> </div> <p>It’s a common mistake to leave off a comma, and then scons complains that it can’t find ‘foo.cbar.c’. This is pretty bewildering behavior even if you <em>are</em> a Python programmer, and not everyone here is.</p> </div></blockquote> </section> </section> <section id="solution"> <h2><a class="toc-backref" href="#solution" role="doc-backlink">Solution</a></h2> <p>In Python, strings are objects and they support the __add__ operator, so it is possible to write:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s2">"abc"</span> <span class="o">+</span> <span class="s2">"def"</span> </pre></div> </div> <p>Because these are literals, this addition can still be optimized away by the compiler; the CPython compiler already does so. <a class="footnote-reference brackets" href="#rcn-constantfold" id="id1">[2]</a></p> <p>Other existing alternatives include multiline (triple-quoted) strings, and the join method:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="sd">"""This string</span> <span class="sd"> extends across</span> <span class="sd"> multiple lines, but you may want to use something like</span> <span class="sd"> Textwrap.dedent</span> <span class="sd"> to clear out the leading spaces</span> <span class="sd"> and/or reformat.</span> <span class="sd">"""</span> <span class="o">>>></span> <span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s2">"empty"</span><span class="p">,</span> <span class="s2">"string"</span><span class="p">,</span> <span class="s2">"joiner"</span><span class="p">])</span> <span class="o">==</span> <span class="s2">"emptystringjoiner"</span> <span class="kc">True</span> <span class="o">>>></span> <span class="s2">" "</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s2">"space"</span><span class="p">,</span> <span class="s2">"string"</span><span class="p">,</span> <span class="s2">"joiner"</span><span class="p">])</span> <span class="o">==</span> <span class="s2">"space string joiner"</span> <span class="kc">True</span> <span class="o">>>></span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s2">"multiple"</span><span class="p">,</span> <span class="s2">"lines"</span><span class="p">])</span> <span class="o">==</span> <span class="s2">"multiple</span><span class="se">\n</span><span class="s2">lines"</span> <span class="o">==</span> <span class="p">(</span> <span class="sd">"""multiple</span> <span class="sd">lines"""</span><span class="p">)</span> <span class="kc">True</span> </pre></div> </div> </section> <section id="concerns"> <h2><a class="toc-backref" href="#concerns" role="doc-backlink">Concerns</a></h2> <section id="operator-precedence"> <h3><a class="toc-backref" href="#operator-precedence" role="doc-backlink">Operator Precedence</a></h3> <p>Guido indicated <a class="footnote-reference brackets" href="#rcn-constantfold" id="id2">[2]</a> that this change should be handled by PEP, because there were a few edge cases with other string operators, such as the %. (Assuming that str % stays – it may be eliminated in favor of <a class="pep reference internal" href="../pep-3101/" title="PEP 3101 – Advanced String Formatting">PEP 3101</a> – Advanced String Formatting. <a class="footnote-reference brackets" href="#elimpercent" id="id3">[3]</a>)</p> <p>The resolution is to use parentheses to enforce precedence – the same solution that can be used today:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Clearest, works today, continues to work, optimization is</span> <span class="c1"># already possible.</span> <span class="p">(</span><span class="s2">"abc </span><span class="si">%s</span><span class="s2"> def"</span> <span class="o">+</span> <span class="s2">"ghi"</span><span class="p">)</span> <span class="o">%</span> <span class="n">var</span> <span class="c1"># Already works today; precedence makes the optimization more</span> <span class="c1"># difficult to recognize, but does not change the semantics.</span> <span class="s2">"abc"</span> <span class="o">+</span> <span class="s2">"def </span><span class="si">%s</span><span class="s2"> ghi"</span> <span class="o">%</span> <span class="n">var</span> </pre></div> </div> <p>as opposed to:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Already fails because modulus (%) is higher precedence than</span> <span class="c1"># addition (+)</span> <span class="p">(</span><span class="s2">"abc </span><span class="si">%s</span><span class="s2"> def"</span> <span class="o">+</span> <span class="s2">"ghi"</span> <span class="o">%</span> <span class="n">var</span><span class="p">)</span> <span class="c1"># Works today only because adjacency is higher precedence than</span> <span class="c1"># modulus. This will no longer be available.</span> <span class="s2">"abc </span><span class="si">%s</span><span class="s2">"</span> <span class="s2">"def"</span> <span class="o">%</span> <span class="n">var</span> <span class="c1"># So the 2-to-3 translator can automatically replace it with the</span> <span class="c1"># (already valid):</span> <span class="p">(</span><span class="s2">"abc </span><span class="si">%s</span><span class="s2">"</span> <span class="o">+</span> <span class="s2">"def"</span><span class="p">)</span> <span class="o">%</span> <span class="n">var</span> </pre></div> </div> </section> <section id="long-commands"> <h3><a class="toc-backref" href="#long-commands" role="doc-backlink">Long Commands</a></h3> <blockquote> <div>… build up (what I consider to be) readable SQL queries <a class="footnote-reference brackets" href="#skipsql" id="id4">[4]</a>:<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rows</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">executesql</span><span class="p">(</span><span class="s2">"select cities.city, state, country"</span> <span class="s2">" from cities, venues, events, addresses"</span> <span class="s2">" where cities.city like </span><span class="si">%s</span><span class="s2">"</span> <span class="s2">" and events.active = 1"</span> <span class="s2">" and venues.address = addresses.id"</span> <span class="s2">" and addresses.city = cities.id"</span> <span class="s2">" and events.venue = venues.id"</span><span class="p">,</span> <span class="p">(</span><span class="n">city</span><span class="p">,))</span> </pre></div> </div> </div></blockquote> <p>Alternatives again include triple-quoted strings, <code class="docutils literal notranslate"><span class="pre">+</span></code>, and <code class="docutils literal notranslate"><span class="pre">.join</span></code>:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">query</span><span class="o">=</span><span class="s2">"""select cities.city, state, country</span> <span class="s2"> from cities, venues, events, addresses</span> <span class="s2"> where cities.city like </span><span class="si">%s</span> <span class="s2"> and events.active = 1"</span> <span class="s2"> and venues.address = addresses.id</span> <span class="s2"> and addresses.city = cities.id</span> <span class="s2"> and events.venue = venues.id"""</span> <span class="n">query</span><span class="o">=</span><span class="p">(</span> <span class="s2">"select cities.city, state, country"</span> <span class="o">+</span> <span class="s2">" from cities, venues, events, addresses"</span> <span class="o">+</span> <span class="s2">" where cities.city like </span><span class="si">%s</span><span class="s2">"</span> <span class="o">+</span> <span class="s2">" and events.active = 1"</span> <span class="o">+</span> <span class="s2">" and venues.address = addresses.id"</span> <span class="o">+</span> <span class="s2">" and addresses.city = cities.id"</span> <span class="o">+</span> <span class="s2">" and events.venue = venues.id"</span> <span class="p">)</span> <span class="n">query</span><span class="o">=</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s2">"select cities.city, state, country"</span><span class="p">,</span> <span class="s2">" from cities, venues, events, addresses"</span><span class="p">,</span> <span class="s2">" where cities.city like </span><span class="si">%s</span><span class="s2">"</span><span class="p">,</span> <span class="s2">" and events.active = 1"</span><span class="p">,</span> <span class="s2">" and venues.address = addresses.id"</span><span class="p">,</span> <span class="s2">" and addresses.city = cities.id"</span><span class="p">,</span> <span class="s2">" and events.venue = venues.id"</span><span class="p">])</span> <span class="c1"># And yes, you *could* inline any of the above querystrings</span> <span class="c1"># the same way the original was inlined.</span> <span class="n">rows</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">executesql</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="p">(</span><span class="n">city</span><span class="p">,))</span> </pre></div> </div> </section> <section id="regular-expressions"> <h3><a class="toc-backref" href="#regular-expressions" role="doc-backlink">Regular Expressions</a></h3> <p>Complex regular expressions are sometimes stated in terms of several implicitly concatenated strings with each regex component on a different line and followed by a comment. The plus operator can be inserted here but it does make the regex harder to read. One alternative is to use the re.VERBOSE option. Another alternative is to build-up the regex with a series of += lines:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Existing idiom which relies on implicit concatenation</span> <span class="n">r</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'a</span><span class="si">{20}</span><span class="s1">'</span> <span class="c1"># Twenty A's</span> <span class="s1">'b</span><span class="si">{5}</span><span class="s1">'</span> <span class="c1"># Followed by Five B's</span> <span class="p">)</span> <span class="c1"># Mechanical replacement</span> <span class="n">r</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'a</span><span class="si">{20}</span><span class="s1">'</span> <span class="o">+</span><span class="c1"># Twenty A's</span> <span class="s1">'b</span><span class="si">{5}</span><span class="s1">'</span> <span class="c1"># Followed by Five B's</span> <span class="p">)</span> <span class="c1"># already works today</span> <span class="n">r</span> <span class="o">=</span> <span class="s1">'''a</span><span class="si">{20}</span><span class="s1"> # Twenty A's</span> <span class="s1"> b</span><span class="si">{5}</span><span class="s1"> # Followed by Five B's</span> <span class="s1"> '''</span> <span class="c1"># Compiled with the re.VERBOSE flag</span> <span class="c1"># already works today</span> <span class="n">r</span> <span class="o">=</span> <span class="s1">'a</span><span class="si">{20}</span><span class="s1">'</span> <span class="c1"># Twenty A's</span> <span class="n">r</span> <span class="o">+=</span> <span class="s1">'b</span><span class="si">{5}</span><span class="s1">'</span> <span class="c1"># Followed by Five B's</span> </pre></div> </div> </section> <section id="internationalization"> <h3><a class="toc-backref" href="#internationalization" role="doc-backlink">Internationalization</a></h3> <p>Some internationalization tools – notably xgettext – have already been special-cased for implicit concatenation, but not for Python’s explicit concatenation. <a class="footnote-reference brackets" href="#barryi8" id="id5">[5]</a></p> <p>These tools will fail to extract the (already legal):</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">_</span><span class="p">(</span><span class="s2">"some string"</span> <span class="o">+</span> <span class="s2">" and more of it"</span><span class="p">)</span> </pre></div> </div> <p>but often have a special case for:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">_</span><span class="p">(</span><span class="s2">"some string"</span> <span class="s2">" and more of it"</span><span class="p">)</span> </pre></div> </div> <p>It should also be possible to just use an overly long line (xgettext limits messages to 2048 characters <a class="footnote-reference brackets" href="#xgettext2048" id="id6">[7]</a>, which is less than Python’s enforced limit) or triple-quoted strings, but these solutions sacrifice some readability in the code:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Lines over a certain length are unpleasant.</span> <span class="n">_</span><span class="p">(</span><span class="s2">"some string and more of it"</span><span class="p">)</span> <span class="c1"># Changing whitespace is not ideal.</span> <span class="n">_</span><span class="p">(</span><span class="s2">"""Some string</span> <span class="s2"> and more of it"""</span><span class="p">)</span> <span class="n">_</span><span class="p">(</span><span class="s2">"""Some string</span> <span class="s2">and more of it"""</span><span class="p">)</span> <span class="n">_</span><span class="p">(</span><span class="s2">"Some string </span><span class="se">\</span> <span class="s2">and more of it"</span><span class="p">)</span> </pre></div> </div> <p>I do not see a good short-term resolution for this.</p> </section> </section> <section id="transition"> <h2><a class="toc-backref" href="#transition" role="doc-backlink">Transition</a></h2> <p>The proposed new constructs are already legal in current Python, and can be used immediately.</p> <p>The 2 to 3 translator can be made to mechanically change:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s2">"str1"</span> <span class="s2">"str2"</span> <span class="p">(</span><span class="s2">"line1"</span> <span class="c1">#comment</span> <span class="s2">"line2"</span><span class="p">)</span> </pre></div> </div> <p>into:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="s2">"str1"</span> <span class="o">+</span> <span class="s2">"str2"</span><span class="p">)</span> <span class="p">(</span><span class="s2">"line1"</span> <span class="o">+</span><span class="c1">#comments</span> <span class="s2">"line2"</span><span class="p">)</span> </pre></div> </div> <p>If users want to use one of the other idioms, they can; as these idioms are all already legal in python 2, the edits can be made to the original source, rather than patching up the translator.</p> </section> <section id="open-issues"> <h2><a class="toc-backref" href="#open-issues" role="doc-backlink">Open Issues</a></h2> <p>Is there a better way to support external text extraction tools, or at least <code class="docutils literal notranslate"><span class="pre">xgettext</span></code> <a class="footnote-reference brackets" href="#gettext" id="id7">[6]</a> in particular?</p> </section> <section id="references"> <h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2> <aside class="footnote-list brackets"> <aside class="footnote brackets" id="orendorff" role="doc-footnote"> <dt class="label" id="orendorff">[1]</dt> <dd>Implicit String Concatenation, Orendorff <a class="reference external" href="https://mail.python.org/pipermail/python-ideas/2007-April/000397.html">https://mail.python.org/pipermail/python-ideas/2007-April/000397.html</a></aside> <aside class="footnote brackets" id="rcn-constantfold" role="doc-footnote"> <dt class="label" id="rcn-constantfold">[2]<em> (<a href='#id1'>1</a>, <a href='#id2'>2</a>) </em></dt> <dd>Reminder: Py3k PEPs due by April, Hettinger, van Rossum <a class="reference external" href="https://mail.python.org/pipermail/python-3000/2007-April/006563.html">https://mail.python.org/pipermail/python-3000/2007-April/006563.html</a></aside> <aside class="footnote brackets" id="elimpercent" role="doc-footnote"> <dt class="label" id="elimpercent">[<a href="#id3">3</a>]</dt> <dd>ps to question Re: Need help completing ABC pep, van Rossum <a class="reference external" href="https://mail.python.org/pipermail/python-3000/2007-April/006737.html">https://mail.python.org/pipermail/python-3000/2007-April/006737.html</a></aside> <aside class="footnote brackets" id="skipsql" role="doc-footnote"> <dt class="label" id="skipsql">[<a href="#id4">4</a>]</dt> <dd>(email Subject) PEP 30XZ: Simplified Parsing, Skip, <a class="reference external" href="https://mail.python.org/pipermail/python-3000/2007-May/007261.html">https://mail.python.org/pipermail/python-3000/2007-May/007261.html</a></aside> <aside class="footnote brackets" id="barryi8" role="doc-footnote"> <dt class="label" id="barryi8">[<a href="#id5">5</a>]</dt> <dd>(email Subject) PEP 30XZ: Simplified Parsing <a class="reference external" href="https://mail.python.org/pipermail/python-3000/2007-May/007305.html">https://mail.python.org/pipermail/python-3000/2007-May/007305.html</a></aside> <aside class="footnote brackets" id="gettext" role="doc-footnote"> <dt class="label" id="gettext">[<a href="#id7">6</a>]</dt> <dd>GNU gettext manual <a class="reference external" href="http://www.gnu.org/software/gettext/">http://www.gnu.org/software/gettext/</a></aside> <aside class="footnote brackets" id="xgettext2048" role="doc-footnote"> <dt class="label" id="xgettext2048">[<a href="#id6">7</a>]</dt> <dd>Unix man page for xgettext – Notes section <a class="reference external" href="http://www.scit.wlv.ac.uk/cgi-bin/mansec?1+xgettext">http://www.scit.wlv.ac.uk/cgi-bin/mansec?1+xgettext</a></aside> </aside> </section> <section id="copyright"> <h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2> <blockquote> <div>This document has been placed in the public domain.</div></blockquote> </section> </section> <hr class="docutils" /> <p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-3126.rst">https://github.com/python/peps/blob/main/peps/pep-3126.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-3126.rst">2024-09-20 05:59:07 GMT</a></p> </article> <nav id="pep-sidebar"> <h2>Contents</h2> <ul> <li><a class="reference internal" href="#rejection-notice">Rejection Notice</a></li> <li><a class="reference internal" href="#abstract">Abstract</a></li> <li><a class="reference internal" href="#motivation">Motivation</a><ul> <li><a class="reference internal" href="#history-or-future">History or Future</a></li> <li><a class="reference internal" href="#problem">Problem</a></li> </ul> </li> <li><a class="reference internal" href="#solution">Solution</a></li> <li><a class="reference internal" href="#concerns">Concerns</a><ul> <li><a class="reference internal" href="#operator-precedence">Operator Precedence</a></li> <li><a class="reference internal" href="#long-commands">Long Commands</a></li> <li><a class="reference internal" href="#regular-expressions">Regular Expressions</a></li> <li><a class="reference internal" href="#internationalization">Internationalization</a></li> </ul> </li> <li><a class="reference internal" href="#transition">Transition</a></li> <li><a class="reference internal" href="#open-issues">Open Issues</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-3126.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>