CINXE.COM
PEP 3105 – Make print a function | 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 3105 – Make print a function | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-3105/"> <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 3105 – Make print a function | peps.python.org'> <meta property="og:description" content="The title says it all – this PEP proposes a new print() builtin that replaces the print statement and suggests a specific signature for the new function."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-3105/"> <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="The title says it all – this PEP proposes a new print() builtin that replaces the print statement and suggests a specific signature for the new function."> <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 3105</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 3105 – Make print a function</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Georg Brandl <georg 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">19-Nov-2006</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">3.0</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even"><p></p></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="#specification">Specification</a></li> <li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li> <li><a class="reference internal" href="#implementation">Implementation</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>The title says it all – this PEP proposes a new <code class="docutils literal notranslate"><span class="pre">print()</span></code> builtin that replaces the <code class="docutils literal notranslate"><span class="pre">print</span></code> statement and suggests a specific signature for the new function.</p> </section> <section id="rationale"> <h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2> <p>The <code class="docutils literal notranslate"><span class="pre">print</span></code> statement has long appeared on lists of dubious language features that are to be removed in Python 3000, such as Guido’s “Python Regrets” presentation <a class="footnote-reference brackets" href="#id4" id="id1">[1]</a>. As such, the objective of this PEP is not new, though it might become much disputed among Python developers.</p> <p>The following arguments for a <code class="docutils literal notranslate"><span class="pre">print()</span></code> function are distilled from a python-3000 message by Guido himself <a class="footnote-reference brackets" href="#id5" id="id2">[2]</a>:</p> <ul class="simple"> <li><code class="docutils literal notranslate"><span class="pre">print</span></code> is the only application-level functionality that has a statement dedicated to it. Within Python’s world, syntax is generally used as a last resort, when something <em>can’t</em> be done without help from the compiler. Print doesn’t qualify for such an exception.</li> <li>At some point in application development one quite often feels the need to replace <code class="docutils literal notranslate"><span class="pre">print</span></code> output by something more sophisticated, like logging calls or calls into some other I/O library. With a <code class="docutils literal notranslate"><span class="pre">print()</span></code> function, this is a straightforward string replacement, today it is a mess adding all those parentheses and possibly converting <code class="docutils literal notranslate"><span class="pre">>>stream</span></code> style syntax.</li> <li>Having special syntax for <code class="docutils literal notranslate"><span class="pre">print</span></code> puts up a much larger barrier for evolution, e.g. a hypothetical new <code class="docutils literal notranslate"><span class="pre">printf()</span></code> function is not too far fetched when it will coexist with a <code class="docutils literal notranslate"><span class="pre">print()</span></code> function.</li> <li>There’s no easy way to convert <code class="docutils literal notranslate"><span class="pre">print</span></code> statements into another call if one needs a different separator, not spaces, or none at all. Also, there’s no easy way <em>at all</em> to conveniently print objects with some other separator than a space.</li> <li>If <code class="docutils literal notranslate"><span class="pre">print()</span></code> is a function, it would be much easier to replace it within one module (just <code class="docutils literal notranslate"><span class="pre">def</span> <span class="pre">print(*args):...</span></code>) or even throughout a program (e.g. by putting a different function in <code class="docutils literal notranslate"><span class="pre">__builtin__.print</span></code>). As it is, one can do this by writing a class with a <code class="docutils literal notranslate"><span class="pre">write()</span></code> method and assigning that to <code class="docutils literal notranslate"><span class="pre">sys.stdout</span></code> – that’s not bad, but definitely a much larger conceptual leap, and it works at a different level than print.</li> </ul> </section> <section id="specification"> <h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2> <p>The signature for <code class="docutils literal notranslate"><span class="pre">print()</span></code>, taken from various mailings and recently posted on the python-3000 list <a class="footnote-reference brackets" href="#id6" id="id3">[3]</a> is:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">print</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">sep</span><span class="o">=</span><span class="s1">' '</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span> </pre></div> </div> <p>A call like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span> </pre></div> </div> <p>will be equivalent to today’s:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="o">>></span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> </pre></div> </div> <p>while the optional <code class="docutils literal notranslate"><span class="pre">sep</span></code> and <code class="docutils literal notranslate"><span class="pre">end</span></code> arguments specify what is printed between and after the arguments, respectively.</p> <p>The <code class="docutils literal notranslate"><span class="pre">softspace</span></code> feature (a semi-secret attribute on files currently used to tell print whether to insert a space before the first item) will be removed. Therefore, there will not be a direct translation for today’s:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="s2">"a"</span><span class="p">,</span> <span class="nb">print</span> </pre></div> </div> <p>which will not print a space between the <code class="docutils literal notranslate"><span class="pre">"a"</span></code> and the newline.</p> </section> <section id="backwards-compatibility"> <h2><a class="toc-backref" href="#backwards-compatibility" role="doc-backlink">Backwards Compatibility</a></h2> <p>The changes proposed in this PEP will render most of today’s <code class="docutils literal notranslate"><span class="pre">print</span></code> statements invalid. Only those which incidentally feature parentheses around all of their arguments will continue to be valid Python syntax in version 3.0, and of those, only the ones printing a single parenthesized value will continue to do the same thing. For example, in 2.x:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">print</span> <span class="p">(</span><span class="s2">"Hello"</span><span class="p">)</span> <span class="go">Hello</span> <span class="gp">>>> </span><span class="nb">print</span> <span class="p">(</span><span class="s2">"Hello"</span><span class="p">,</span> <span class="s2">"world"</span><span class="p">)</span> <span class="go">('Hello', 'world')</span> </pre></div> </div> <p>whereas in 3.0:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">print</span> <span class="p">(</span><span class="s2">"Hello"</span><span class="p">)</span> <span class="go">Hello</span> <span class="gp">>>> </span><span class="nb">print</span> <span class="p">(</span><span class="s2">"Hello"</span><span class="p">,</span> <span class="s2">"world"</span><span class="p">)</span> <span class="go">Hello world</span> </pre></div> </div> <p>Luckily, as it is a statement in Python 2, <code class="docutils literal notranslate"><span class="pre">print</span></code> can be detected and replaced reliably and non-ambiguously by an automated tool, so there should be no major porting problems (provided someone writes the mentioned tool).</p> </section> <section id="implementation"> <h2><a class="toc-backref" href="#implementation" role="doc-backlink">Implementation</a></h2> <p>The proposed changes were implemented in the Python 3000 branch in the Subversion revisions 53685 to 53704. Most of the legacy code in the library has been converted too, but it is an ongoing effort to catch every print statement that may be left in the distribution.</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="id4" role="doc-footnote"> <dt class="label" id="id4">[<a href="#id1">1</a>]</dt> <dd><a class="reference external" href="http://legacy.python.org/doc/essays/ppt/regrets/PythonRegrets.pdf">http://legacy.python.org/doc/essays/ppt/regrets/PythonRegrets.pdf</a></aside> <aside class="footnote brackets" id="id5" role="doc-footnote"> <dt class="label" id="id5">[<a href="#id2">2</a>]</dt> <dd>Replacement for print in Python 3.0 (Guido van Rossum) <a class="reference external" href="https://mail.python.org/pipermail/python-dev/2005-September/056154.html">https://mail.python.org/pipermail/python-dev/2005-September/056154.html</a></aside> <aside class="footnote brackets" id="id6" role="doc-footnote"> <dt class="label" id="id6">[<a href="#id3">3</a>]</dt> <dd>print() parameters in py3k (Guido van Rossum) <a class="reference external" href="https://mail.python.org/pipermail/python-3000/2006-November/004485.html">https://mail.python.org/pipermail/python-3000/2006-November/004485.html</a></aside> </aside> </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-3105.rst">https://github.com/python/peps/blob/main/peps/pep-3105.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-3105.rst">2023-09-09 17:39:29 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="#specification">Specification</a></li> <li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li> <li><a class="reference internal" href="#implementation">Implementation</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-3105.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>