[Python-checkins] r53144 - peps/trunk/pep-0000.txt peps/trunk/pep-3107.txt

david.goodger python-checkins at python.org
Fri Dec 22 16:46:01 CET 2006


Author: david.goodger
Date: Fri Dec 22 16:46:01 2006
New Revision: 53144

Added:
   peps/trunk/pep-3107.txt   (contents, props changed)
Modified:
   peps/trunk/pep-0000.txt
Log:
added PEP 3107, Function Annotations, by Winter & Lownds

Modified: peps/trunk/pep-0000.txt
==============================================================================
--- peps/trunk/pep-0000.txt	(original)
+++ peps/trunk/pep-0000.txt	Fri Dec 22 16:46:01 2006
@@ -105,6 +105,7 @@
  S  3104  Access to Names in Outer Scopes              Yee
  S  3105  Make print a function                        Brandl
  S  3106  Revamping dict.keys(), .values() and .items() GvR
+ S  3107  Function Annotations                         Winter, Lownds
 
  Finished PEPs (done, implemented in Subversion)
 
@@ -442,7 +443,8 @@
  S  3103  A Switch/Case Statement                      GvR
  S  3104  Access to Names in Outer Scopes              Yee
  S  3105  Make print a function                        Brandl
- S  3106  Revamping dict.keys(), .values() and .items() GvR
+ S  3106  Revamping dict.keys(), .values() and .items()  GvR
+ S  3107  Function Annotations                         Winter, Lownds
 
 Key
 
@@ -513,6 +515,7 @@
     Lielens, Gregory         gregory.lielens at fft.be
     Lindqvist, Björn         bjourne at gmail.com
     von Loewis, Martin       loewis at informatik.hu-berlin.de
+    Lownds, Tony             tony at pagedna.com
     Martelli, Alex           aleax at aleax.it
     McClelland, Andrew       eternalsquire at comcast.net
     McMillan, Gordon         gmcm at hypernet.com
@@ -549,6 +552,7 @@
     Way, Terence             terry at wayforward.net
     Wells, Cliff             LogiplexSoftware at earthlink.net
     Wilson, Greg             gvwilson at ddj.com
+    Winter, Collin           collinw at gmail.com
     Wouters, Thomas          thomas at xs4all.net
     Yee, Ka-Ping             ping at zesty.ca
     Zadka, Moshe             moshez at zadka.site.co.il

Added: peps/trunk/pep-3107.txt
==============================================================================
--- (empty file)
+++ peps/trunk/pep-3107.txt	Fri Dec 22 16:46:01 2006
@@ -0,0 +1,294 @@
+PEP: 3107
+Title: Function Annotations
+Version: $Revision$
+Last-Modified: $Date$
+Author: Collin Winter <collinw at gmail.com>,
+        Tony Lownds <tony at pagedna.com>
+Status: Draft
+Type: Standards Track
+Requires: 362
+Content-Type: text/x-rst
+Created: 2-Dec-2006
+Python-Version: 3.0
+Post-History:
+
+
+Abstract
+========
+
+This PEP introduces a syntax for adding arbitrary metadata annotations
+to Python functions [#functerm]_.
+
+
+Rationale
+=========
+
+Because Python's 2.x series lacks a standard way of annotating a
+function's parameters and return values (e.g., with information about
+a what type a function's return value should be), a variety of tools
+and libraries have appeared to fill this gap [#tailexamp]_.  Some
+utilise the decorators introduced in "PEP 318", while others parse a
+function's docstring, looking for annotations there.
+
+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.
+
+
+Fundamentals of Function Annotations
+====================================
+
+Before launching into a discussion of the precise ins and outs of
+Python 3.0's function annotations, let's first talk broadly about
+what annotations are and are not:
+
+1. Function annotations, both for parameters and return values, are
+   completely optional.
+
+2. Function annotations are nothing more than a way of associating
+   arbitrary Python expressions with various parts of a function at
+   compile-time.
+
+   By itself, Python does not attach any particular meaning or
+   significance to annotations.  Left to its own, Python simply makes
+   these expressions available as the values in the
+   ``__signature__.annotations`` mapping described in `Accessing
+   Function Annotations`_ below.
+
+   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 function's annotations.  For
+   example, one library might use string-based annotations to provide
+   improved help messages, like so::
+
+        def compile(source: "something compilable",
+                    filename: "where the compilable thing comes from",
+                    mode: "is this a single statement or a suite?"):
+            ...
+
+   Another library might be used to provide typechecking for Python
+   functions and methods.  This library could use annotations to
+   indicate the function's expected input and return types, possibly
+   something like ::
+
+        def haul(item: Haulable, *vargs: PackAnimal) -> Distance:
+            ...
+
+   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.
+
+3. 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.
+
+   There is no worry that these libraries will assign semantics at
+   random, or that a variety of libraries will appear, each with
+   varying semantics and interpretations of what, say, a tuple of
+   strings means. The difficulty inherent in writing annotation
+   interpreting libraries will keep their number low and their
+   authorship in the hands of people who, frankly, know what they're
+   doing.
+
+
+Syntax
+======
+
+Parameters
+----------
+
+Annotations for parameters take the form of optional expressions that
+follow the parameter name.  This example indicates that parameters 'a'
+and 'c' should both be a ``Number``, while parameter 'b' should both
+be a ``Mapping``::
+
+    def foo(a: Number, b: Mapping, c: Number = 5):
+        ...
+        
+(Number, Mapping and Sequence are used thoughout this PEP and
+represent the standard `numeric`_, `mapping`_ and `sequence
+protocols`_.)
+
+In pseudo-grammar, parameters now look like ``identifier [:
+expression] [= expression]``.  That is, type annotations always
+precede a parameter's default value and both type 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.
+
+Annotations for excess parameters (i.e., ``*args`` and ``**kwargs``)
+are indicated similarly.  In the following function definition,
+``*args`` is flagged as a list of ``Number``, and ``**kwargs`` is
+marked as a dict whose keys are strings and whose values are of type
+``Sequence``. ::
+
+    def foo(*args: Number, **kwargs: Sequence):
+        ...
+
+Note that, depending on what annotation-interpreting library you're
+using, the following might also be a valid spelling of the above::
+
+    def foo(*args: [Number], **kwargs: {str: Sequence}):
+        ...
+
+Only the first, however, has the BDFL's blessing [#blessedexcess]_ as
+the One Obvious Way.
+
+
+Return Values
+-------------
+
+The examples thus far have omitted examples of how to annotate the
+type of a function's return value.  This is done like so::
+
+    def sum(*args: Number) -> Number:
+        ...
+
+The parameter list can now be followed by a literal ``->`` and a
+Python expression.  Like the annotations for parameters, this
+expression will be evaluated when the function definition is executed.
+
+The grammar for function definitions [#grammar]_ is now something like
+::
+
+    funcdef         ::=     [decorators] "def" funcname "("
+                            [parameter_list] ")" ["->" expression] ":" suite
+    decorators      ::=     decorator+
+    decorator       ::=     "@" dotted_name ["(" [argument_list
+                                                  [","]] ")"] NEWLINE
+    dotted_name     ::=     identifier ("." identifier)*
+    parameter_list  ::=     (defparameter ",")*
+            (  "*" identifier [":" expression]
+                [, "**" identifier [":" expression] ]
+             | "**" identifier [":" expression]
+             | defparameter [","] )
+    defparameter    ::=     parameter [":" expression] ["=" expression]
+    sublist         ::=     parameter ("," parameter)* [","]
+    parameter       ::=     identifier | "(" sublist ")"
+    funcname        ::=     identifier
+
+
+Accessing Function Annotations
+==============================
+
+Once compiled, a function's annotations are available via the
+function's ``__signature__`` attribute, introduced by PEP 362.
+Signature objects include an attribute just for annotations,
+appropriately called ``annotations``.  This attribute is a dictionary,
+mapping parameter names to an object representing the evaluated
+annotation expression.
+
+There is a special key in the ``annotations`` mapping, ``"return"``.
+This key is present only if an annotation was supplied for the
+function's return value.
+
+For example, the following annotation::
+
+    def foo(a: Number, b: 5 + 6, c: list) -> String:
+        ...
+
+would result in a ``__signature__.annotations`` mapping of ::
+
+    {'a': Number,
+     'b': 11,
+     'c': list,
+     'return': String}
+
+The ``return`` key was chosen because it cannot conflict with the name
+of a parameter; any attempt to use ``return`` as a parameter name
+would result in a ``SyntaxError``.
+
+
+Implementation
+==============
+
+A sample implementation has been provided [#implementation]_ by Tony
+Lownds.
+
+
+Rejected Proposals
+==================
+
++ The BDFL rejected the author's idea for a special syntax for adding
+  annotations to generators as being "too ugly" [#rejectgensyn]_.
+
++ Though discussed early on ([#threadgen]_, [#threadhof]_), 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.
+
++ Despite considerable discussion about a standard type
+  parameterisation syntax, it was decided that this should also be
+  left to third-party libraries. ([#threadimmlist]_, [#threadmixing]_,
+  [#emphasistpls]_)
+
+
+References and Footnotes
+========================
+
+.. [#functerm] Unless specifically stated, "function" is generally
+   used as a synonym for "callable" throughout this document.
+
+.. [#tailexamp] The author's typecheck_ library makes use of
+   decorators, while `Maxime Bourget's own typechecker`_ utilises
+   parsed docstrings.
+
+.. [#blessedexcess]
+   http://mail.python.org/pipermail/python-3000/2006-May/002173.html
+
+.. [#rejectgensyn]
+   http://mail.python.org/pipermail/python-3000/2006-May/002103.html
+
+.. _typecheck:
+   http://oakwinter.com/code/typecheck/
+
+.. _Maxime Bourget's own typechecker:
+   http://maxrepo.info/taxonomy/term/3,6/all
+
+.. [#threadgen]
+   http://mail.python.org/pipermail/python-3000/2006-May/002091.html
+
+.. [#threadhof]
+   http://mail.python.org/pipermail/python-3000/2006-May/001972.html
+
+.. [#threadimmlist]
+   http://mail.python.org/pipermail/python-3000/2006-May/002105.html
+
+.. [#threadmixing]
+   http://mail.python.org/pipermail/python-3000/2006-May/002209.html
+
+.. [#emphasistpls]
+   http://mail.python.org/pipermail/python-3000/2006-June/002438.html
+
+.. [#implementation]
+   http://python.org/sf/1607548
+   
+.. _numeric:
+   http://docs.python.org/lib/typesnumeric.html
+   
+.. _mapping:
+   http://docs.python.org/lib/typesmapping.html
+   
+.. _sequence protocols:
+   http://docs.python.org/lib/typesseq.html
+   
+.. [#grammar]
+   http://www.python.org/doc/current/ref/function.html
+
+
+Copyright
+=========
+
+This document has been placed in the public domain.
+
+
+..
+   Local Variables:
+   mode: indented-text
+   indent-tabs-mode: nil
+   sentence-end-double-space: t
+   fill-column: 70
+   coding: utf-8
+   End:


More information about the Python-checkins mailing list