python-peps/pep-3107/index.html

475 lines
36 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 3107 Function Annotations | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-3107/">
<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 3107 Function Annotations | peps.python.org'>
<meta property="og:description" content="This PEP introduces a syntax for adding arbitrary metadata annotations to Python functions 1.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-3107/">
<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 introduces a syntax for adding arbitrary metadata annotations to Python functions 1.">
<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 3107</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 3107 Function Annotations</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Collin Winter &lt;collinwinter&#32;&#97;t&#32;google.com&gt;,
Tony Lownds &lt;tony&#32;&#97;t&#32;lownds.com&gt;</dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
<dt class="field-odd">Type<span class="colon">:</span></dt>
<dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
<dt class="field-even">Created<span class="colon">:</span></dt>
<dd class="field-even">02-Dec-2006</dd>
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
<dd class="field-odd">3.0</dd>
<dt class="field-even">Post-History<span class="colon">:</span></dt>
<dd class="field-even"><p></p></dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#fundamentals-of-function-annotations">Fundamentals of Function Annotations</a></li>
<li><a class="reference internal" href="#syntax">Syntax</a><ul>
<li><a class="reference internal" href="#parameters">Parameters</a></li>
<li><a class="reference internal" href="#return-values">Return Values</a></li>
<li><a class="reference internal" href="#lambda">Lambda</a></li>
</ul>
</li>
<li><a class="reference internal" href="#accessing-function-annotations">Accessing Function Annotations</a></li>
<li><a class="reference internal" href="#use-cases">Use Cases</a></li>
<li><a class="reference internal" href="#standard-library">Standard Library</a><ul>
<li><a class="reference internal" href="#pydoc-and-inspect">pydoc and inspect</a></li>
</ul>
</li>
<li><a class="reference internal" href="#relation-to-other-peps">Relation to Other PEPs</a><ul>
<li><a class="reference internal" href="#function-signature-objects-pep-362">Function Signature Objects (PEP 362)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#rejected-proposals">Rejected Proposals</a></li>
<li><a class="reference internal" href="#references-and-footnotes">References and Footnotes</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 introduces a syntax for adding arbitrary metadata annotations
to Python functions <a class="footnote-reference brackets" href="#functerm" id="id1">[1]</a>.</p>
</section>
<section id="rationale">
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
<p>Because Pythons 2.x series lacks a standard way of annotating a
functions parameters and return values, a variety of tools
and libraries have appeared to fill this gap. Some
utilise the decorators introduced in <a class="pep reference internal" href="../pep-0318/" title="PEP 318 Decorators for Functions and Methods">PEP 318</a>, while others parse a
functions docstring, looking for annotations there.</p>
<p>This PEP aims to provide a single, standard way of specifying this
information, reducing the confusion caused by the wide variation in
mechanism and syntax that has existed until this point.</p>
</section>
<section id="fundamentals-of-function-annotations">
<h2><a class="toc-backref" href="#fundamentals-of-function-annotations" role="doc-backlink">Fundamentals of Function Annotations</a></h2>
<p>Before launching into a discussion of the precise ins and outs of
Python 3.0s function annotations, lets first talk broadly about
what annotations are and are not:</p>
<ol class="arabic">
<li>Function annotations, both for parameters and return values, are
completely optional.</li>
<li>Function annotations are nothing more than a way of associating
arbitrary Python expressions with various parts of a function at
compile-time.<p>By itself, Python does not attach any particular meaning or
significance to annotations. Left to its own, Python simply makes
these expressions available as described in <a class="reference internal" href="#accessing-function-annotations">Accessing Function
Annotations</a> below.</p>
<p>The only way that annotations take on meaning is when they are
interpreted by third-party libraries. These annotation consumers
can do anything they want with a functions annotations. For
example, one library might use string-based annotations to provide
improved help messages, like so:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile</span><span class="p">(</span><span class="n">source</span><span class="p">:</span> <span class="s2">&quot;something compilable&quot;</span><span class="p">,</span>
<span class="n">filename</span><span class="p">:</span> <span class="s2">&quot;where the compilable thing comes from&quot;</span><span class="p">,</span>
<span class="n">mode</span><span class="p">:</span> <span class="s2">&quot;is this a single statement or a suite?&quot;</span><span class="p">):</span>
<span class="o">...</span>
</pre></div>
</div>
<p>Another library might be used to provide typechecking for Python
functions and methods. This library could use annotations to
indicate the functions expected input and return types, possibly
something like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">haul</span><span class="p">(</span><span class="n">item</span><span class="p">:</span> <span class="n">Haulable</span><span class="p">,</span> <span class="o">*</span><span class="n">vargs</span><span class="p">:</span> <span class="n">PackAnimal</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Distance</span><span class="p">:</span>
<span class="o">...</span>
</pre></div>
</div>
<p>However, neither the strings in the first example nor the
type information in the second example have any meaning on their
own; meaning comes from third-party libraries alone.</p>
</li>
<li>Following from point 2, this PEP makes no attempt to introduce
any kind of standard semantics, even for the built-in types.
This work will be left to third-party libraries.</li>
</ol>
</section>
<section id="syntax">
<h2><a class="toc-backref" href="#syntax" role="doc-backlink">Syntax</a></h2>
<section id="parameters">
<h3><a class="toc-backref" href="#parameters" role="doc-backlink">Parameters</a></h3>
<p>Annotations for parameters take the form of optional expressions that
follow the parameter name:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">a</span><span class="p">:</span> <span class="n">expression</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="n">expression</span> <span class="o">=</span> <span class="mi">5</span><span class="p">):</span>
<span class="o">...</span>
</pre></div>
</div>
<p>In pseudo-grammar, parameters now look like <code class="docutils literal notranslate"><span class="pre">identifier</span> <span class="pre">[:</span>
<span class="pre">expression]</span> <span class="pre">[=</span> <span class="pre">expression]</span></code>. That is, annotations always precede a
parameters default value and both annotations and default values are
optional. Just like how equal signs are used to indicate a default
value, colons are used to mark annotations. All annotation
expressions are evaluated when the function definition is executed,
just like default values.</p>
<p>Annotations for excess parameters (i.e., <code class="docutils literal notranslate"><span class="pre">*args</span></code> and <code class="docutils literal notranslate"><span class="pre">**kwargs</span></code>)
are indicated similarly:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="n">expression</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">expression</span><span class="p">):</span>
<span class="o">...</span>
</pre></div>
</div>
<p>Annotations for nested parameters always follow the name of the
parameter, not the last parenthesis. Annotating all parameters of a
nested parameter is not required:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">foo</span><span class="p">((</span><span class="n">x1</span><span class="p">,</span> <span class="n">y1</span><span class="p">:</span> <span class="n">expression</span><span class="p">),</span>
<span class="p">(</span><span class="n">x2</span><span class="p">:</span> <span class="n">expression</span><span class="p">,</span> <span class="n">y2</span><span class="p">:</span> <span class="n">expression</span><span class="p">)</span><span class="o">=</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)):</span>
<span class="o">...</span>
</pre></div>
</div>
</section>
<section id="return-values">
<h3><a class="toc-backref" href="#return-values" role="doc-backlink">Return Values</a></h3>
<p>The examples thus far have omitted examples of how to annotate the
type of a functions return value. This is done like so:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sum</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">expression</span><span class="p">:</span>
<span class="o">...</span>
</pre></div>
</div>
<p>That is, the parameter list can now be followed by a literal <code class="docutils literal notranslate"><span class="pre">-&gt;</span></code>
and a Python expression. Like the annotations for parameters, this
expression will be evaluated when the function definition is executed.</p>
<p>The grammar for function definitions <a class="footnote-reference brackets" href="#grammar" id="id2">[11]</a> is now:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">decorator</span><span class="p">:</span> <span class="s1">&#39;@&#39;</span> <span class="n">dotted_name</span> <span class="p">[</span> <span class="s1">&#39;(&#39;</span> <span class="p">[</span><span class="n">arglist</span><span class="p">]</span> <span class="s1">&#39;)&#39;</span> <span class="p">]</span> <span class="n">NEWLINE</span>
<span class="n">decorators</span><span class="p">:</span> <span class="n">decorator</span><span class="o">+</span>
<span class="n">funcdef</span><span class="p">:</span> <span class="p">[</span><span class="n">decorators</span><span class="p">]</span> <span class="s1">&#39;def&#39;</span> <span class="n">NAME</span> <span class="n">parameters</span> <span class="p">[</span><span class="s1">&#39;-&gt;&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span>
<span class="n">parameters</span><span class="p">:</span> <span class="s1">&#39;(&#39;</span> <span class="p">[</span><span class="n">typedargslist</span><span class="p">]</span> <span class="s1">&#39;)&#39;</span>
<span class="n">typedargslist</span><span class="p">:</span> <span class="p">((</span><span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="s1">&#39;,&#39;</span><span class="p">)</span><span class="o">*</span>
<span class="p">(</span><span class="s1">&#39;*&#39;</span> <span class="p">[</span><span class="n">tname</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">tname</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="s1">&#39;**&#39;</span> <span class="n">tname</span><span class="p">]</span>
<span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">tname</span><span class="p">)</span>
<span class="o">|</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">])</span>
<span class="n">tname</span><span class="p">:</span> <span class="n">NAME</span> <span class="p">[</span><span class="s1">&#39;:&#39;</span> <span class="n">test</span><span class="p">]</span>
<span class="n">tfpdef</span><span class="p">:</span> <span class="n">tname</span> <span class="o">|</span> <span class="s1">&#39;(&#39;</span> <span class="n">tfplist</span> <span class="s1">&#39;)&#39;</span>
<span class="n">tfplist</span><span class="p">:</span> <span class="n">tfpdef</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">tfpdef</span><span class="p">)</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span>
</pre></div>
</div>
</section>
<section id="lambda">
<h3><a class="toc-backref" href="#lambda" role="doc-backlink">Lambda</a></h3>
<p><code class="docutils literal notranslate"><span class="pre">lambda</span></code>s syntax does not support annotations. The syntax of
<code class="docutils literal notranslate"><span class="pre">lambda</span></code> could be changed to support annotations, by requiring
parentheses around the parameter list. However it was decided
<a class="footnote-reference brackets" href="#id25" id="id3">[12]</a> not to make this change because:</p>
<ol class="arabic simple">
<li>It would be an incompatible change.</li>
<li>Lambdas are neutered anyway.</li>
<li>The lambda can always be changed to a function.</li>
</ol>
</section>
</section>
<section id="accessing-function-annotations">
<h2><a class="toc-backref" href="#accessing-function-annotations" role="doc-backlink">Accessing Function Annotations</a></h2>
<p>Once compiled, a functions annotations are available via the
functions <code class="docutils literal notranslate"><span class="pre">__annotations__</span></code> attribute. This attribute is
a mutable dictionary, mapping parameter names to an object
representing the evaluated annotation expression</p>
<p>There is a special key in the <code class="docutils literal notranslate"><span class="pre">__annotations__</span></code> mapping,
<code class="docutils literal notranslate"><span class="pre">&quot;return&quot;</span></code>. This key is present only if an annotation was supplied
for the functions return value.</p>
<p>For example, the following annotation:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">a</span><span class="p">:</span> <span class="s1">&#39;x&#39;</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="mi">5</span> <span class="o">+</span> <span class="mi">6</span><span class="p">,</span> <span class="n">c</span><span class="p">:</span> <span class="nb">list</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">max</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">9</span><span class="p">):</span>
<span class="o">...</span>
</pre></div>
</div>
<p>would result in an <code class="docutils literal notranslate"><span class="pre">__annotations__</span></code> mapping of</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="s1">&#39;a&#39;</span><span class="p">:</span> <span class="s1">&#39;x&#39;</span><span class="p">,</span>
<span class="s1">&#39;b&#39;</span><span class="p">:</span> <span class="mi">11</span><span class="p">,</span>
<span class="s1">&#39;c&#39;</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span>
<span class="s1">&#39;return&#39;</span><span class="p">:</span> <span class="mi">9</span><span class="p">}</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">return</span></code> key was chosen because it cannot conflict with the name
of a parameter; any attempt to use <code class="docutils literal notranslate"><span class="pre">return</span></code> as a parameter name
would result in a <code class="docutils literal notranslate"><span class="pre">SyntaxError</span></code>.</p>
<p><code class="docutils literal notranslate"><span class="pre">__annotations__</span></code> is an empty, mutable dictionary if there are no
annotations on the function or if the functions was created from
a <code class="docutils literal notranslate"><span class="pre">lambda</span></code> expression.</p>
</section>
<section id="use-cases">
<h2><a class="toc-backref" href="#use-cases" role="doc-backlink">Use Cases</a></h2>
<p>In the course of discussing annotations, a number of use-cases have
been raised. Some of these are presented here, grouped by what kind
of information they convey. Also included are examples of existing
products and packages that could make use of annotations.</p>
<ul class="simple">
<li>Providing typing information<ul>
<li>Type checking (<a class="footnote-reference brackets" href="#typecheck" id="id4">[3]</a>, <a class="footnote-reference brackets" href="#maxime" id="id5">[4]</a>)</li>
<li>Let IDEs show what types a function expects and returns (<a class="footnote-reference brackets" href="#idle" id="id6">[16]</a>)</li>
<li>Function overloading / generic functions (<a class="footnote-reference brackets" href="#scaling" id="id7">[21]</a>)</li>
<li>Foreign-language bridges (<a class="footnote-reference brackets" href="#jython" id="id8">[17]</a>, <a class="footnote-reference brackets" href="#ironpython" id="id9">[18]</a>)</li>
<li>Adaptation (<a class="footnote-reference brackets" href="#adaptationpost" id="id10">[20]</a>, <a class="footnote-reference brackets" href="#pyprotocols" id="id11">[19]</a>)</li>
<li>Predicate logic functions</li>
<li>Database query mapping</li>
<li>RPC parameter marshaling (<a class="footnote-reference brackets" href="#rpyc" id="id12">[22]</a>)</li>
</ul>
</li>
<li>Other information<ul>
<li>Documentation for parameters and return values (<a class="footnote-reference brackets" href="#pydoc" id="id13">[23]</a>)</li>
</ul>
</li>
</ul>
</section>
<section id="standard-library">
<h2><a class="toc-backref" href="#standard-library" role="doc-backlink">Standard Library</a></h2>
<section id="pydoc-and-inspect">
<h3><a class="toc-backref" href="#pydoc-and-inspect" role="doc-backlink">pydoc and inspect</a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">pydoc</span></code> module should display the function annotations when
displaying help for a function. The <code class="docutils literal notranslate"><span class="pre">inspect</span></code> module should change
to support annotations.</p>
</section>
</section>
<section id="relation-to-other-peps">
<h2><a class="toc-backref" href="#relation-to-other-peps" role="doc-backlink">Relation to Other PEPs</a></h2>
<section id="function-signature-objects-pep-362">
<h3><a class="toc-backref" href="#function-signature-objects-pep-362" role="doc-backlink">Function Signature Objects (PEP 362)</a></h3>
<p>Function Signature Objects should expose the functions annotations.
The <code class="docutils literal notranslate"><span class="pre">Parameter</span></code> object may change or other changes may be warranted.</p>
</section>
</section>
<section id="implementation">
<h2><a class="toc-backref" href="#implementation" role="doc-backlink">Implementation</a></h2>
<p>A reference implementation has been checked into the py3k (formerly
“p3yk”) branch as revision 53170 <a class="footnote-reference brackets" href="#id24" id="id14">[10]</a>.</p>
</section>
<section id="rejected-proposals">
<h2><a class="toc-backref" href="#rejected-proposals" role="doc-backlink">Rejected Proposals</a></h2>
<ul class="simple">
<li>The BDFL rejected the authors idea for a special syntax for adding
annotations to generators as being “too ugly” <a class="footnote-reference brackets" href="#rejectgensyn" id="id15">[2]</a>.</li>
<li>Though discussed early on (<a class="footnote-reference brackets" href="#threadgen" id="id16">[5]</a>, <a class="footnote-reference brackets" href="#threadhof" id="id17">[6]</a>), including
special objects in the stdlib for annotating generator functions and
higher-order functions was ultimately rejected as being more
appropriate for third-party libraries; including them in the
standard library raised too many thorny issues.</li>
<li>Despite considerable discussion about a standard type
parameterisation syntax, it was decided that this should also be
left to third-party libraries. (<a class="footnote-reference brackets" href="#threadimmlist" id="id18">[7]</a>,
<a class="footnote-reference brackets" href="#threadmixing" id="id19">[8]</a>, <a class="footnote-reference brackets" href="#emphasistpls" id="id20">[9]</a>).</li>
<li>Despite yet more discussion, it was decided not to standardize
a mechanism for annotation interoperability. Standardizing
interoperability conventions at this point would be premature.
We would rather let these conventions develop organically, based
on real-world usage and necessity, than try to force all users
into some contrived scheme. (<a class="footnote-reference brackets" href="#interop0" id="id21">[13]</a>, <a class="footnote-reference brackets" href="#interop1" id="id22">[14]</a>,
<a class="footnote-reference brackets" href="#interop2" id="id23">[15]</a>).</li>
</ul>
</section>
<section id="references-and-footnotes">
<h2><a class="toc-backref" href="#references-and-footnotes" role="doc-backlink">References and Footnotes</a></h2>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="functerm" role="doc-footnote">
<dt class="label" id="functerm">[<a href="#id1">1</a>]</dt>
<dd>Unless specifically stated, “function” is generally
used as a synonym for “callable” throughout this document.</aside>
<aside class="footnote brackets" id="rejectgensyn" role="doc-footnote">
<dt class="label" id="rejectgensyn">[<a href="#id15">2</a>]</dt>
<dd><a class="reference external" href="https://mail.python.org/pipermail/python-3000/2006-May/002103.html">https://mail.python.org/pipermail/python-3000/2006-May/002103.html</a></aside>
<aside class="footnote brackets" id="typecheck" role="doc-footnote">
<dt class="label" id="typecheck">[<a href="#id4">3</a>]</dt>
<dd><a class="reference external" href="http://web.archive.org/web/20070730120117/http://oakwinter.com/code/typecheck/">http://web.archive.org/web/20070730120117/http://oakwinter.com/code/typecheck/</a></aside>
<aside class="footnote brackets" id="maxime" role="doc-footnote">
<dt class="label" id="maxime">[<a href="#id5">4</a>]</dt>
<dd><a class="reference external" href="http://web.archive.org/web/20070603221429/http://maxrepo.info/">http://web.archive.org/web/20070603221429/http://maxrepo.info/</a></aside>
<aside class="footnote brackets" id="threadgen" role="doc-footnote">
<dt class="label" id="threadgen">[<a href="#id16">5</a>]</dt>
<dd><a class="reference external" href="https://mail.python.org/pipermail/python-3000/2006-May/002091.html">https://mail.python.org/pipermail/python-3000/2006-May/002091.html</a></aside>
<aside class="footnote brackets" id="threadhof" role="doc-footnote">
<dt class="label" id="threadhof">[<a href="#id17">6</a>]</dt>
<dd><a class="reference external" href="https://mail.python.org/pipermail/python-3000/2006-May/001972.html">https://mail.python.org/pipermail/python-3000/2006-May/001972.html</a></aside>
<aside class="footnote brackets" id="threadimmlist" role="doc-footnote">
<dt class="label" id="threadimmlist">[<a href="#id18">7</a>]</dt>
<dd><a class="reference external" href="https://mail.python.org/pipermail/python-3000/2006-May/002105.html">https://mail.python.org/pipermail/python-3000/2006-May/002105.html</a></aside>
<aside class="footnote brackets" id="threadmixing" role="doc-footnote">
<dt class="label" id="threadmixing">[<a href="#id19">8</a>]</dt>
<dd><a class="reference external" href="https://mail.python.org/pipermail/python-3000/2006-May/002209.html">https://mail.python.org/pipermail/python-3000/2006-May/002209.html</a></aside>
<aside class="footnote brackets" id="emphasistpls" role="doc-footnote">
<dt class="label" id="emphasistpls">[<a href="#id20">9</a>]</dt>
<dd><a class="reference external" href="https://mail.python.org/pipermail/python-3000/2006-June/002438.html">https://mail.python.org/pipermail/python-3000/2006-June/002438.html</a></aside>
<aside class="footnote brackets" id="id24" role="doc-footnote">
<dt class="label" id="id24">[<a href="#id14">10</a>]</dt>
<dd><a class="reference external" href="http://svn.python.org/view?rev=53170&amp;view=rev">http://svn.python.org/view?rev=53170&amp;view=rev</a></aside>
<aside class="footnote brackets" id="grammar" role="doc-footnote">
<dt class="label" id="grammar">[<a href="#id2">11</a>]</dt>
<dd><a class="reference external" href="http://docs.python.org/reference/compound_stmts.html#function-definitions">http://docs.python.org/reference/compound_stmts.html#function-definitions</a></aside>
<aside class="footnote brackets" id="id25" role="doc-footnote">
<dt class="label" id="id25">[<a href="#id3">12</a>]</dt>
<dd><a class="reference external" href="https://mail.python.org/pipermail/python-3000/2006-May/001613.html">https://mail.python.org/pipermail/python-3000/2006-May/001613.html</a></aside>
<aside class="footnote brackets" id="interop0" role="doc-footnote">
<dt class="label" id="interop0">[<a href="#id21">13</a>]</dt>
<dd><a class="reference external" href="https://mail.python.org/pipermail/python-3000/2006-August/002895.html">https://mail.python.org/pipermail/python-3000/2006-August/002895.html</a></aside>
<aside class="footnote brackets" id="interop1" role="doc-footnote">
<dt class="label" id="interop1">[<a href="#id22">14</a>]</dt>
<dd><a class="reference external" href="https://mail.python.org/pipermail/python-ideas/2007-January/000032.html">https://mail.python.org/pipermail/python-ideas/2007-January/000032.html</a></aside>
<aside class="footnote brackets" id="interop2" role="doc-footnote">
<dt class="label" id="interop2">[<a href="#id23">15</a>]</dt>
<dd><a class="reference external" href="https://mail.python.org/pipermail/python-list/2006-December/420645.html">https://mail.python.org/pipermail/python-list/2006-December/420645.html</a></aside>
<aside class="footnote brackets" id="idle" role="doc-footnote">
<dt class="label" id="idle">[<a href="#id6">16</a>]</dt>
<dd><a class="reference external" href="http://www.python.org/idle/doc/idle2.html#Tips">http://www.python.org/idle/doc/idle2.html#Tips</a></aside>
<aside class="footnote brackets" id="jython" role="doc-footnote">
<dt class="label" id="jython">[<a href="#id8">17</a>]</dt>
<dd><a class="reference external" href="http://www.jython.org/Project/index.html">http://www.jython.org/Project/index.html</a></aside>
<aside class="footnote brackets" id="ironpython" role="doc-footnote">
<dt class="label" id="ironpython">[<a href="#id9">18</a>]</dt>
<dd><a class="reference external" href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython">http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython</a></aside>
<aside class="footnote brackets" id="pyprotocols" role="doc-footnote">
<dt class="label" id="pyprotocols">[<a href="#id11">19</a>]</dt>
<dd><a class="reference external" href="http://peak.telecommunity.com/PyProtocols.html">http://peak.telecommunity.com/PyProtocols.html</a></aside>
<aside class="footnote brackets" id="adaptationpost" role="doc-footnote">
<dt class="label" id="adaptationpost">[<a href="#id10">20</a>]</dt>
<dd><a class="reference external" href="http://www.artima.com/weblogs/viewpost.jsp?thread=155123">http://www.artima.com/weblogs/viewpost.jsp?thread=155123</a></aside>
<aside class="footnote brackets" id="scaling" role="doc-footnote">
<dt class="label" id="scaling">[<a href="#id7">21</a>]</dt>
<dd><a class="reference external" href="http://www-128.ibm.com/developerworks/library/l-cppeak2/">http://www-128.ibm.com/developerworks/library/l-cppeak2/</a></aside>
<aside class="footnote brackets" id="rpyc" role="doc-footnote">
<dt class="label" id="rpyc">[<a href="#id12">22</a>]</dt>
<dd><a class="reference external" href="http://rpyc.wikispaces.com/">http://rpyc.wikispaces.com/</a></aside>
<aside class="footnote brackets" id="pydoc" role="doc-footnote">
<dt class="label" id="pydoc">[<a href="#id13">23</a>]</dt>
<dd><a class="reference external" href="http://docs.python.org/library/pydoc.html">http://docs.python.org/library/pydoc.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-3107.rst">https://github.com/python/peps/blob/main/peps/pep-3107.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-3107.rst">2023-09-09 17:39:29 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#fundamentals-of-function-annotations">Fundamentals of Function Annotations</a></li>
<li><a class="reference internal" href="#syntax">Syntax</a><ul>
<li><a class="reference internal" href="#parameters">Parameters</a></li>
<li><a class="reference internal" href="#return-values">Return Values</a></li>
<li><a class="reference internal" href="#lambda">Lambda</a></li>
</ul>
</li>
<li><a class="reference internal" href="#accessing-function-annotations">Accessing Function Annotations</a></li>
<li><a class="reference internal" href="#use-cases">Use Cases</a></li>
<li><a class="reference internal" href="#standard-library">Standard Library</a><ul>
<li><a class="reference internal" href="#pydoc-and-inspect">pydoc and inspect</a></li>
</ul>
</li>
<li><a class="reference internal" href="#relation-to-other-peps">Relation to Other PEPs</a><ul>
<li><a class="reference internal" href="#function-signature-objects-pep-362">Function Signature Objects (PEP 362)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation">Implementation</a></li>
<li><a class="reference internal" href="#rejected-proposals">Rejected Proposals</a></li>
<li><a class="reference internal" href="#references-and-footnotes">References and Footnotes</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-3107.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>