CINXE.COM

PEP 359 – The “make” Statement | 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 359 – The “make” Statement | peps.python.org</title> <link rel="shortcut icon" href="../_static/py.png"> <link rel="canonical" href="https://peps.python.org/pep-0359/"> <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 359 – The “make” Statement | peps.python.org'> <meta property="og:description" content="This PEP proposes a generalization of the class-declaration syntax, the make statement. The proposed syntax and semantics parallel the syntax for class definition, and so:"> <meta property="og:type" content="website"> <meta property="og:url" content="https://peps.python.org/pep-0359/"> <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 a generalization of the class-declaration syntax, the make statement. The proposed syntax and semantics parallel the syntax for class definition, and so:"> <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 359</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 359 – The “make” Statement</h1> <dl class="rfc2822 field-list simple"> <dt class="field-odd">Author<span class="colon">:</span></dt> <dd class="field-odd">Steven Bethard &lt;steven.bethard&#32;&#97;t&#32;gmail.com&gt;</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">05-Apr-2006</dd> <dt class="field-odd">Python-Version<span class="colon">:</span></dt> <dd class="field-odd">2.6</dd> <dt class="field-even">Post-History<span class="colon">:</span></dt> <dd class="field-even">05-Apr-2006, 06-Apr-2006, 13-Apr-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="#withdrawal-notice">Withdrawal Notice</a></li> <li><a class="reference internal" href="#motivation">Motivation</a><ul> <li><a class="reference internal" href="#example-simple-namespaces">Example: simple namespaces</a></li> <li><a class="reference internal" href="#example-gui-objects">Example: GUI objects</a></li> <li><a class="reference internal" href="#example-custom-descriptors">Example: custom descriptors</a></li> <li><a class="reference internal" href="#example-property-namespaces">Example: property namespaces</a></li> <li><a class="reference internal" href="#example-interfaces">Example: interfaces</a></li> </ul> </li> <li><a class="reference internal" href="#specification">Specification</a></li> <li><a class="reference internal" href="#open-issues">Open Issues</a><ul> <li><a class="reference internal" href="#keyword">Keyword</a></li> <li><a class="reference internal" href="#the-make-statement-as-an-alternate-constructor">The make-statement as an alternate constructor</a></li> <li><a class="reference internal" href="#customizing-the-dict-in-which-the-block-is-executed">Customizing the dict in which the block is executed</a></li> </ul> </li> <li><a class="reference internal" href="#optional-extensions">Optional Extensions</a><ul> <li><a class="reference internal" href="#remove-the-make-keyword">Remove the make keyword</a></li> <li><a class="reference internal" href="#removing-metaclass-in-python-3000">Removing __metaclass__ in Python 3000</a></li> <li><a class="reference internal" href="#removing-class-statements-in-python-3000">Removing class statements in Python 3000</a></li> </ul> </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>This PEP proposes a generalization of the class-declaration syntax, the <code class="docutils literal notranslate"><span class="pre">make</span></code> statement. The proposed syntax and semantics parallel the syntax for class definition, and so:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make</span> <span class="o">&lt;</span><span class="nb">callable</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="nb">tuple</span><span class="o">&gt;</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">block</span><span class="o">&gt;</span> </pre></div> </div> <p>is translated into the assignment:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span> <span class="o">=</span> <span class="o">&lt;</span><span class="nb">callable</span><span class="o">&gt;</span><span class="p">(</span><span class="s2">&quot;&lt;name&gt;&quot;</span><span class="p">,</span> <span class="o">&lt;</span><span class="nb">tuple</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">namespace</span><span class="o">&gt;</span><span class="p">)</span> </pre></div> </div> <p>where <code class="docutils literal notranslate"><span class="pre">&lt;namespace&gt;</span></code> is the dict created by executing <code class="docutils literal notranslate"><span class="pre">&lt;block&gt;</span></code>. This is mostly syntactic sugar for:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>class &lt;name&gt; &lt;tuple&gt;: __metaclass__ = &lt;callable&gt; &lt;block&gt; </pre></div> </div> <p>and is intended to help more clearly express the intent of the statement when something other than a class is being created. Of course, other syntax for such a statement is possible, but it is hoped that by keeping a strong parallel to the class statement, an understanding of how classes and metaclasses work will translate into an understanding of how the make-statement works as well.</p> <p>The PEP is based on a suggestion <a class="footnote-reference brackets" href="#id11" id="id1">[1]</a> from Michele Simionato on the python-dev list.</p> </section> <section id="withdrawal-notice"> <h2><a class="toc-backref" href="#withdrawal-notice" role="doc-backlink">Withdrawal Notice</a></h2> <p>This PEP was withdrawn at Guido’s request <a class="footnote-reference brackets" href="#id12" id="id2">[2]</a>. Guido didn’t like it, and in particular didn’t like how the property use-case puts the instance methods of a property at a different level than other instance methods and requires fixed names for the property functions.</p> </section> <section id="motivation"> <h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2> <p>Class statements provide two nice facilities to Python:</p> <ol class="arabic simple"> <li>They execute a block of statements and provide the resulting bindings as a dict to the metaclass.</li> <li>They encourage DRY (don’t repeat yourself) by allowing the class being created to know the name it is being assigned.</li> </ol> <p>Thus in a simple class statement like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">C</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">def</span><span class="w"> </span><span class="nf">foo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="s1">&#39;bar&#39;</span> </pre></div> </div> <p>the metaclass (<code class="docutils literal notranslate"><span class="pre">type</span></code>) gets called with something like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="s1">&#39;C&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nb">object</span><span class="p">,),</span> <span class="p">{</span><span class="s1">&#39;x&#39;</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;foo&#39;</span><span class="p">:</span><span class="o">&lt;</span><span class="n">function</span> <span class="n">foo</span> <span class="n">at</span> <span class="o">...&gt;</span><span class="p">})</span> </pre></div> </div> <p>The class statement is just syntactic sugar for the above assignment statement, but clearly a very useful sort of syntactic sugar. It avoids not only the repetition of <code class="docutils literal notranslate"><span class="pre">C</span></code>, but also simplifies the creation of the dict by allowing it to be expressed as a series of statements.</p> <p>Historically, type instances (a.k.a. class objects) have been the only objects blessed with this sort of syntactic support. The make statement aims to extend this support to other sorts of objects where such syntax would also be useful.</p> <section id="example-simple-namespaces"> <h3><a class="toc-backref" href="#example-simple-namespaces" role="doc-backlink">Example: simple namespaces</a></h3> <p>Let’s say I have some attributes in a module that I access like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mod</span><span class="o">.</span><span class="n">thematic_roletype</span> <span class="n">mod</span><span class="o">.</span><span class="n">opinion_roletype</span> <span class="n">mod</span><span class="o">.</span><span class="n">text_format</span> <span class="n">mod</span><span class="o">.</span><span class="n">html_format</span> </pre></div> </div> <p>and since “Namespaces are one honking great idea”, I’d like to be able to access these attributes instead as:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mod</span><span class="o">.</span><span class="n">roletypes</span><span class="o">.</span><span class="n">thematic</span> <span class="n">mod</span><span class="o">.</span><span class="n">roletypes</span><span class="o">.</span><span class="n">opinion</span> <span class="n">mod</span><span class="o">.</span><span class="n">format</span><span class="o">.</span><span class="n">text</span> <span class="n">mod</span><span class="o">.</span><span class="n">format</span><span class="o">.</span><span class="n">html</span> </pre></div> </div> <p>I currently have two main options:</p> <ol class="arabic simple"> <li>Turn the module into a package, turn <code class="docutils literal notranslate"><span class="pre">roletypes</span></code> and <code class="docutils literal notranslate"><span class="pre">format</span></code> into submodules, and move the attributes to the submodules.</li> <li>Create <code class="docutils literal notranslate"><span class="pre">roletypes</span></code> and <code class="docutils literal notranslate"><span class="pre">format</span></code> classes, and move the attributes to the classes.</li> </ol> <p>The former is a fair chunk of refactoring work, and produces two tiny modules without much content. The latter keeps the attributes local to the module, but creates classes when there is no intention of ever creating instances of those classes.</p> <p>In situations like this, it would be nice to simply be able to declare a “namespace” to hold the few attributes. With the new make statement, I could introduce my new namespaces with something like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make</span> <span class="n">namespace</span> <span class="n">roletypes</span><span class="p">:</span> <span class="n">thematic</span> <span class="o">=</span> <span class="o">...</span> <span class="n">opinion</span> <span class="o">=</span> <span class="o">...</span> <span class="n">make</span> <span class="n">namespace</span> <span class="nb">format</span><span class="p">:</span> <span class="n">text</span> <span class="o">=</span> <span class="o">...</span> <span class="n">html</span> <span class="o">=</span> <span class="o">...</span> </pre></div> </div> <p>and keep my attributes local to the module without making classes that are never intended to be instantiated. One definition of namespace that would make this work is:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">namespace</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span> </pre></div> </div> <p>Given this definition, at the end of the make-statements above, <code class="docutils literal notranslate"><span class="pre">roletypes</span></code> and <code class="docutils literal notranslate"><span class="pre">format</span></code> would be namespace instances.</p> </section> <section id="example-gui-objects"> <h3><a class="toc-backref" href="#example-gui-objects" role="doc-backlink">Example: GUI objects</a></h3> <p>In GUI toolkits, objects like frames and panels are often associated with attributes and functions. With the make-statement, code that looks something like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">root</span> <span class="o">=</span> <span class="n">Tkinter</span><span class="o">.</span><span class="n">Tk</span><span class="p">()</span> <span class="n">frame</span> <span class="o">=</span> <span class="n">Tkinter</span><span class="o">.</span><span class="n">Frame</span><span class="p">(</span><span class="n">root</span><span class="p">)</span> <span class="n">frame</span><span class="o">.</span><span class="n">pack</span><span class="p">()</span> <span class="k">def</span><span class="w"> </span><span class="nf">say_hi</span><span class="p">():</span> <span class="nb">print</span> <span class="s2">&quot;hi there, everyone!&quot;</span> <span class="n">hi_there</span> <span class="o">=</span> <span class="n">Tkinter</span><span class="o">.</span><span class="n">Button</span><span class="p">(</span><span class="n">frame</span><span class="p">,</span> <span class="n">text</span><span class="o">=</span><span class="s2">&quot;Hello&quot;</span><span class="p">,</span> <span class="n">command</span><span class="o">=</span><span class="n">say_hi</span><span class="p">)</span> <span class="n">hi_there</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="n">side</span><span class="o">=</span><span class="n">Tkinter</span><span class="o">.</span><span class="n">LEFT</span><span class="p">)</span> <span class="n">root</span><span class="o">.</span><span class="n">mainloop</span><span class="p">()</span> </pre></div> </div> <p>could be rewritten to group the Button’s function with its declaration:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">root</span> <span class="o">=</span> <span class="n">Tkinter</span><span class="o">.</span><span class="n">Tk</span><span class="p">()</span> <span class="n">frame</span> <span class="o">=</span> <span class="n">Tkinter</span><span class="o">.</span><span class="n">Frame</span><span class="p">(</span><span class="n">root</span><span class="p">)</span> <span class="n">frame</span><span class="o">.</span><span class="n">pack</span><span class="p">()</span> <span class="n">make</span> <span class="n">Tkinter</span><span class="o">.</span><span class="n">Button</span> <span class="n">hi_there</span><span class="p">(</span><span class="n">frame</span><span class="p">):</span> <span class="n">text</span> <span class="o">=</span> <span class="s2">&quot;Hello&quot;</span> <span class="k">def</span><span class="w"> </span><span class="nf">command</span><span class="p">():</span> <span class="nb">print</span> <span class="s2">&quot;hi there, everyone!&quot;</span> <span class="n">hi_there</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="n">side</span><span class="o">=</span><span class="n">Tkinter</span><span class="o">.</span><span class="n">LEFT</span><span class="p">)</span> <span class="n">root</span><span class="o">.</span><span class="n">mainloop</span><span class="p">()</span> </pre></div> </div> </section> <section id="example-custom-descriptors"> <h3><a class="toc-backref" href="#example-custom-descriptors" role="doc-backlink">Example: custom descriptors</a></h3> <p>Since descriptors are used to customize access to an attribute, it’s often useful to know the name of that attribute. Current Python doesn’t give an easy way to find this name and so a lot of custom descriptors, like Ian Bicking’s setonce descriptor <a class="footnote-reference brackets" href="#id13" id="id3">[3]</a>, have to hack around this somehow. With the make-statement, you could create a <code class="docutils literal notranslate"><span class="pre">setonce</span></code> attribute like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">A</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="o">...</span> <span class="n">make</span> <span class="n">setonce</span> <span class="n">x</span><span class="p">:</span> <span class="s2">&quot;A&#39;s x attribute&quot;</span> <span class="o">...</span> </pre></div> </div> <p>where the <code class="docutils literal notranslate"><span class="pre">setonce</span></code> descriptor would be defined like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">setonce</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="s1">&#39;_setonce_attr_</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">name</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__doc__</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">&#39;__doc__&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="fm">__get__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> <span class="k">if</span> <span class="n">obj</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="k">return</span> <span class="bp">self</span> <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="fm">__set__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> <span class="k">try</span><span class="p">:</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">)</span> <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> <span class="nb">setattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="s2">&quot;Attribute already set&quot;</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="nf">set</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> <span class="nb">setattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="fm">__delete__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span> <span class="nb">delattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">)</span> </pre></div> </div> <p>Note that unlike the original implementation, the private attribute name is stable since it uses the name of the descriptor, and therefore instances of class A are pickleable.</p> </section> <section id="example-property-namespaces"> <h3><a class="toc-backref" href="#example-property-namespaces" role="doc-backlink">Example: property namespaces</a></h3> <p>Python’s property type takes three function arguments and a docstring argument which, though relevant only to the property, must be declared before it and then passed as arguments to the property call, e.g.:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">C</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="o">...</span> <span class="k">def</span><span class="w"> </span><span class="nf">get_x</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="o">...</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_x</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="o">...</span> <span class="n">x</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">get_x</span><span class="p">,</span> <span class="n">set_x</span><span class="p">,</span> <span class="s2">&quot;the x of the frobulation&quot;</span><span class="p">)</span> </pre></div> </div> <p>This issue has been brought up before, and Guido <a class="footnote-reference brackets" href="#id14" id="id4">[4]</a> and others <a class="footnote-reference brackets" href="#id15" id="id5">[5]</a> have briefly mused over alternate property syntaxes to make declaring properties easier. With the make-statement, the following syntax could be supported:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">C</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="o">...</span> <span class="n">make</span> <span class="n">block_property</span> <span class="n">x</span><span class="p">:</span> <span class="w"> </span><span class="sd">&#39;&#39;&#39;The x of the frobulation&#39;&#39;&#39;</span> <span class="k">def</span><span class="w"> </span><span class="nf">fget</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="o">...</span> <span class="k">def</span><span class="w"> </span><span class="nf">fset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="o">...</span> </pre></div> </div> <p>with the following definition of <code class="docutils literal notranslate"><span class="pre">block_property</span></code>:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">block_property</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">block_dict</span><span class="p">):</span> <span class="n">fget</span> <span class="o">=</span> <span class="n">block_dict</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">&#39;fget&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="n">fset</span> <span class="o">=</span> <span class="n">block_dict</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">&#39;fset&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="n">fdel</span> <span class="o">=</span> <span class="n">block_dict</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">&#39;fdel&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="n">doc</span> <span class="o">=</span> <span class="n">block_dict</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">&#39;__doc__&#39;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="k">assert</span> <span class="ow">not</span> <span class="n">block_dict</span> <span class="k">return</span> <span class="nb">property</span><span class="p">(</span><span class="n">fget</span><span class="p">,</span> <span class="n">fset</span><span class="p">,</span> <span class="n">fdel</span><span class="p">,</span> <span class="n">doc</span><span class="p">)</span> </pre></div> </div> </section> <section id="example-interfaces"> <h3><a class="toc-backref" href="#example-interfaces" role="doc-backlink">Example: interfaces</a></h3> <p>Guido <a class="footnote-reference brackets" href="#id16" id="id6">[6]</a> and others have occasionally suggested introducing interfaces into python. Most suggestions have offered syntax along the lines of:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">interface</span> <span class="n">IFoo</span><span class="p">:</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Foo blah blah&quot;&quot;&quot;</span> <span class="k">def</span><span class="w"> </span><span class="nf">fumble</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">count</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;docstring&quot;&quot;&quot;</span> </pre></div> </div> <p>but since there is currently no way in Python to declare an interface in this manner, most implementations of Python interfaces use class objects instead, e.g. Zope’s:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">IFoo</span><span class="p">(</span><span class="n">Interface</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Foo blah blah&quot;&quot;&quot;</span> <span class="k">def</span><span class="w"> </span><span class="nf">fumble</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">count</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;docstring&quot;&quot;&quot;</span> </pre></div> </div> <p>With the new make-statement, these interfaces could instead be declared as:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make</span> <span class="n">Interface</span> <span class="n">IFoo</span><span class="p">:</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;Foo blah blah&quot;&quot;&quot;</span> <span class="k">def</span><span class="w"> </span><span class="nf">fumble</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">count</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot;docstring&quot;&quot;&quot;</span> </pre></div> </div> <p>which makes the intent (that this is an interface, not a class) much clearer.</p> </section> </section> <section id="specification"> <h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2> <p>Python will translate a make-statement:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make</span> <span class="o">&lt;</span><span class="nb">callable</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="nb">tuple</span><span class="o">&gt;</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">block</span><span class="o">&gt;</span> </pre></div> </div> <p>into the assignment:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span> <span class="o">=</span> <span class="o">&lt;</span><span class="nb">callable</span><span class="o">&gt;</span><span class="p">(</span><span class="s2">&quot;&lt;name&gt;&quot;</span><span class="p">,</span> <span class="o">&lt;</span><span class="nb">tuple</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">namespace</span><span class="o">&gt;</span><span class="p">)</span> </pre></div> </div> <p>where <code class="docutils literal notranslate"><span class="pre">&lt;namespace&gt;</span></code> is the dict created by executing <code class="docutils literal notranslate"><span class="pre">&lt;block&gt;</span></code>. The <code class="docutils literal notranslate"><span class="pre">&lt;tuple&gt;</span></code> expression is optional; if not present, an empty tuple will be assumed.</p> <p>A patch is available implementing these semantics <a class="footnote-reference brackets" href="#id17" id="id7">[7]</a>.</p> <p>The make-statement introduces a new keyword, <code class="docutils literal notranslate"><span class="pre">make</span></code>. Thus in Python 2.6, the make-statement will have to be enabled using <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">__future__</span> <span class="pre">import</span> <span class="pre">make_statement</span></code>.</p> </section> <section id="open-issues"> <h2><a class="toc-backref" href="#open-issues" role="doc-backlink">Open Issues</a></h2> <section id="keyword"> <h3><a class="toc-backref" href="#keyword" role="doc-backlink">Keyword</a></h3> <p>Does the <code class="docutils literal notranslate"><span class="pre">make</span></code> keyword break too much code? Originally, the make statement used the keyword <code class="docutils literal notranslate"><span class="pre">create</span></code> (a suggestion due to Alyssa Coghlan). However, investigations into the standard library <a class="footnote-reference brackets" href="#id18" id="id8">[8]</a> and Zope+Plone code <a class="footnote-reference brackets" href="#id19" id="id9">[9]</a> revealed that <code class="docutils literal notranslate"><span class="pre">create</span></code> would break a lot more code, so <code class="docutils literal notranslate"><span class="pre">make</span></code> was adopted as the keyword instead. However, there are still a few instances where <code class="docutils literal notranslate"><span class="pre">make</span></code> would break code. Is there a better keyword for the statement?</p> <p>Some possible keywords and their counts in the standard library (plus some installed packages):</p> <ul class="simple"> <li>make - 2 (both in tests)</li> <li>create - 19 (including existing function in imaplib)</li> <li>build - 83 (including existing class in distutils.command.build)</li> <li>construct - 0</li> <li>produce - 0</li> </ul> </section> <section id="the-make-statement-as-an-alternate-constructor"> <h3><a class="toc-backref" href="#the-make-statement-as-an-alternate-constructor" role="doc-backlink">The make-statement as an alternate constructor</a></h3> <p>Currently, there are not many functions which have the signature <code class="docutils literal notranslate"><span class="pre">(name,</span> <span class="pre">args,</span> <span class="pre">kwargs)</span></code>. That means that something like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make</span> <span class="nb">dict</span> <span class="n">params</span><span class="p">:</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">2</span> </pre></div> </div> <p>is currently impossible because the dict constructor has a different signature. Does this sort of thing need to be supported? One suggestion, by Carl Banks, would be to add a <code class="docutils literal notranslate"><span class="pre">__make__</span></code> magic method that if found would be called instead of <code class="docutils literal notranslate"><span class="pre">__call__</span></code>. For types, the <code class="docutils literal notranslate"><span class="pre">__make__</span></code> method would be identical to <code class="docutils literal notranslate"><span class="pre">__call__</span></code> and thus unnecessary, but dicts could support the make-statement by defining a <code class="docutils literal notranslate"><span class="pre">__make__</span></code> method on the dict type that looks something like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">__make__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">):</span> <span class="k">return</span> <span class="bp">cls</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> </pre></div> </div> <p>Of course, rather than adding another magic method, the dict type could just grow a classmethod something like <code class="docutils literal notranslate"><span class="pre">dict.fromblock</span></code> that could be used like:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make</span> <span class="nb">dict</span><span class="o">.</span><span class="n">fromblock</span> <span class="n">params</span><span class="p">:</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">2</span> </pre></div> </div> <p>So the question is, will many types want to use the make-statement as an alternate constructor? And if so, does that alternate constructor need to have the same name as the original constructor?</p> </section> <section id="customizing-the-dict-in-which-the-block-is-executed"> <h3><a class="toc-backref" href="#customizing-the-dict-in-which-the-block-is-executed" role="doc-backlink">Customizing the dict in which the block is executed</a></h3> <p>Should users of the make-statement be able to determine in which dict object the code is executed? This would allow the make-statement to be used in situations where a normal dict object would not suffice, e.g. if order and repeated names must be allowed. Allowing this sort of customization could allow XML to be written without repeating element names, and with nesting of make-statements corresponding to nesting of XML elements:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make</span> <span class="n">Element</span> <span class="n">html</span><span class="p">:</span> <span class="n">make</span> <span class="n">Element</span> <span class="n">body</span><span class="p">:</span> <span class="n">text</span><span class="p">(</span><span class="s1">&#39;before first h1&#39;</span><span class="p">)</span> <span class="n">make</span> <span class="n">Element</span> <span class="n">h1</span><span class="p">:</span> <span class="n">attrib</span><span class="p">(</span><span class="n">style</span><span class="o">=</span><span class="s1">&#39;first&#39;</span><span class="p">)</span> <span class="n">text</span><span class="p">(</span><span class="s1">&#39;first h1&#39;</span><span class="p">)</span> <span class="n">tail</span><span class="p">(</span><span class="s1">&#39;after first h1&#39;</span><span class="p">)</span> <span class="n">make</span> <span class="n">Element</span> <span class="n">h1</span><span class="p">:</span> <span class="n">attrib</span><span class="p">(</span><span class="n">style</span><span class="o">=</span><span class="s1">&#39;second&#39;</span><span class="p">)</span> <span class="n">text</span><span class="p">(</span><span class="s1">&#39;second h1&#39;</span><span class="p">)</span> <span class="n">tail</span><span class="p">(</span><span class="s1">&#39;after second h1&#39;</span><span class="p">)</span> </pre></div> </div> <p>If the make-statement tried to get the dict in which to execute its block by calling the callable’s <code class="docutils literal notranslate"><span class="pre">__make_dict__</span></code> method, the following code would allow the make-statement to be used as above:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">Element</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="k">class</span><span class="w"> </span><span class="nc">__make_dict__</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">_super</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">Element</span><span class="o">.</span><span class="n">__make_dict__</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">_super</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">elements</span> <span class="o">=</span> <span class="p">[]</span> <span class="bp">self</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="kc">None</span> <span class="bp">self</span><span class="o">.</span><span class="n">tail</span> <span class="o">=</span> <span class="kc">None</span> <span class="bp">self</span><span class="o">.</span><span class="n">attrib</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">def</span><span class="w"> </span><span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span> <span class="k">try</span><span class="p">:</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_super</span><span class="o">.</span><span class="fm">__getitem__</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span> <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">&#39;attrib&#39;</span><span class="p">,</span> <span class="s1">&#39;text&#39;</span><span class="p">,</span> <span class="s1">&#39;tail&#39;</span><span class="p">]:</span> <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;set_</span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">name</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="nb">globals</span><span class="p">()[</span><span class="n">name</span><span class="p">]</span> <span class="k">def</span><span class="w"> </span><span class="fm">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">_super</span><span class="o">.</span><span class="fm">__setitem__</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">elements</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_attrib</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">attrib</span> <span class="o">=</span> <span class="n">kwargs</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_text</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="n">text</span> <span class="k">def</span><span class="w"> </span><span class="nf">set_tail</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">tail</span> <span class="o">=</span> <span class="n">text</span> <span class="k">def</span><span class="w"> </span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">edict</span><span class="p">):</span> <span class="n">get_element</span> <span class="o">=</span> <span class="n">etree</span><span class="o">.</span><span class="n">ElementTree</span><span class="o">.</span><span class="n">Element</span> <span class="n">result</span> <span class="o">=</span> <span class="n">get_element</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">attrib</span><span class="o">=</span><span class="n">edict</span><span class="o">.</span><span class="n">attrib</span><span class="p">)</span> <span class="n">result</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="n">edict</span><span class="o">.</span><span class="n">text</span> <span class="n">result</span><span class="o">.</span><span class="n">tail</span> <span class="o">=</span> <span class="n">edict</span><span class="o">.</span><span class="n">tail</span> <span class="k">for</span> <span class="n">element</span> <span class="ow">in</span> <span class="n">edict</span><span class="o">.</span><span class="n">elements</span><span class="p">:</span> <span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">element</span><span class="p">)</span> <span class="k">return</span> <span class="n">result</span> </pre></div> </div> <p>Note, however, that the code to support this is somewhat fragile – it has to magically populate the namespace with <code class="docutils literal notranslate"><span class="pre">attrib</span></code>, <code class="docutils literal notranslate"><span class="pre">text</span></code> and <code class="docutils literal notranslate"><span class="pre">tail</span></code>, and it assumes that every name binding inside the make statement body is creating an Element. As it stands, this code would break with the introduction of a simple for-loop to any one of the make-statement bodies, because the for-loop would bind a name to a non-Element object. This could be worked around by adding some sort of isinstance check or attribute examination, but this still results in a somewhat fragile solution.</p> <p>It has also been pointed out that the with-statement can provide equivalent nesting with a much more explicit syntax:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="n">Element</span><span class="p">(</span><span class="s1">&#39;html&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">html</span><span class="p">:</span> <span class="k">with</span> <span class="n">Element</span><span class="p">(</span><span class="s1">&#39;body&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">body</span><span class="p">:</span> <span class="n">body</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s1">&#39;before first h1&#39;</span> <span class="k">with</span> <span class="n">Element</span><span class="p">(</span><span class="s1">&#39;h1&#39;</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="s1">&#39;first&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">h1</span><span class="p">:</span> <span class="n">h1</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s1">&#39;first h1&#39;</span> <span class="n">h1</span><span class="o">.</span><span class="n">tail</span> <span class="o">=</span> <span class="s1">&#39;after first h1&#39;</span> <span class="k">with</span> <span class="n">Element</span><span class="p">(</span><span class="s1">&#39;h1&#39;</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="s1">&#39;second&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">h1</span><span class="p">:</span> <span class="n">h1</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s1">&#39;second h1&#39;</span> <span class="n">h1</span><span class="o">.</span><span class="n">tail</span> <span class="o">=</span> <span class="s1">&#39;after second h1&#39;</span> </pre></div> </div> <p>And if the repetition of the element names here is too much of a DRY violation, it is also possible to eliminate all as-clauses except for the first by adding a few methods to Element. <a class="footnote-reference brackets" href="#id20" id="id10">[10]</a></p> <p>So are there real use-cases for executing the block in a dict of a different type? And if so, should the make-statement be extended to support them?</p> </section> </section> <section id="optional-extensions"> <h2><a class="toc-backref" href="#optional-extensions" role="doc-backlink">Optional Extensions</a></h2> <section id="remove-the-make-keyword"> <h3><a class="toc-backref" href="#remove-the-make-keyword" role="doc-backlink">Remove the make keyword</a></h3> <p>It might be possible to remove the make keyword so that such statements would begin with the callable being called, e.g.:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">namespace</span> <span class="n">ns</span><span class="p">:</span> <span class="n">badger</span> <span class="o">=</span> <span class="mi">42</span> <span class="k">def</span><span class="w"> </span><span class="nf">spam</span><span class="p">():</span> <span class="o">...</span> <span class="n">interface</span> <span class="n">C</span><span class="p">(</span><span class="o">...</span><span class="p">):</span> <span class="o">...</span> </pre></div> </div> <p>However, almost all other Python statements begin with a keyword, and removing the keyword would make it harder to look up this construct in the documentation. Additionally, this would add some complexity in the grammar and so far I (Steven Bethard) have not been able to implement the feature without the keyword.</p> </section> <section id="removing-metaclass-in-python-3000"> <h3><a class="toc-backref" href="#removing-metaclass-in-python-3000" role="doc-backlink">Removing __metaclass__ in Python 3000</a></h3> <p>As a side-effect of its generality, the make-statement mostly eliminates the need for the <code class="docutils literal notranslate"><span class="pre">__metaclass__</span></code> attribute in class objects. Thus in Python 3000, instead of:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>class &lt;name&gt; &lt;bases-tuple&gt;: __metaclass__ = &lt;metaclass&gt; &lt;block&gt; </pre></div> </div> <p>metaclasses could be supported by using the metaclass as the callable in a make-statement:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">make</span> <span class="o">&lt;</span><span class="n">metaclass</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="n">bases</span><span class="o">-</span><span class="nb">tuple</span><span class="o">&gt;</span><span class="p">:</span> <span class="o">&lt;</span><span class="n">block</span><span class="o">&gt;</span> </pre></div> </div> <p>Removing the <code class="docutils literal notranslate"><span class="pre">__metaclass__</span></code> hook would simplify the BUILD_CLASS opcode a bit.</p> </section> <section id="removing-class-statements-in-python-3000"> <h3><a class="toc-backref" href="#removing-class-statements-in-python-3000" role="doc-backlink">Removing class statements in Python 3000</a></h3> <p>In the most extreme application of make-statements, the class statement itself could be deprecated in favor of <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">type</span></code> statements.</p> </section> </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="id11" role="doc-footnote"> <dt class="label" id="id11">[<a href="#id1">1</a>]</dt> <dd>Michele Simionato’s original suggestion (<a class="reference external" href="https://mail.python.org/pipermail/python-dev/2005-October/057435.html">https://mail.python.org/pipermail/python-dev/2005-October/057435.html</a>)</aside> <aside class="footnote brackets" id="id12" role="doc-footnote"> <dt class="label" id="id12">[<a href="#id2">2</a>]</dt> <dd>Guido requests withdrawal (<a class="reference external" href="https://mail.python.org/pipermail/python-3000/2006-April/000936.html">https://mail.python.org/pipermail/python-3000/2006-April/000936.html</a>)</aside> <aside class="footnote brackets" id="id13" role="doc-footnote"> <dt class="label" id="id13">[<a href="#id3">3</a>]</dt> <dd>Ian Bicking’s setonce descriptor (<a class="reference external" href="http://blog.ianbicking.org/easy-readonly-attributes.html">http://blog.ianbicking.org/easy-readonly-attributes.html</a>)</aside> <aside class="footnote brackets" id="id14" role="doc-footnote"> <dt class="label" id="id14">[<a href="#id4">4</a>]</dt> <dd>Guido ponders property syntax (<a class="reference external" href="https://mail.python.org/pipermail/python-dev/2005-October/057404.html">https://mail.python.org/pipermail/python-dev/2005-October/057404.html</a>)</aside> <aside class="footnote brackets" id="id15" role="doc-footnote"> <dt class="label" id="id15">[<a href="#id5">5</a>]</dt> <dd>Namespace-based property recipe (<a class="reference external" href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442418">http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442418</a>)</aside> <aside class="footnote brackets" id="id16" role="doc-footnote"> <dt class="label" id="id16">[<a href="#id6">6</a>]</dt> <dd>Python interfaces (<a class="reference external" href="http://www.artima.com/weblogs/viewpost.jsp?thread=86641">http://www.artima.com/weblogs/viewpost.jsp?thread=86641</a>)</aside> <aside class="footnote brackets" id="id17" role="doc-footnote"> <dt class="label" id="id17">[<a href="#id7">7</a>]</dt> <dd>Make Statement patch (<a class="reference external" href="http://ucsu.colorado.edu/~bethard/py/make_statement.patch">http://ucsu.colorado.edu/~bethard/py/make_statement.patch</a>)</aside> <aside class="footnote brackets" id="id18" role="doc-footnote"> <dt class="label" id="id18">[<a href="#id8">8</a>]</dt> <dd>Instances of create in the stdlib (<a class="reference external" href="https://mail.python.org/pipermail/python-list/2006-April/335159.html">https://mail.python.org/pipermail/python-list/2006-April/335159.html</a>)</aside> <aside class="footnote brackets" id="id19" role="doc-footnote"> <dt class="label" id="id19">[<a href="#id9">9</a>]</dt> <dd>Instances of create in Zope+Plone (<a class="reference external" href="https://mail.python.org/pipermail/python-list/2006-April/335284.html">https://mail.python.org/pipermail/python-list/2006-April/335284.html</a>)</aside> <aside class="footnote brackets" id="id20" role="doc-footnote"> <dt class="label" id="id20">[<a href="#id10">10</a>]</dt> <dd>Eliminate as-clauses in with-statement XML (<a class="reference external" href="https://mail.python.org/pipermail/python-list/2006-April/336774.html">https://mail.python.org/pipermail/python-list/2006-April/336774.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-0359.rst">https://github.com/python/peps/blob/main/peps/pep-0359.rst</a></p> <p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0359.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="#withdrawal-notice">Withdrawal Notice</a></li> <li><a class="reference internal" href="#motivation">Motivation</a><ul> <li><a class="reference internal" href="#example-simple-namespaces">Example: simple namespaces</a></li> <li><a class="reference internal" href="#example-gui-objects">Example: GUI objects</a></li> <li><a class="reference internal" href="#example-custom-descriptors">Example: custom descriptors</a></li> <li><a class="reference internal" href="#example-property-namespaces">Example: property namespaces</a></li> <li><a class="reference internal" href="#example-interfaces">Example: interfaces</a></li> </ul> </li> <li><a class="reference internal" href="#specification">Specification</a></li> <li><a class="reference internal" href="#open-issues">Open Issues</a><ul> <li><a class="reference internal" href="#keyword">Keyword</a></li> <li><a class="reference internal" href="#the-make-statement-as-an-alternate-constructor">The make-statement as an alternate constructor</a></li> <li><a class="reference internal" href="#customizing-the-dict-in-which-the-block-is-executed">Customizing the dict in which the block is executed</a></li> </ul> </li> <li><a class="reference internal" href="#optional-extensions">Optional Extensions</a><ul> <li><a class="reference internal" href="#remove-the-make-keyword">Remove the make keyword</a></li> <li><a class="reference internal" href="#removing-metaclass-in-python-3000">Removing __metaclass__ in Python 3000</a></li> <li><a class="reference internal" href="#removing-class-statements-in-python-3000">Removing class statements in Python 3000</a></li> </ul> </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-0359.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