CINXE.COM

PEP 299 – Special __main__() function in modules | 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 299 – Special __main__() function in modules | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0299/"> <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 299 – Special __main__() function in modules | peps.python.org'> <meta property="og:description" content="Many Python modules are also intended to be callable as standalone scripts. This PEP proposes that a special function called __main__() should serve this purpose."> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0299/"> <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="Many Python modules are also intended to be callable as standalone scripts. This PEP proposes that a special function called __main__() should serve this purpose."> <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> &raquo; </li> <li><a href="../pep-0000/">PEP Index</a> &raquo; </li> <li>PEP 299</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 299 – Special __main__() function in modules</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Jeff Epler &lt;jepler&#32;&#97;t&#32;unpythonic.net&gt;</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">12-Aug-2002</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">2.3</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even">29-Mar-2006</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="#proposal">Proposal</a></li> <li><a class="reference internal" href="#implementation">Implementation</a></li> <li><a class="reference internal" href="#open-issues">Open Issues</a></li> <li><a class="reference internal" href="#rejection">Rejection</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>Many Python modules are also intended to be callable as standalone scripts. This PEP proposes that a special function called <code class="docutils literal notranslate"><span class="pre">__main__()</span></code> should serve this purpose.</p> </section> <section id="motivation"> <h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2> <p>There should be one simple and universal idiom for invoking a module as a standalone script.</p> <p>The semi-standard idiom:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span> <span class="n">perform</span> <span class="s2">&quot;standalone&quot;</span> <span class="n">functionality</span> </pre></div> </div> <p>is unclear to programmers of languages like C and C++. It also does not permit invocation of the standalone function when the module is imported. The variant:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span> <span class="n">main_function</span><span class="p">()</span> </pre></div> </div> <p>is sometimes seen, but there exists no standard name for the function, and because arguments are taken from sys.argv it is not possible to pass specific arguments without changing the argument list seen by all other modules. (Imagine a threaded Python program, with two threads wishing to invoke the standalone functionality of different modules with different argument lists)</p> </section> <section id="proposal"> <h2><a class="toc-backref" href="#proposal" role="doc-backlink">Proposal</a></h2> <p>The standard name of the ‘main function’ should be <code class="docutils literal notranslate"><span class="pre">__main__</span></code>. When a module is invoked on the command line, such as:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">python</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">py</span> </pre></div> </div> <p>then the module behaves as though the following lines existed at the end of the module (except that the attribute __sys may not be used or assumed to exist elsewhere in the script):</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="s2">&quot;__main__&quot;</span><span class="p">):</span> <span class="kn">import</span><span class="w"> </span><span class="nn">sys</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">__sys</span> <span class="n">__sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">__main__</span><span class="p">(</span><span class="n">__sys</span><span class="o">.</span><span class="n">argv</span><span class="p">))</span> </pre></div> </div> <p>Other modules may execute:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span><span class="w"> </span><span class="nn">mymodule</span> <span class="n">mymodule</span><span class="o">.</span><span class="n">__main__</span><span class="p">([</span><span class="s1">&#39;mymodule&#39;</span><span class="p">,</span> <span class="o">...</span><span class="p">])</span> </pre></div> </div> <p>It is up to <code class="docutils literal notranslate"><span class="pre">mymodule</span></code> to document thread-safety issues or other issues which might restrict use of <code class="docutils literal notranslate"><span class="pre">__main__</span></code>. (Other issues might include use of mutually exclusive GUI modules, non-sharable resources like hardware devices, reassignment of <code class="docutils literal notranslate"><span class="pre">sys.stdin</span></code>/<code class="docutils literal notranslate"><span class="pre">stdout</span></code>, etc)</p> </section> <section id="implementation"> <h2><a class="toc-backref" href="#implementation" role="doc-backlink">Implementation</a></h2> <p>In <code class="docutils literal notranslate"><span class="pre">modules/main.c</span></code>, the block near line 385 (after the <code class="docutils literal notranslate"><span class="pre">PyRun_AnyFileExFlags</span></code> call) will be changed so that the above code (or its C equivalent) is executed.</p> </section> <section id="open-issues"> <h2><a class="toc-backref" href="#open-issues" role="doc-backlink">Open Issues</a></h2> <ul> <li>Should the return value from <code class="docutils literal notranslate"><span class="pre">__main__</span></code> be treated as the exit value?<p>Yes. Many <code class="docutils literal notranslate"><span class="pre">__main__</span></code> will naturally return <code class="docutils literal notranslate"><span class="pre">None</span></code>, which <code class="docutils literal notranslate"><span class="pre">sys.exit</span></code> translates into a “success” return code. In those that return a numeric result, it behaves just like the argument to <code class="docutils literal notranslate"><span class="pre">sys.exit()</span></code> or the return value from C’s main().</p> </li> <li>Should the argument list to <code class="docutils literal notranslate"><span class="pre">__main__</span></code> include <code class="docutils literal notranslate"><span class="pre">argv[0]</span></code>, or just the “real” arguments <code class="docutils literal notranslate"><span class="pre">argv[1:]</span></code>?<p><code class="docutils literal notranslate"><span class="pre">argv[0]</span></code> is included for symmetry with <code class="docutils literal notranslate"><span class="pre">sys.argv</span></code> and easy transition to the new standard idiom.</p> </li> </ul> </section> <section id="rejection"> <h2><a class="toc-backref" href="#rejection" role="doc-backlink">Rejection</a></h2> <p>In a short discussion on python-dev <a class="footnote-reference brackets" href="#id2" id="id1">[1]</a>, two major backwards compatibility problems were brought up and Guido pronounced that he doesn’t like the idea anyway as it’s “not worth the change (in docs, user habits, etc.) and there’s nothing particularly broken.”</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="id2" role="doc-footnote"> <dt class="label" id="id2">[<a href="#id1">1</a>]</dt> <dd>Georg Brandl, “What about PEP 299”, <a class="reference external" href="https://mail.python.org/pipermail/python-dev/2006-March/062951.html">https://mail.python.org/pipermail/python-dev/2006-March/062951.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-0299.rst">https://github.com/python/peps/blob/main/peps/pep-0299.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0299.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="#proposal">Proposal</a></li> <li><a class="reference internal" href="#implementation">Implementation</a></li> <li><a class="reference internal" href="#open-issues">Open Issues</a></li> <li><a class="reference internal" href="#rejection">Rejection</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-0299.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>

Pages: 1 2 3 4 5 6 7 8 9 10