-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
bpo-39491: Merge PEP 593 (typing.Annotated) support #18260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1028,7 +1028,7 @@ The module defines the following classes, functions and decorators: | |
runtime we intentionally don't check anything (we want this | ||
to be as fast as possible). | ||
|
||
.. function:: get_type_hints(obj[, globals[, locals]]) | ||
.. function:: get_type_hints(obj, globalns=None, localns=None, include_extras=False) | ||
|
||
Return a dictionary containing type hints for a function, method, module | ||
or class object. | ||
|
@@ -1041,6 +1041,22 @@ The module defines the following classes, functions and decorators: | |
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:: | ||
|
||
class Student(NamedTuple): | ||
name: Annotated[str, struct.ctype("<10s")] | ||
|
||
get_type_hints(Student) == {'name': str} | ||
get_type_hints(Student, include_extras=False) == {'name': str} | ||
get_type_hints(Student, include_extras=True) == { | ||
'name': Annotated[str, struct.ctype("<10s")] | ||
} | ||
|
||
.. versionchanged:: 3.9 | ||
Added ``include_extras`` parameter as part of :pep:`593`. | ||
|
||
.. function:: get_origin(tp) | ||
.. function:: get_args(tp) | ||
|
||
|
@@ -1372,3 +1388,87 @@ The module defines the following classes, functions and decorators: | |
evaluated, so the second annotation does not need to be enclosed in quotes. | ||
|
||
.. versionadded:: 3.5.2 | ||
|
||
.. data:: Annotated | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can I ask that you hint at the possibility of passing multiple extras ( |
||
|
||
A type, introduced in :pep:`593` (``Flexible function and variable | ||
annotations``), to decorate | ||
existing types with context-specific metadata. Specifically, a type | ||
``T`` can be annotated with metadata ``x`` via the typehint | ||
``Annotated[T, x]``. This metadata can be used for either static | ||
analysis or at runtime. If a library (or tool) encounters a typehint | ||
``Annotated[T, x]`` and has no special logic for metadata ``x``, it | ||
should ignore it and simply treat the type as ``T``. Unlike the | ||
``no_type_check`` functionality that currently exists in the ``typing`` | ||
module which completely disables typechecking annotations on a function | ||
or a class, the ``Annotated`` type allows for both static typechecking | ||
of ``T`` (e.g., via mypy or Pyre, which can safely ignore ``x``) | ||
together with runtime access to ``x`` within a specific application. | ||
|
||
Ultimately, the responsibility of how to interpret the annotations (if | ||
at all) is the responsibility of the tool or library encountering the | ||
``Annotated`` type. A tool or library encountering an ``Annotated`` type | ||
can scan through the annotations to determine if they are of interest | ||
(e.g., using ``isinstance()``). | ||
|
||
When a tool or a library does not support annotations or encounters an | ||
unknown annotation it should just ignore it and treat annotated type as | ||
the underlying type. | ||
|
||
It's up to the tool consuming the annotations | ||
to decide whether the client is allowed to have several annotations on | ||
one type and how to merge those annotations. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reflow this paragraph. |
||
|
||
Since the ``Annotated`` type allows you to put several annotations of | ||
the same (or different) type(s) on any node, the tools or libraries | ||
consuming those annotations are in charge of dealing with potential | ||
duplicates. For example, if you are doing value range analysis you might | ||
allow this:: | ||
|
||
T1 = Annotated[int, ValueRange(-10, 5)] | ||
T2 = Annotated[T1, ValueRange(-20, 3)] | ||
|
||
A new ``include_extras`` parameter to :func:`get_type_hints` has been added, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It will stop to be "new" in the next version. You can just state that the functionality exists without describing that it's new and has been added (that would be text for "what's new" though). |
||
setting it to ``True`` lets one access the extra annotations at runtime. | ||
|
||
The details of the syntax: | ||
|
||
* The first argument to ``Annotated`` must be a valid type | ||
|
||
* Multiple type annotations are supported (``Annotated`` supports variadic | ||
arguments):: | ||
|
||
Annotated[int, ValueRange(3, 10), ctype("char")] | ||
|
||
* ``Annotated`` must be called with at least two arguments ( | ||
``Annotated[int]`` is not valid) | ||
|
||
* The order of the annotations is preserved and matters for equality | ||
checks:: | ||
|
||
Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[ | ||
int, ctype("char"), ValueRange(3, 10) | ||
] | ||
|
||
* Nested ``Annotated`` types are flattened, with metadata ordered | ||
starting with the innermost annotation:: | ||
|
||
Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[ | ||
int, ValueRange(3, 10), ctype("char") | ||
] | ||
|
||
* Duplicated annotations are not removed:: | ||
|
||
Annotated[int, ValueRange(3, 10)] != Annotated[ | ||
int, ValueRange(3, 10), ValueRange(3, 10) | ||
] | ||
|
||
* ``Annotated`` can be used with nested and generic aliases:: | ||
|
||
Typevar T = ... | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use correct syntax for type variables. |
||
Vec = Annotated[List[Tuple[T, T]], MaxLen(10)] | ||
V = Vec[int] | ||
|
||
V == Annotated[List[Tuple[int, int]], MaxLen(10)] | ||
|
||
.. versionadded:: 3.9 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -294,6 +294,13 @@ signal | |
Exposed the Linux-specific :func:`signal.pidfd_send_signal` for sending to | ||
signals to a process using a file descriptor instead of a pid. (:issue:`38712`) | ||
|
||
typing | ||
------ | ||
|
||
:pep:`593` introduced an :data:`typing.Annotated` type to decorate existing | ||
types with context-specific metadata. (Contributed by Till Varoquaux and | ||
Konstantin Kashin.) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also mention the new argument to get_type_hints() here. |
||
|
||
|
||
Optimizations | ||
============= | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The builtin module
struct
doesn't have an attributectype
. Maybe pick a different example?