python-peps/pep-0286/index.html

238 lines
16 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 286 Enhanced Argument Tuples | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0286/">
<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 286 Enhanced Argument Tuples | peps.python.org'>
<meta property="og:description" content="PyArg_ParseTuple is confronted with difficult memory management if an argument converter creates new memory. To deal with these cases, a specialized argument type is proposed.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0286/">
<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="PyArg_ParseTuple is confronted with difficult memory management if an argument converter creates new memory. To deal with these cases, a specialized argument type is proposed.">
<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 286</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 286 Enhanced Argument Tuples</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Martin von Löwis &lt;martin&#32;&#97;t&#32;v.loewis.de&gt;</dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Inactive draft that may be taken up again at a later time">Deferred</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">03-Mar-2002</dd>
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
<dd class="field-odd">2.3</dd>
<dt class="field-even">Post-History<span class="colon">:</span></dt>
<dd class="field-even"><p></p></dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#pep-deferral">PEP Deferral</a></li>
<li><a class="reference internal" href="#problem-description">Problem description</a></li>
<li><a class="reference internal" href="#proposed-solution">Proposed solution</a></li>
<li><a class="reference internal" href="#affected-converters">Affected converters</a></li>
<li><a class="reference internal" href="#new-converters">New converters</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
</details></section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p><code class="docutils literal notranslate"><span class="pre">PyArg_ParseTuple</span></code> is confronted with difficult memory management if
an argument converter creates new memory. To deal with these
cases, a specialized argument type is proposed.</p>
</section>
<section id="pep-deferral">
<h2><a class="toc-backref" href="#pep-deferral" role="doc-backlink">PEP Deferral</a></h2>
<p>Further exploration of the concepts covered in this PEP has been deferred
for lack of a current champion interested in promoting the goals of the
PEP and collecting and incorporating feedback, and with sufficient
available time to do so effectively.</p>
<p>The resolution of this PEP may also be affected by the resolution of
<a class="pep reference internal" href="../pep-0426/" title="PEP 426 Metadata for Python Software Packages 2.0">PEP 426</a>, which proposes the use of a preprocessing step to generate
some aspects of C API interface code.</p>
</section>
<section id="problem-description">
<h2><a class="toc-backref" href="#problem-description" role="doc-backlink">Problem description</a></h2>
<p>Today, argument tuples keep references to the function arguments,
which are guaranteed to live as long as the argument tuple exists
which is at least as long as the function call is being executed.</p>
<p>In some cases, parsing an argument will allocate new memory, which
is then to be released by the caller. This has two problems:</p>
<ol class="arabic simple">
<li>In case of failure, the application cannot know what memory to
release; most callers dont even know that they have the
responsibility to release that memory. Example for this are
the <code class="docutils literal notranslate"><span class="pre">N</span></code> converter (bug #416288 <a class="footnote-reference brackets" href="#id3" id="id1">[1]</a>) and the <code class="docutils literal notranslate"><span class="pre">es#</span></code> converter (bug
#501716 <a class="footnote-reference brackets" href="#id4" id="id2">[2]</a>).</li>
<li>Even for successful argument parsing, it is still inconvenient
for the caller to be responsible for releasing the memory. In
some cases, this is unnecessarily inefficient. For example,
the <code class="docutils literal notranslate"><span class="pre">es</span></code> converter copies the conversion result into memory, even
though there already is a string object that has the right
contents.</li>
</ol>
</section>
<section id="proposed-solution">
<h2><a class="toc-backref" href="#proposed-solution" role="doc-backlink">Proposed solution</a></h2>
<p>A new type argument tuple is introduced. This type derives from
tuple, adding an <code class="docutils literal notranslate"><span class="pre">__dict__</span></code> member (at <code class="docutils literal notranslate"><span class="pre">tp_dictoffset</span></code> -4). Instances
of this type might get the following attributes:</p>
<ul class="simple">
<li>failobjects, a list of objects which need to be deallocated
in case of success</li>
<li>okobjects, a list of object which will be released when the
argument tuple is released</li>
</ul>
<p>To manage this type, the following functions will be added, and
used appropriately in <code class="docutils literal notranslate"><span class="pre">ceval.c</span></code> and <code class="docutils literal notranslate"><span class="pre">getargs.c</span></code>:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">PyArgTuple_New(int);</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">PyArgTuple_AddFailObject(PyObject*,</span> <span class="pre">PyObject*);</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">PyArgTuple_AddFailMemory(PyObject*,</span> <span class="pre">void*);</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">PyArgTuple_AddOkObject(PyObject*,</span> <span class="pre">PyObject*);</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">PyArgTuple_AddOkMemory(PyObject*,</span> <span class="pre">void*);</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">PyArgTuple_ClearFailed(PyObject*);</span></code></li>
</ul>
<p>When argument parsing fails, all fail objects will be released
through <code class="docutils literal notranslate"><span class="pre">Py_DECREF</span></code>, and all fail memory will be released through
<code class="docutils literal notranslate"><span class="pre">PyMem_Free</span></code>. If parsing succeeds, the references to the fail
objects and fail memory are dropped, without releasing anything.</p>
<p>When the argument tuple is released, all ok objects and memory
will be released.</p>
<p>If those functions are called with an object of a different type,
a warning is issued and no further action is taken; usage of the
affected converters without using argument tuples is deprecated.</p>
</section>
<section id="affected-converters">
<h2><a class="toc-backref" href="#affected-converters" role="doc-backlink">Affected converters</a></h2>
<p>The following converters will add fail memory and fail objects: <code class="docutils literal notranslate"><span class="pre">N</span></code>,
<code class="docutils literal notranslate"><span class="pre">es</span></code>, <code class="docutils literal notranslate"><span class="pre">et</span></code>, <code class="docutils literal notranslate"><span class="pre">es#</span></code>, <code class="docutils literal notranslate"><span class="pre">et#</span></code> (unless memory is passed into the converter)</p>
</section>
<section id="new-converters">
<h2><a class="toc-backref" href="#new-converters" role="doc-backlink">New converters</a></h2>
<p>To simplify Unicode conversion, the <code class="docutils literal notranslate"><span class="pre">e*</span></code> converters are duplicated
as <code class="docutils literal notranslate"><span class="pre">E*</span></code> converters (<code class="docutils literal notranslate"><span class="pre">Es</span></code>, <code class="docutils literal notranslate"><span class="pre">Et</span></code>, <code class="docutils literal notranslate"><span class="pre">Es#</span></code>, <code class="docutils literal notranslate"><span class="pre">Et#</span></code>). The usage of the <code class="docutils literal notranslate"><span class="pre">E*</span></code>
converters is identical to that of the <code class="docutils literal notranslate"><span class="pre">e*</span></code> converters, except that
the application will not need to manage the resulting memory.
This will be implemented through registration of Ok objects with
the argument tuple. The <code class="docutils literal notranslate"><span class="pre">e*</span></code> converters are deprecated.</p>
</section>
<section id="references">
<h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id3" role="doc-footnote">
<dt class="label" id="id3">[<a href="#id1">1</a>]</dt>
<dd>infrequent memory leak in pyexpat
(<a class="reference external" href="http://bugs.python.org/issue416288">http://bugs.python.org/issue416288</a>)</aside>
<aside class="footnote brackets" id="id4" role="doc-footnote">
<dt class="label" id="id4">[<a href="#id2">2</a>]</dt>
<dd>“es#” parser marker leaks memory
(<a class="reference external" href="http://bugs.python.org/issue501716">http://bugs.python.org/issue501716</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-0286.rst">https://github.com/python/peps/blob/main/peps/pep-0286.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0286.rst">2023-09-09 17:39:29 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#pep-deferral">PEP Deferral</a></li>
<li><a class="reference internal" href="#problem-description">Problem description</a></li>
<li><a class="reference internal" href="#proposed-solution">Proposed solution</a></li>
<li><a class="reference internal" href="#affected-converters">Affected converters</a></li>
<li><a class="reference internal" href="#new-converters">New converters</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0286.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>