update from the authors
This commit is contained in:
parent
860fb91f25
commit
b72af864fa
136
pep-3107.txt
136
pep-3107.txt
|
@ -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:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue