python-peps/pep-0359/index.html

707 lines
62 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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 Guidos request <a class="footnote-reference brackets" href="#id12" id="id2">[2]</a>. Guido didnt like it,
and in particular didnt 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 (dont 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="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="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>Lets 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”, Id 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="nc">namespace</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</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="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 Buttons 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="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, its
often useful to know the name of that attribute. Current Python
doesnt give an easy way to find this name and so a lot of custom
descriptors, like Ian Bickings 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="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="nc">setonce</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</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="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="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="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="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>Pythons 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="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="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="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="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="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="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="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="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. Zopes:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</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="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="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="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 callables <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="nc">Element</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">class</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="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="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="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="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="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="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="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="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 Simionatos 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 Bickings 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">2023-10-11 12:05:51 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>