From 6a5e4404589442b687efd94f006f02f04a89e3ef Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 24 May 2025 14:04:38 -0700 Subject: [PATCH 1/3] gh-119180: Updates to PEP 649/749 docs - Mention (again) that `type.__annotations__` is unsafe. It is now safe when using only classes defined under PEP 649 semantics, but not with classes defined using `from __future__ import annotations`. - Mention that annotations on instances no longer work. There was already an issue about this. - Mention the general changes in the "Porting to Python 3.14" section. - `annotationlib` was proposed by PEP-749, not PEP-649. --- Doc/reference/datamodel.rst | 14 +++++++++++++- Doc/whatsnew/3.14.rst | 11 ++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 005a768f684e2c..c13e4bf682c58b 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1228,10 +1228,22 @@ Special attributes :attr:`__annotations__ attributes `. For best practices on working with :attr:`~object.__annotations__`, - please see :mod:`annotationlib`. Where possible, use + please see :mod:`annotationlib`. Use :func:`annotationlib.get_annotations` instead of accessing this attribute directly. + .. warning:: + + Accessing the :attr:`!__annotations__` attribute directly + on a class object may return annotations for the wrong class + in certain cases where the class, its base class, or a metaclass + is defined under ``from __future__ import annotations``. + See :pep:`749 <749#pep749-metaclasses>` for details. + + This attribute does not exist on certain builtin classes. On + user-defined classes without ``__annotations__``, it is an + empty dictionary. + .. versionchanged:: 3.14 Annotations are now :ref:`lazily evaluated `. See :pep:`649`. diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 88e52015bdc2b1..5efd3332c5c0d0 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -74,7 +74,7 @@ deferred evaluation of annotations (:pep:`649`), and a new type of interpreter that uses tail calls. The library changes include the addition of a new :mod:`!annotationlib` module -for introspecting and wrapping annotations (:pep:`649`), +for introspecting and wrapping annotations (:pep:`749`), a new :mod:`!compression.zstd` module for Zstandard support (:pep:`784`), plus syntax highlighting in the REPL, as well as the usual deprecations and removals, @@ -444,6 +444,10 @@ In particular, do not read annotations directly from the namespace dictionary attribute of type objects. Use :func:`annotationlib.get_annotate_from_class_namespace` during class construction and :func:`annotationlib.get_annotations` afterwards. +In previous releases, it was sometimes possible to access class annotations from +an instance of an annotated class. This behavior was undocumented and accidental, +and will no longer work in Python 3.14. + ``from __future__ import annotations`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -2501,6 +2505,11 @@ Changes in the Python API See :ref:`above ` for more details. (Contributed by Jelle Zijlstra in :gh:`105499`.) +* The behavior of annotations has changed in various ways; see + :ref:`above ` for details. While most code that interacts + with annotations should continue to work, some undocumented details may behave + differently. + Build changes ============= From b5ff710116a8e8f151315959f84ac9e09be372e9 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 26 May 2025 07:39:32 -0700 Subject: [PATCH 2/3] Update Doc/whatsnew/3.14.rst Co-authored-by: Emma Smith --- Doc/whatsnew/3.14.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 5efd3332c5c0d0..561d1a8914b50c 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -2505,7 +2505,7 @@ Changes in the Python API See :ref:`above ` for more details. (Contributed by Jelle Zijlstra in :gh:`105499`.) -* The behavior of annotations has changed in various ways; see +* The runtime behavior of annotations has changed in various ways; see :ref:`above ` for details. While most code that interacts with annotations should continue to work, some undocumented details may behave differently. From 596bdbe7ad0ded516c131b03386c32322e74b45b Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 26 May 2025 08:19:08 -0700 Subject: [PATCH 3/3] Update Doc/reference/datamodel.rst Co-authored-by: Carol Willing --- Doc/reference/datamodel.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index c13e4bf682c58b..32a2e266262c52 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1235,7 +1235,7 @@ Special attributes .. warning:: Accessing the :attr:`!__annotations__` attribute directly - on a class object may return annotations for the wrong class + on a class object may return annotations for the wrong class, specifically in certain cases where the class, its base class, or a metaclass is defined under ``from __future__ import annotations``. See :pep:`749 <749#pep749-metaclasses>` for details.