Skip to content

Commit

Permalink
pythongh-119180: Add discussion of annotations to the 3.14 What's New
Browse files Browse the repository at this point in the history
  • Loading branch information
JelleZijlstra committed Sep 23, 2024
1 parent 67201ad commit 3275204
Showing 1 changed file with 75 additions and 1 deletion.
76 changes: 75 additions & 1 deletion Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,78 @@ Summary -- Release highlights
New Features
============

.. _whatsnew-314-pep649:

PEP 649: Deferred Evaluation of Annotations
-------------------------------------------

The :term:`annotations <annotation>` on functions, classes, and modules are no
longer evaluated eagerly. Instead, annotations are stored in special-purpose
:term:`annotation functions <annotation function>` and evaluated only when
necessary. This is specified in :pep:`649` and :pep:`749`.

The new :mod:`annotationlib` module provides tools for inspecting deferred
annotations. Annotations may be evaluated in the :attr:`~annotationlib.Format.VALUE`
format (which evaluates annotations to runtime values, similar to the behavior in
earlier Python versions), the :attr:`~annotationlib.Format.FORWARDREF` format
(which replaces undefined names with special markers), and the
:attr:`~annotationlib.Format.SOURCE` format (which returns annotations as strings).

This example shows how these formats behave::

from annotationlib import get_annotations, Format

def func(arg: Undefined):
pass

print(get_annotations(func, format=Format.VALUE)) # raises NameError
print(get_annotations(func, format=Format.FORWARDREF)) # {'arg': ForwardRef('Undefined')}
print(get_annotations(func, format=Format.SOURCE)) # {'arg': 'Undefined'}

Implications if you write annotations in your code
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you write annotations in your code (for example, for use with a static type
checker), then this change probably does not affect you: you can keep
writing annotations the same way you did in previous versions of Python.

You will likely be able to remove quoted strings in annotations, which are frequently
used for forward references. Similarly, if you use ``from __future__ import annotations``
to avoid having to write strings in annotations, you may well be able to
remove it. However, if you rely on third-party libraries that read annotations,
those libraries may need changes to support unquoted annotations.

Implications if you read ``__annotations__``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If your code reads the ``__annotations__`` attribute on objects, you may want
to make changes in order to support code that relies on deferred evaluation of
annotations. For example, you may want to use the :func:`annotationlib.get_annotations`
with the :attr:`~annotationlib.Format.FORWARDREF` format, as the :mod:`dataclasses`
module now does.

Related changes
^^^^^^^^^^^^^^^

The changes in Python 3.14 are designed to minimize changes to code that contains
annotations in source code and to code that reads ``__annotations__``. However,
there are many changes to the supporting code, and if you rely on undocumented
details of the annotation behavior or on private functions in the standard library,
your code may not work in Python 3.14. To safeguard your code against future changes,
use only the documented functionality of the :mod:`annotationlib` module.

``from __future__ import annotations``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In Python 3.7, :pep:`563` introduced the ``from __future__ import annotations``
directive, which turns all annotations into strings. This directive is now
considered deprecated and it is expected to be removed in a future version of Python.
However, this removal will not happen until after Python 3.13, the last version of
Python without deferred evaluation of annotations, loses support.
In Python 3.14, the behavior of code using ``from __future__ import annotations``
does not change.


Improved Error Messages
-----------------------

Expand Down Expand Up @@ -109,7 +181,9 @@ Other Language Changes
New Modules
===========

* None yet.
* :mod:`annotationlib`: For introspecting :term:`annotations <annotation>`.
See :pep:`749` for more details.
(Contributed by Jelle Zijlstra in :gh:`119180`.)


Improved Modules
Expand Down

0 comments on commit 3275204

Please sign in to comment.