Skip to content

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

Merged
merged 3 commits into from
Feb 5, 2020

Conversation

jstasiak
Copy link
Contributor

@jstasiak jstasiak commented Jan 29, 2020

PEP 593 has been accepted some time ago. I got a green light for merging
this from Till, so I went ahead and combined the code contributed to
typing_extensions[1] and the documentation from the PEP 593 text[2].

My changes were limited to:

  • removing code designed for typing_extensions to run on older Python
    versions
  • removing some irrelevant parts of the PEP text when copying it over as
    documentation and otherwise changing few small bits to better serve
    the purpose
  • changing the get_type_hints signature to match reality (parameter
    names)

I wasn't entirely sure how to go about crediting the authors but I used
my best judgment, let me know if something needs changing in this
regard.

[1] https://github.com/python/typing/blob/8280de241fd8c8afe727c7860254b753e383b360/typing_extensions/src_py3/typing_extensions.py
[2] https://github.com/python/peps/blob/17710b879882454d55f82c2d44596e8e9f8e4bff/pep-0593.rst

https://bugs.python.org/issue39491

PEP 593 has been accepted some time ago. I got a green light for merging
this from Till, so I went ahead and combined the code contributed to
typing_extensions[1] and the documentation from the PEP 593 text[2].

My changes were limited to:

* removing code designed for typing_extensions to run on older Python
  versions
* removing some irrelevant parts of the PEP text when copying it over as
  documentation and otherwise changing few small bits to better serve
  the purpose
* changing the get_type_hints signature to match reality (parameter
  names)

I wasn't entirely sure how to go about crediting the authors but I used
my best judgment, let me know if something needs changing in this
regard.

[1] https://github.com/python/typing/blob/8280de241fd8c8afe727c7860254b753e383b360/typing_extensions/src_py3/typing_extensions.py
[2] https://github.com/python/peps/blob/17710b879882454d55f82c2d44596e8e9f8e4bff/pep-0593.rst
@jstasiak
Copy link
Contributor Author

I also modified get_origin() and get_args() to support extracting information from Annotated[...] at runtime, since the conclusion of the discussion on typing-sig was that get_origin() and get_args() are the public API to do that.

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't audit that the changes to typing.py and test_typing.py are exactly what's in the typing repo, I skimmed it and beyond that I trust you.

more information). For example::

class Student(NamedTuple):
name: Annotated[str, struct.ctype("<10s")]
Copy link
Member

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 attribute ctype. Maybe pick a different example?

@@ -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
Copy link
Member

Choose a reason for hiding this comment

The 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 (Annotated[T, x, y, z]) early in the description?

Comment on lines 1418 to 1420
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reflow this paragraph.

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,
Copy link
Member

Choose a reason for hiding this comment

The 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).


* ``Annotated`` can be used with nested and generic aliases::

Typevar T = ...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use correct syntax for type variables.

Comment on lines 300 to 302
:pep:`593` introduced an :data:`typing.Annotated` type to decorate existing
types with context-specific metadata. (Contributed by Till Varoquaux and
Konstantin Kashin.)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also mention the new argument to get_type_hints() here.

Comment on lines 2925 to 2926


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only one blank line here.

@jstasiak
Copy link
Contributor Author

jstasiak commented Feb 5, 2020

If there's a difference between this and what's in the typing repo other than I listed above it's a mistake, but I don't believe anything significant got changed when transferring the code here. As for your comments – they should be addressed now.

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I'll land this once the tests pass.

@gvanrossum gvanrossum merged commit cf5b109 into python:master Feb 5, 2020
@bedevere-bot
Copy link

@gvanrossum: Please replace # with GH- in the commit message next time. Thanks!

@jstasiak jstasiak deleted the pep593 branch February 5, 2020 13:39
@jstasiak
Copy link
Contributor Author

jstasiak commented Feb 5, 2020

Woo!

I'm wondering now – what should happen in the typing repository? Should the typing module import (from typing_extensions) and reexport Annotated and get_type_hints?

@jstasiak
Copy link
Contributor Author

jstasiak commented Feb 5, 2020

I'm thinking typing.Annotated needs to be the same object as typing_extensions.Annotated to avoid multiple implementations present at runtime (I'm sure it'd cause issues) which should be easy enough with a conditional import in typing_extensions, correct me if this is not making sense.

@gvanrossum
Copy link
Member

I can't speak for @ilevkivskyi (who seems to be too busy to follow this, alas) but I think the dependency clearly goes from typing_extension to typing -- typing doesn't use anything from typing_extensions, while typing_extensions already depends on typing.

So to make typing_extensions work with Python 3.9, typing_extensions should try to import Annotated from typing before defining its own versions (and refraining from defining its own versions if it can import Annotated from typing).

I don't think it's worth your while to copy Annotated and the improved get_type_info into typing -- that would only benefit Python versions so old that they don't have typing in the stdlib at all. Probably the only relevant version would be 2.7, whose end of life has come. Let those users continue to import this feature from typing_extensions.

There's also something similar to be done for typeshed, otherwise 3.9 users who import Annotated from typing will get complaints. Here I think the definition should strictly check on sys.version_info: in 3.9 and later, the definition is in typing, and typing_extensions imports from there; in earlier versions, the definition is only in typing_extensions.

jstasiak added a commit to jstasiak/typing that referenced this pull request Feb 6, 2020
The implementations come from CPython commit 427c84f13f77 with one small
change – the get_origin's docstring mentions Annotated as it's also
supported.

get_origin() and get_args() introduced in [1] and modified in [2] to
support Annotated.

[1] python/cpython#13685
[2] python/cpython#18260
jstasiak added a commit to jstasiak/typing that referenced this pull request Feb 6, 2020
Following [1] this prevents multiple runtime implementations of Annotated
and get_type_hints from existing on Python 3.9 (which has recently
merged PEP 593 changes[2]). Reexporting allows code targetting both
Python pre-3.9 and 3.9+ to be able to import from typing_extensions and
to keep working without changes.

[1] python/cpython#18260 (comment)
[2] python/cpython#18260
jstasiak added a commit to jstasiak/cpython that referenced this pull request Feb 6, 2020
msullivan pushed a commit to python/mypy that referenced this pull request Feb 6, 2020
This is to handle PEP 593 support recently merged into CPython[1].

[1] python/cpython#18260
gvanrossum pushed a commit that referenced this pull request Feb 7, 2020
gvanrossum pushed a commit to python/typing that referenced this pull request Feb 7, 2020
The implementations come from CPython commit 427c84f13f77 with one small
change – the get_origin's docstring mentions Annotated as it's also
supported.

get_origin() and get_args() introduced in [1] and modified in [2] to
support Annotated.

[1] python/cpython#13685
[2] python/cpython#18260

* Define our own get_origin()/get_args() in typing_extensions on Python 3.8

Otherwise typing_extensions.get_origin() would not recognize
typing_extensions.Annotated on 3.8.
gvanrossum pushed a commit to python/typing that referenced this pull request Feb 11, 2020
…699)

Following [1] this prevents multiple runtime implementations of Annotated
and get_type_hints from existing on Python 3.9 (which has recently
merged PEP 593 changes[2]). Reexporting allows code targetting both
Python pre-3.9 and 3.9+ to be able to import from typing_extensions and
to keep working without changes.

[1] python/cpython#18260 (comment)
[2] python/cpython#18260
JelleZijlstra pushed a commit to python/typing_extensions that referenced this pull request May 19, 2022
The implementations come from CPython commit 427c84f13f77 with one small
change – the get_origin's docstring mentions Annotated as it's also
supported.

get_origin() and get_args() introduced in [1] and modified in [2] to
support Annotated.

[1] python/cpython#13685
[2] python/cpython#18260

* Define our own get_origin()/get_args() in typing_extensions on Python 3.8

Otherwise typing_extensions.get_origin() would not recognize
typing_extensions.Annotated on 3.8.
JelleZijlstra pushed a commit to python/typing_extensions that referenced this pull request May 19, 2022
…#699)

Following [1] this prevents multiple runtime implementations of Annotated
and get_type_hints from existing on Python 3.9 (which has recently
merged PEP 593 changes[2]). Reexporting allows code targetting both
Python pre-3.9 and 3.9+ to be able to import from typing_extensions and
to keep working without changes.

[1] python/cpython#18260 (comment)
[2] python/cpython#18260
JelleZijlstra pushed a commit to python/typing_extensions that referenced this pull request May 19, 2022
The implementations come from CPython commit 427c84f13f77 with one small
change – the get_origin's docstring mentions Annotated as it's also
supported.

get_origin() and get_args() introduced in [1] and modified in [2] to
support Annotated.

[1] python/cpython#13685
[2] python/cpython#18260

* Define our own get_origin()/get_args() in typing_extensions on Python 3.8

Otherwise typing_extensions.get_origin() would not recognize
typing_extensions.Annotated on 3.8.
JelleZijlstra pushed a commit to python/typing_extensions that referenced this pull request May 19, 2022
…#699)

Following [1] this prevents multiple runtime implementations of Annotated
and get_type_hints from existing on Python 3.9 (which has recently
merged PEP 593 changes[2]). Reexporting allows code targetting both
Python pre-3.9 and 3.9+ to be able to import from typing_extensions and
to keep working without changes.

[1] python/cpython#18260 (comment)
[2] python/cpython#18260
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants