update from the authors
This commit is contained in:
parent
860fb91f25
commit
b72af864fa
148
pep-3107.txt
148
pep-3107.txt
|
@ -24,9 +24,8 @@ 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
|
||||
what type a function's return value should be), a variety of tools
|
||||
and libraries have appeared to fill this gap [#tailexamp]_. Some
|
||||
function's parameters and return values, a variety of tools
|
||||
and libraries have appeared to fill this gap. Some
|
||||
utilise the decorators introduced in "PEP 318", while others parse a
|
||||
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.
|
||||
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
|
||||
======
|
||||
|
@ -97,11 +88,9 @@ 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 an ``int``, while parameter 'b' should
|
||||
be a ``dict``::
|
||||
follow the parameter name::
|
||||
|
||||
def foo(a: int, b: dict, c: int = 5):
|
||||
def foo(a: expression, b: expression = 5):
|
||||
...
|
||||
|
||||
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
|
||||
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.
|
||||
expressions are evaluated when the function definition is executed,
|
||||
just like default values.
|
||||
|
||||
Annotations for excess parameters (i.e., ``*args`` and ``**kwargs``)
|
||||
are indicated similarly. In the following function definition,
|
||||
``*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``::
|
||||
are indicated similarly::
|
||||
|
||||
def foo(*args: int, **kwargs: str):
|
||||
def foo(*args: expression, **kwargs: expression):
|
||||
...
|
||||
|
||||
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::
|
||||
|
||||
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: [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
|
||||
-------------
|
||||
|
@ -136,11 +122,11 @@ 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: int) -> int:
|
||||
def sum() -> expression:
|
||||
...
|
||||
|
||||
The parameter list can now be followed by a literal ``->`` and a
|
||||
Python expression. Like the annotations for parameters, this
|
||||
That is, 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::
|
||||
|
@ -162,7 +148,7 @@ Lambda
|
|||
|
||||
``lambda``'s syntax does not support annotations. The syntax of
|
||||
``lambda`` could be changed to support annotations, by requiring
|
||||
parentheses around the parameter list. However it was decided
|
||||
parentheses around the parameter list. However it was decided
|
||||
[#lambda]_ not to make this change because:
|
||||
|
||||
1. It would be an incompatible change.
|
||||
|
@ -179,12 +165,12 @@ a dictionary, mapping parameter names to an object representing
|
|||
the evaluated annotation expression
|
||||
|
||||
There is a special key in the ``func_annotations`` mapping,
|
||||
``"return"``. This key is present only if an annotation was supplied
|
||||
``"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: '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 ::
|
||||
|
@ -192,16 +178,39 @@ would result in a ``func_annotation`` mapping of ::
|
|||
{'a': 'x',
|
||||
'b': 11,
|
||||
'c': list,
|
||||
'return': str}
|
||||
'return': 9}
|
||||
|
||||
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``.
|
||||
|
||||
``func_annotations`` is an empty dictionary if no there are no
|
||||
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.
|
||||
|
||||
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
|
||||
================
|
||||
|
@ -210,7 +219,7 @@ pydoc and inspect
|
|||
-----------------
|
||||
|
||||
The ``pydoc`` module should display the function annotations when
|
||||
displaying help for a function. The ``inspect`` module should change
|
||||
displaying help for a function. The ``inspect`` module should change
|
||||
to support annotations.
|
||||
|
||||
|
||||
|
@ -245,8 +254,16 @@ Rejected Proposals
|
|||
|
||||
+ 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]_)
|
||||
left to third-party libraries. ([#threadimmlist]_,
|
||||
[#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
|
||||
|
@ -255,20 +272,13 @@ 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:
|
||||
.. [#typecheck]
|
||||
http://oakwinter.com/code/typecheck/
|
||||
|
||||
.. _Maxime Bourget's own typechecker:
|
||||
.. [#maxime]
|
||||
http://maxrepo.info/taxonomy/term/3,6/all
|
||||
|
||||
.. [#threadgen]
|
||||
|
@ -289,15 +299,6 @@ References and Footnotes
|
|||
.. [#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
|
||||
|
||||
|
@ -306,7 +307,39 @@ References and Footnotes
|
|||
|
||||
.. [#pep-362]
|
||||
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
|
||||
|
@ -323,4 +356,3 @@ This document has been placed in the public domain.
|
|||
fill-column: 70
|
||||
coding: utf-8
|
||||
End:
|
||||
|
||||
|
|
Loading…
Reference in New Issue