From 0db3be7e5e0cf4c7401812d6568d5feb02d206a7 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 1 Jun 2024 15:09:54 -0700 Subject: [PATCH 1/4] Improve documentation for typing.get_type_hints - Explicit list of what it does that is different from "just return __annotations__" - Remove reference to PEP 563; adding the future import doesn't do anything to type aliases, and in general it will never make get_type_hints() less likely to fail. - Remove example, as the Annotated docs already have a similar example, and it's unbalanced to have one example about this one edge case but not about other behaviors of the function. --- Doc/library/typing.rst | 48 +++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index a8068609fcfbe7..28292d99e62d1a 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3080,35 +3080,31 @@ Introspection helpers Return a dictionary containing type hints for a function, method, module or class object. - This is often the same as ``obj.__annotations__``. In addition, - forward references encoded as string literals are handled by evaluating - them in ``globals``, ``locals`` and (where applicable) - :ref:`type parameter ` namespaces. - For a class ``C``, return - a dictionary constructed by merging all the ``__annotations__`` along - ``C.__mro__`` in reverse order. - - The function recursively replaces all ``Annotated[T, ...]`` with ``T``, - unless ``include_extras`` is set to ``True`` (see :class:`Annotated` for - more information). For example: - - .. testcode:: - - class Student(NamedTuple): - name: Annotated[str, 'some marker'] - - assert get_type_hints(Student) == {'name': str} - assert get_type_hints(Student, include_extras=False) == {'name': str} - assert get_type_hints(Student, include_extras=True) == { - 'name': Annotated[str, 'some marker'] - } + This is often the same as ``obj.__annotations__``, but this function makes + the following changes to the annotations dictionary: + + * Forward references encoded as string literals or :class:`ForwardRef` objects + are handled by evaluating them in *globalns*, *localns*, and (where applicable) + *obj*'s :ref:`type parameter ` namespace. If *globalns* or + *localns* is not given, appropriate namespace dictionaries are inferred + from *obj*. + * :const:`None` is replaced with :class:`types.NoneType`. + * If :func:`@no_type_check ` has been applied to *obj*, an empty dictionary is + returned. + * If *obj* is a class ``C``, the function returns only the class's own annotations, + but also those of all base classes. This is done by merging all the ``__annotations__`` along + ``C.__mro__`` in reverse order. + + See also :func:`inspect.get_annotations`, a lower-level function that + returns annotations more directly. .. note:: - :func:`get_type_hints` does not work with imported - :ref:`type aliases ` that include forward references. - Enabling postponed evaluation of annotations (:pep:`563`) may remove - the need for most forward references. + If any forward references in the annotations of *obj* are not resolvable + or are not valid Python code, this function will raise an exception + such as :exc:`NameError`. For example, this can happen with imported + :ref:`type aliases ` that include forward references, + or with names imported under :data:`if TYPE_CHECKING `. .. versionchanged:: 3.9 Added ``include_extras`` parameter as part of :pep:`593`. From 43620274d00c0454fb8c6ffd496e037ab3decc14 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sun, 2 Jun 2024 06:46:01 -0700 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Alex Waygood --- Doc/library/typing.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 28292d99e62d1a..2c4fdab2394d47 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3088,12 +3088,15 @@ Introspection helpers *obj*'s :ref:`type parameter ` namespace. If *globalns* or *localns* is not given, appropriate namespace dictionaries are inferred from *obj*. - * :const:`None` is replaced with :class:`types.NoneType`. + * ``None`` is replaced with :class:`types.NoneType`. * If :func:`@no_type_check ` has been applied to *obj*, an empty dictionary is returned. - * If *obj* is a class ``C``, the function returns only the class's own annotations, - but also those of all base classes. This is done by merging all the ``__annotations__`` along - ``C.__mro__`` in reverse order. + * If *obj* is a class ``C``, the function returns a dictionary that merges + annotations from ``C``'s base classes with those on ``C`` directly. This + is done by traversing ``C.__mro__`` and iteratively combining + ``__annotations__`` dictionaries. Annotations on classes appearing + earlier in the :term:`method resolution order` always take precedence over + annotations on classes appearing later in the method resolution order. See also :func:`inspect.get_annotations`, a lower-level function that returns annotations more directly. From 807fba49ff8978ba8e214b75d4d60129bb84ae63 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sun, 2 Jun 2024 07:05:47 -0700 Subject: [PATCH 3/4] Update Doc/library/typing.rst --- Doc/library/typing.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 2c4fdab2394d47..7481bd3f66929a 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3097,6 +3097,9 @@ Introspection helpers ``__annotations__`` dictionaries. Annotations on classes appearing earlier in the :term:`method resolution order` always take precedence over annotations on classes appearing later in the method resolution order. + * The function recursively replaces all occurrences of ``Annotated[T, ...]`` with ``T``, + unless *include_extras* is set to ``True`` (see :class:`Annotated` for + more information). See also :func:`inspect.get_annotations`, a lower-level function that returns annotations more directly. From 5fed5168d35b998246eb89cd89134d4d9ef7e68d Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 2 Jun 2024 15:21:18 +0100 Subject: [PATCH 4/4] line length nits --- Doc/library/typing.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 7481bd3f66929a..94de64fcf835fc 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3083,23 +3083,23 @@ Introspection helpers This is often the same as ``obj.__annotations__``, but this function makes the following changes to the annotations dictionary: - * Forward references encoded as string literals or :class:`ForwardRef` objects - are handled by evaluating them in *globalns*, *localns*, and (where applicable) - *obj*'s :ref:`type parameter ` namespace. If *globalns* or - *localns* is not given, appropriate namespace dictionaries are inferred - from *obj*. + * Forward references encoded as string literals or :class:`ForwardRef` + objects are handled by evaluating them in *globalns*, *localns*, and + (where applicable) *obj*'s :ref:`type parameter ` namespace. + If *globalns* or *localns* is not given, appropriate namespace + dictionaries are inferred from *obj*. * ``None`` is replaced with :class:`types.NoneType`. - * If :func:`@no_type_check ` has been applied to *obj*, an empty dictionary is - returned. + * If :func:`@no_type_check ` has been applied to *obj*, an + empty dictionary is returned. * If *obj* is a class ``C``, the function returns a dictionary that merges annotations from ``C``'s base classes with those on ``C`` directly. This is done by traversing ``C.__mro__`` and iteratively combining ``__annotations__`` dictionaries. Annotations on classes appearing earlier in the :term:`method resolution order` always take precedence over annotations on classes appearing later in the method resolution order. - * The function recursively replaces all occurrences of ``Annotated[T, ...]`` with ``T``, - unless *include_extras* is set to ``True`` (see :class:`Annotated` for - more information). + * The function recursively replaces all occurrences of ``Annotated[T, ...]`` + with ``T``, unless *include_extras* is set to ``True`` (see + :class:`Annotated` for more information). See also :func:`inspect.get_annotations`, a lower-level function that returns annotations more directly.