8000 String annotations [PEP 563] (#4390) · python/cpython@95e4d58 · GitHub
[go: up one dir, main page]

Skip to content

Commit 95e4d58

Browse files
gvanrossumambv
authored andcommitted
String annotations [PEP 563] (#4390)
* Document `from __future__ import annotations` * Provide plumbing and tests for `from __future__ import annotations` * Implement unparsing the AST back to string form This is required for PEP 563 and as such only implements a part of the unparsing process that covers expressions.
1 parent d7773d9 commit 95e4d58

16 files changed

+1477
-30
lines changed

Doc/glossary.rst

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,11 @@ Glossary
372372
may be accessed via the :attr:`__annotations__` special attribute of a
373373
function object.
374374

375-
Python itself does not assign any particular meaning to function
376-
annotations. They are intended to be interpreted by third-party libraries
377-
or tools. See :pep:`3107`, which describes some of their potential uses.
375+
See also the :term:`variable annotation` glossary entry.
376+
377+
Annotations are meant to provide a standard way for programmers to
378+
document types of functions they design. See :pep:`484`, which
379+
describes this functionality.
378380

379381
__future__
380382
A pseudo-module which programmers can use to enable new language features
@@ -1021,10 +1023,11 @@ Glossary
10211023
attribute of a class or module object and can be accessed using
10221024
:func:`typing.get_type_hints`.
10231025

1024-
Python itself does not assign any particular meaning to variable
1025-
annotations. They are intended to be interpreted by third-party libraries
1026-
or type checking tools. See :pep:`526`, :pep:`484` which describe
1027-
some of their potential uses.
1026+
See also the :term:`function annotation` glossary entry.
1027+
1028+
Annotations are meant to provide a standard way for programmers to
1029+
document types of functions they design. See :pep:`484` and :pep:`526`
1030+
which describe this functionality.
10281031

10291032
virtual environment
10301033
A cooperatively isolated runtime environment that allows Python users

Doc/library/__future__.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ language using this mechanism:
9090
| generator_stop | 3.5.0b1 | 3.7 | :pep:`479`: |
9191
| | | | *StopIteration handling inside generators* |
9292
+------------------+-------------+--------------+---------------------------------------------+
93+
| annotations | 3.7.0b1 | 4.0 | :pep:`563`: |
94+
| | | | *Postponed evaluation of annotations* |
95+
+------------------+-------------+--------------+---------------------------------------------+
96+
97+
.. XXX Adding a new entry? Remember to update simple_stmts.rst, too.
9398
9499
95100
.. seealso::

Doc/reference/compound_stmts.rst

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -559,12 +559,14 @@ Parameters may have annotations of the form "``: expression``" following the
559559
parameter name. Any parameter may have an annotation even those of the form
560560
``*identifier`` or ``**identifier``. Functions may have "return" annotation of
561561
the form "``-> expression``" after the parameter list. These annotations can be
562-
any valid Python expression and are evaluated when the function definition is
563-
executed. Annotations may be evaluated in a different order than they appear in
564-
the source code. The presence of annotations does not change the semantics of a
565-
function. The annotation values are available as values of a dictionary keyed
566-
by the parameters' names in the :attr:`__annotations__` attribute of the
567-
function object.
562+
any valid Python expression. The presence of annotations does not change the
563+
semantics of a function. The annotation values are available as values of
564+
a dictionary keyed by the parameters' names in the :attr:`__annotations__`
565+
attribute of the function object. If the ``annotations`` import from
566+
:mod:`__future__` is used, annotations are preserved as strings at runtime which
567+
enables postponed evaluation. Otherwise, they are evaluated when the function
568+
definition is executed. In this case annotations may be evaluated in
569+
a different order than they appear in the source code.
568570

569571
.. index:: pair: lambda; expression
570572

@@ -587,6 +589,17 @@ access the local variables of the function containing the def. See section
587589
:pep:`3107` - Function Annotations
588590
The original specification for function annotations.
589591

592+
:pep:`484` - Type Hints
593+
Definition of a standard meaning for annotations: type hints.
594+
595+
:pep:`526` - Syntax for Variable Annotations
596+
Ability to type hint variable declarations, including class
597+
variables and instance variables
598+
599+
:pep:`563` - Postponed Evaluation of Annotations
600+
Support for forward references within annotations by preserving
601+
annotations in a string form at runtime instead of eager evaluation.
602+
590603

591604
.. _class:
592605

Doc/reference/simple_stmts.rst

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -853,12 +853,15 @@ can appear before a future statement are:
853853
* blank lines, and
854854
* other future statements.
855855

856-
.. XXX change this if future is cleaned out
857-
858-
The features recognized by Python 3.0 are ``absolute_import``, ``division``,
859-
``generators``, ``unicode_literals``, ``print_function``, ``nested_scopes`` and
860-
``with_statement``. They are all redundant because they are always enabled, and
861-
only kept for backwards compatibility.
856+
The only feature in Python 3.7 that requires using the future statement is
857+
``annotations``.
858+
859+
All historical features enabled by the future statement are still recognized
860+
by Python 3. The list includes ``absolute_import``, ``division``,
861+
``generators``, ``generator_stop``, ``unicode_literals``,
862+
``print_function``, ``nested_scopes`` and ``with_statement``. They are
863+
all redundant because they are always enabled, and only kept for
864+
backwards compatibility.
862865

863866
A future statement is recognized and 10000 treated specially at compile time: Changes
864867
to the semantics of core constructs are often implemented by generating

Doc/whatsnew/3.7.rst

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,57 @@ a normal ``__getattr__`` method, except that it will be defined on module
179179
PEP written and implemented by Ivan Levkivskyi
180180

181181

182+
PEP 563: Postponed evaluation of annotations
183+
--------------------------------------------
184+
185+
The advent of type hints in Python uncovered two glaring usability issues
186+
with the functionality of annotations added in :pep:`3107` and refined
187+
further in :pep:`526`:
188+
189+
* annotations could only use names which were already available in the
190+
current scope, in other words they didn't support forward references
191+
of any kind; and
192+
193+
* annotating source code had adverse effects on startup time of Python
194+
programs.
195+
196+
Both of these issues are fixed by postponing the evaluation of
197+
annotations. Instead of compiling code which executes expressions in
198+
annotations at their definition time, the compiler stores the annotation
199+
in a string form equivalent to the AST of the expression in question.
200+
If needed, annotations can be resolved at runtime using
201+
``typing.get_type_hints()``. In the common case where this is not
202+
required, the annotations are cheaper to store (since short strings
203+
are interned by the interpreter) and make startup time faster.
204+
205+
Usability-wise, annotations now support forward references, making the
206+
following syntax valid::
207+
208+
class C:
209+
@classmethod
210+
def from_string(cls, source: str) -> C:
211+
...
212+
213+
def validate_b(self, obj: B) -> bool:
214+
...
215+
216+
class B:
217+
...
218+
219+
Since this change breaks compatibility, the new behavior can be enabled
220+
on a per-module basis in Python 3.7 using a ``__future__`` import, like
221+
this::
222+
223+
from __future__ import annotations
224+
225+
It will become the default in Python 4.0.
226+
227+
.. seealso::
228+
229+
:pep:`563` -- Postponed evaluation of annotations
230+
PEP written and implemented by Łukasz Langa.
231+
232+
182233
PEP 564: Add new time functions with nanosecond resolution
183234
----------------------------------------------------------
184235

Include/ast.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ PyAPI_FUNC(mod_ty) PyAST_FromNodeObject(
1616
PyObject *filename,
1717
PyArena *arena);
1818

19+
#ifndef Py_LIMITED_API
20+
21+
/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */
22+
PyAPI_FUNC(PyObject *) _PyAST_ExprAsUnicode(
23+
expr_ty e,
24+
int omit_parens);
25+
26+
#endif /* !Py_LIMITED_API */
27+
1928
#ifdef __cplusplus
2029
}
2130
#endif

Include/code.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ typedef struct {
8282

8383
#define CO_FUTURE_BARRY_AS_BDFL 0x40000
8484
#define CO_FUTURE_GENERATOR_STOP 0x80000
85+
#define CO_FUTURE_ANNOTATIONS 0x100000
8586

8687
/* This value is found in the co_cell2arg array when the associated cell
8788
variable does not correspond to an argument. */

Include/compile.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *);
1616
#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \
1717
CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \
1818
CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \
19-
CO_FUTURE_GENERATOR_STOP)
19+
CO_FUTURE_GENERATOR_STOP | CO_FUTURE_ANNOTATIONS)
2020
#define PyCF_MASK_OBSOLETE (CO_NESTED)
2121
#define PyCF_SOURCE_IS_UTF8 0x0100
2222
#define PyCF_DONT_IMPLY_DEDENT 0x0200
@@ -45,6 +45,7 @@ typedef struct {
4545
#define FUTURE_UNICODE_LITERALS "unicode_literals"
4646
#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL"
4747
#define FUTURE_GENERATOR_STOP "generator_stop"
48+
#define FUTURE_ANNOTATIONS "annotatio 10000 ns"
4849

4950
struct _mod; /* Declare the existence of this type */
5051
#define PyAST_Compile(mod, s, f, ar) PyAST_CompileEx(mod, s, f, -1, ar)

Lib/__future__.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,14 @@
5757
"unicode_literals",
5858
"barry_as_FLUFL",
5959
"generator_stop",
60+
"annotations",
6061
]
6162

6263
__all__ = ["all_feature_names"] + all_feature_names
6364

64-
# The CO_xxx symbols are defined here under the same names used by
65-
# compile.h, so that an editor search will find them here. However,
66-
# they're not exported in __all__, because they don't really belong to
65+
# The CO_xxx symbols are defined here under the same names defined in
66+
# code.h and used by compile.h, so that an editor search will find them here.
67+
# However, they're not exported in __all__, because they don't really belong to
6768
# this module.
6869
CO_NESTED = 0x0010 # nested_scopes
6970
CO_GENERATOR_ALLOWED = 0 # generators (obsolete, was 0x1000)
@@ -74,6 +75,7 @@
7475
CO_FUTURE_UNICODE_LITERALS = 0x20000 # unicode string literals
7576
CO_FUTURE_BARRY_AS_BDFL = 0x40000
7677
CO_FUTURE_GENERATOR_STOP = 0x80000 # StopIteration becomes RuntimeError in generators
78+
CO_FUTURE_ANNOTATIONS = 0x100000 # annotations become strings at runtime
7779

7880
class _Feature:
7981
def __init__(self, optionalRelease, mandatoryRelease, compiler_flag):
@@ -132,9 +134,13 @@ def __repr__(self):
132134
CO_FUTURE_UNICODE_LITERALS)
133135

134136
barry_as_FLUFL = _Feature((3, 1, 0, "alpha", 2),
135-
(3, 9, 0, "alpha", 0),
136-
CO_FUTURE_BARRY_AS_BDFL)
137+
(3, 9, 0, "alpha", 0),
138+
CO_FUTURE_BARRY_AS_BDFL)
137139

138140
generator_stop = _Feature((3, 5, 0, "beta", 1),
139-
(3, 7, 0, "alpha", 0),
140-
CO_FUTURE_GENERATOR_STOP)
141+
(3, 7, 0, "alpha", 0),
142+
CO_FUTURE_GENERATOR_STOP)
143+
144+
annotations = _Feature((3, 7, 0, "beta", 1),
145+
(4, 0, 0, "alpha", 0),
146+
CO_FUTURE_ANNOTATIONS)

0 commit comments

Comments
 (0)
0