[Python-checkins] peps: Update rules for function annotations in the light of PEP 484.

guido.van.rossum python-checkins at python.org
Tue Jan 5 13:33:38 EST 2016


https://hg.python.org/peps/rev/3f6f9839bbe1
changeset:   6147:3f6f9839bbe1
user:        Guido van Rossum <guido at python.org>
date:        Tue Jan 05 10:33:30 2016 -0800
summary:
  Update rules for function annotations in the light of PEP 484.

files:
  pep-0008.txt |  130 +++++++++++++++++++++++---------------
  1 files changed, 77 insertions(+), 53 deletions(-)


diff --git a/pep-0008.txt b/pep-0008.txt
--- a/pep-0008.txt
+++ b/pep-0008.txt
@@ -520,22 +520,33 @@
       def complex(real, imag = 0.0):
           return magic(r = real, i = imag)
 
-- Do use spaces around the ``=`` sign  of an annotated function definition.
-  Additionally, use a single space after the ``:``, as well as a single space
-  on either side of the ``->`` sign representing an annotated return value.
+- Function annotations should use the normal rules for colons and
+  always have spaces around the ``->`` arrow if present.  (See
+  `Function Annotations`_ below for more about function annotations.)
 
   Yes::
 
-      def munge(input: AnyStr):
-      def munge(sep: AnyStr = None):
-      def munge() -> AnyStr:
-      def munge(input: AnyStr, sep: AnyStr = None, limit=1000):
+      def munge(input: AnyStr): ...
+      def munge() -> AnyStr: ...
 
   No::
 
-      def munge(input: AnyStr=None):
-      def munge(input:AnyStr):
-      def munge(input: AnyStr)->PosInt:
+      def munge(input:AnyStr): ...
+      def munge()->PosInt: ...
+
+- When combining an argument annotation with a default value, use
+  spaces around the ``=`` sign (but only for those arguments that have
+  both an annotation and a default).
+
+  Yes::
+
+      def munge(sep: AnyStr = None): ...
+      def munge(input: AnyStr, sep: AnyStr = None, limit=1000): ...
+
+  No::
+
+      def munge(input: AnyStr=None): ...
+      def munge(input: AnyStr, limit = 1000): ...
 
 - Compound statements (multiple statements on the same line) are
   generally discouraged.
@@ -1233,60 +1244,65 @@
       No:    if greeting == True:
       Worse: if greeting is True:
 
-- The Python standard library will not use function annotations as
-  that would result in a premature commitment to a particular
-  annotation style.  Instead, the annotations are left for users to
-  discover and experiment with useful annotation styles.
+Function Annotations
+--------------------
 
-  It is recommended that third party experiments with annotations use an
-  associated decorator to indicate how the annotation should be
-  interpreted.
+With the acceptance of PEP 484, the style rules for function
+annotations are changing.
 
-  Early core developer attempts to use function annotations revealed
-  inconsistent, ad-hoc annotation styles.  For example:
+- In order to be forward compatible, function annotations in Python 3
+  code should preferably use PEP 484 syntax.  (There are some
+  formatting recommendations for annotations in the previous section.)
 
-  * ``[str]`` was ambiguous as to whether it represented a list of
-    strings or a value that could be either *str* or *None*.
+- The experimentation with annotation styles that was recommended
+  previously in this PEP is no longer encouraged.
 
-  * The notation ``open(file:(str,bytes))`` was used for a value that
-    could be either *bytes* or *str* rather than a 2-tuple containing
-    a *str* value followed by a *bytes* value.
+- However, experiments within the rules of PEP 484 are now encouraged.
+  For example, marking up a large library with PEP 484 style type
+  annotations, reviewing how easy it was to add those annotations, and
+  observing whether their presence increases code understandabilty.
 
-  * The annotation ``seek(whence:int)`` exhibited a mix of
-    over-specification and under-specification: *int* is too
-    restrictive (anything with ``__index__`` would be allowed) and it
-    is not restrictive enough (only the values 0, 1, and 2 are
-    allowed).  Likewise, the annotation ``write(b: bytes)`` was also
-    too restrictive (anything supporting the buffer protocol would be
-    allowed).
+- The Python standard library should be conservative in adopting such
+  annotations, but their use is allowed for new code and for big
+  refactorings.
 
-  * Annotations such as ``read1(n: int=None)`` were self-contradictory
-    since *None* is not an *int*.  Annotations such as
-    ``source_path(self, fullname:str) -> object`` were confusing about
-    what the return type should be.
+- For code that wants to make a different use of function annotations
+  it is recommended to put a comment of the form::
 
-  * In addition to the above, annotations were inconsistent in the use
-    of concrete types versus abstract types:  *int* versus *Integral*
-    and set/frozenset versus MutableSet/Set.
+    # type: ignore
 
-  * Some annotations in the abstract base classes were incorrect
-    specifications.  For example, set-to-set operations require
-    *other* to be another instance of *Set* rather than just an
-    *Iterable*.
+  near the top of the file; this tells type checker to ignore all
+  annotations.  (More fine-grained ways of disabling complaints from
+  type checkers can be found in PEP 484.)
 
-  * A further issue was that annotations become part of the
-    specification but weren't being tested.
+- Like linters, type checkers are optional, separate tools.  Python
+  interpreters by default should not issue any messages due to type
+  checking and should not alter their behavior based on annotations.
 
-  * In most cases, the docstrings already included the type
-    specifications and did so with greater clarity than the function
-    annotations.  In the remaining cases, the docstrings were improved
-    once the annotations were removed.
+- Users who don't want to use type checkers are free to ignore them.
+  However, it is expected that users of library packages may want to
+  run type checkers over those library packages.  For this purpose PEP
+  484 recommends the use of stub files: .pyi files that are read by
+  the type checker in preference of the corresponding .py files.  Stub
+  files can be distributed with a library, or separately (with the
+  library author's permission) through the _typeshed_ repo [5]_.
 
-  * The observed function annotations were too ad-hoc and inconsistent
-    to work with a coherent system of automatic type checking or
-    argument validation.  Leaving these annotations in the code would
-    have made it more difficult to make changes later so that
-    automated utilities could be supported.
+- For code that needs to be backwards compatible, function annotations
+  can be added in the form of comments.  Basically, this Python 3 annotation::
+
+    def embezzle(self, account: str, funds: int = 1000000, **fake_receipts: str) -> None:
+        """Embezzle funds from account using fake receipts."""
+        <code goes here>
+
+  is equivalent to the following::
+
+    def embezzle(self, account, funds=1000000, **fake_receipts):
+        # type: (str, int, **str) -> None
+        """Embezzle funds from account using fake receipts."""
+        <code goes here>
+
+  The _mypy_ type checker [6]_ currently support this syntax, and other
+  type checkers are encouraged to adopt it.
 
 
 .. rubric:: Footnotes
@@ -1312,6 +1328,14 @@
 .. [4] PEP 8 modernisation, July 2013
    http://bugs.python.org/issue18472
 
+.. [5] Typeshed repo
+   https://github.com/python/typeshed
+
+.. [6] mypy type checker
+   http://mypy-lang.org
+   https://github.com/JukkaL/mypy
+
+
 
 Copyright
 =========

-- 
Repository URL: https://hg.python.org/peps


More information about the Python-checkins mailing list