update from the authors

This commit is contained in:
David Goodger 2007-01-04 18:19:54 +00:00
parent 860fb91f25
commit b72af864fa
1 changed files with 90 additions and 58 deletions

View File

@ -24,9 +24,8 @@ Rationale
========= =========
Because Python's 2.x series lacks a standard way of annotating a Because Python's 2.x series lacks a standard way of annotating a
function's parameters and return values (e.g., with information about function's parameters and return values, a variety of tools
what type a function's return value should be), a variety of tools and libraries have appeared to fill this gap. Some
and libraries have appeared to fill this gap [#tailexamp]_. Some
utilise the decorators introduced in "PEP 318", while others parse a utilise the decorators introduced in "PEP 318", while others parse a
function's docstring, looking for annotations there. function's docstring, looking for annotations there.
@ -81,14 +80,6 @@ what annotations are and are not:
any kind of standard semantics, even for the built-in types. any kind of standard semantics, even for the built-in types.
This work will be left to third-party libraries. 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 Syntax
====== ======
@ -97,11 +88,9 @@ Parameters
---------- ----------
Annotations for parameters take the form of optional expressions that Annotations for parameters take the form of optional expressions that
follow the parameter name. This example indicates that parameters follow the parameter name::
'a' and 'c' should both be an ``int``, while parameter 'b' should
be a ``dict``::
def foo(a: int, b: dict, c: int = 5): def foo(a: expression, b: expression = 5):
... ...
In pseudo-grammar, parameters now look like ``identifier [: In pseudo-grammar, parameters now look like ``identifier [:
@ -109,26 +98,23 @@ expression] [= expression]``. That is, annotations always precede a
parameter's default value and both annotations and default values are parameter's default value and both annotations and default values are
optional. Just like how equal signs are used to indicate a default optional. Just like how equal signs are used to indicate a default
value, colons are used to mark annotations. All annotation value, colons are used to mark annotations. All annotation
expressions are evaluated when the function definition is executed. expressions are evaluated when the function definition is executed,
just like default values.
Annotations for excess parameters (i.e., ``*args`` and ``**kwargs``) Annotations for excess parameters (i.e., ``*args`` and ``**kwargs``)
are indicated similarly. In the following function definition, are indicated similarly::
``*args`` is flagged as a tuple of ``int``, and ``**kwargs`` is
marked as a dict whose keys are strings and whose values are of type
``str``::
def foo(*args: int, **kwargs: str): def foo(*args: expression, **kwargs: expression):
... ...
Note that, depending on what annotation-interpreting library you're Annotations for nested parameters always follow the name of the
using, the following might also be a valid spelling of the above:: parameter, not the last parenthesis. Annotating all parameters of a
nested parameter is not required::
def foo(*args: [int], **kwargs: {str: str}): def foo((x1, y1: expression),
(x2: expression, y2: expression)=(None, None)):
... ...
Only the first, however, has the BDFL's blessing [#blessedexcess]_ as
the One Obvious Way.
Return Values Return Values
------------- -------------
@ -136,11 +122,11 @@ Return Values
The examples thus far have omitted examples of how to annotate the The examples thus far have omitted examples of how to annotate the
type of a function's return value. This is done like so:: type of a function's return value. This is done like so::
def sum(*args: int) -> int: def sum() -> expression:
... ...
The parameter list can now be followed by a literal ``->`` and a That is, the parameter list can now be followed by a literal ``->``
Python expression. Like the annotations for parameters, this and a Python expression. Like the annotations for parameters, this
expression will be evaluated when the function definition is executed. expression will be evaluated when the function definition is executed.
The grammar for function definitions [#grammar]_ is now:: The grammar for function definitions [#grammar]_ is now::
@ -184,7 +170,7 @@ for the function's return value.
For example, the following annotation:: For example, the following annotation::
def foo(a: 'x', b: 5 + 6, c: list) -> str: def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
... ...
would result in a ``func_annotation`` mapping of :: would result in a ``func_annotation`` mapping of ::
@ -192,7 +178,7 @@ would result in a ``func_annotation`` mapping of ::
{'a': 'x', {'a': 'x',
'b': 11, 'b': 11,
'c': list, 'c': list,
'return': str} 'return': 9}
The ``return`` key was chosen because it cannot conflict with the name The ``return`` key was chosen because it cannot conflict with the name
of a parameter; any attempt to use ``return`` as a parameter name of a parameter; any attempt to use ``return`` as a parameter name
@ -202,6 +188,29 @@ would result in a ``SyntaxError``.
annotations on the function. ``func_annotations`` is always an empty annotations on the function. ``func_annotations`` is always an empty
dictionary for functions created from ``lambda`` expressions. dictionary for functions created from ``lambda`` expressions.
Use Cases
=========
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.
* Providing typing information
+ Type checking ([#typecheck]_, [#maxime]_)
+ Let IDEs show what types a function expects and returns ([#idle]_)
+ Function overloading / generic functions ([#scaling]_)
+ Foreign-language bridges ([#jython]_, [#ironpython]_)
+ Adaptation ([#adaptationpost]_, [#pyprotocols]_)
+ Predicate logic functions
+ Database query mapping
+ RPC parameter marshaling ([#rpyc]_)
* Other information
+ Documentation for parameters and return values ([#pydoc]_)
Standard Library Standard Library
================ ================
@ -246,7 +255,15 @@ Rejected Proposals
+ Despite considerable discussion about a standard type + Despite considerable discussion about a standard type
parameterisation syntax, it was decided that this should also be parameterisation syntax, it was decided that this should also be
left to third-party libraries. ([#threadimmlist]_, left to third-party libraries. ([#threadimmlist]_,
[#threadmixing]_, [#emphasistpls]_) [#threadmixing]_, [#emphasistpls]_).
+ 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. ([#interop0]_, [#interop1]_,
[#interop2]_).
References and Footnotes References and Footnotes
@ -255,20 +272,13 @@ References and Footnotes
.. [#functerm] Unless specifically stated, "function" is generally .. [#functerm] Unless specifically stated, "function" is generally
used as a synonym for "callable" throughout this document. 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] .. [#rejectgensyn]
http://mail.python.org/pipermail/python-3000/2006-May/002103.html http://mail.python.org/pipermail/python-3000/2006-May/002103.html
.. _typecheck: .. [#typecheck]
http://oakwinter.com/code/typecheck/ http://oakwinter.com/code/typecheck/
.. _Maxime Bourget's own typechecker: .. [#maxime]
http://maxrepo.info/taxonomy/term/3,6/all http://maxrepo.info/taxonomy/term/3,6/all
.. [#threadgen] .. [#threadgen]
@ -289,15 +299,6 @@ References and Footnotes
.. [#implementation] .. [#implementation]
http://python.org/sf/1607548 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] .. [#grammar]
http://www.python.org/doc/current/ref/function.html http://www.python.org/doc/current/ref/function.html
@ -307,6 +308,38 @@ References and Footnotes
.. [#pep-362] .. [#pep-362]
http://www.python.org/dev/peps/pep-0362/ http://www.python.org/dev/peps/pep-0362/
.. [#interop0]
http://mail.python.org/pipermail/python-3000/2006-August/002895.html
.. [#interop1]
http://mail.python.org/pipermail/python-ideas/2007-January/000032.html
.. [#interop2]
http://mail.python.org/pipermail/python-list/2006-December/420645.html
.. [#idle]
http://www.python.org/idle/doc/idle2.html#Tips
.. [#jython]
http://www.jython.org/Project/index.html
.. [#ironpython]
http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython
.. [#pyprotocols]
http://peak.telecommunity.com/PyProtocols.html
.. [#adaptationpost]
http://www.artima.com/weblogs/viewpost.jsp?thread=155123
.. [#scaling]
http://www-128.ibm.com/developerworks/library/l-cppeak2/
.. [#rpyc]
http://rpyc.wikispaces.com/
.. [#pydoc]
http://docs.python.org/lib/module-pydoc.html
Copyright Copyright
@ -323,4 +356,3 @@ This document has been placed in the public domain.
fill-column: 70 fill-column: 70
coding: utf-8 coding: utf-8
End: End: