Skip to content
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

Clarify the future of from __future__ import annotations #19

Closed
ncoghlan opened this issue Oct 26, 2022 · 2 comments
Closed

Clarify the future of from __future__ import annotations #19

ncoghlan opened this issue Oct 26, 2022 · 2 comments

Comments

@ncoghlan
Copy link

ncoghlan commented Oct 26, 2022

As mentioned in a couple of other tickets, I was recently re-reading https://lukasz.langa.pl/61df599c-d9d8-4938-868b-36b67fdb4448/ (prompted by the release of Python 3.11) and considering the concerns it raises with PEP 649.

The circular reference and if TYPE_CHECKING: questions are already discussed in #1, #2, and #17, so I won't repeat them here.

This ticket is instead about:

  1. Backporting type hinting syntax from newer versions of Python to older versions
  2. Backwards compatibility for code that currently uses from __future__ import annotations

For the first, I think "Explicitly quote annotations that use type hinting syntax that only becomes valid at runtime in later Python versions" is sufficient to address the point. Even string annotations would need to rely on explicit quoting to backport type hinting syntax that only becomes valid at compile time in future versions, and code object annotations would be starting from the much richer Python 3.12 type hinting syntax baseline.

For the second, PEP 649 doesn't currently spell out the expected fate of from __future__ import annotations. Łukasz's article assumes it would be deprecated, emit deprecation warnings, and eventually stop working outright, but I'm not sure that's the right thing for it to do (due to the cross-version compatibility concerns that Łukasz raises in his post).

Instead, the following seems like a cleaner way forward:

  1. While PEP 649 still requires its own __future__ import, from __future__ import annotations continues to function as it does in 3.9, without any deprecation warnings (just as regular annotations wouldn't have any deprecation warnings)
  2. When PEP 649 becomes the default behaviour for annotations, it also becomes the behaviour for code using from __future__ import annotations (so the semantics of the latter import still change from what they were previously, just as they would for code with no __future__ import, but there's no hard error on the __future__ import itself)

That way, just as concerns with migrating from eager annotations to lazy annotations can be resolved during the __future__ import period, so can concerns with migrating from string annotations to code object based annotations, with the goal being that the eventual semantic change doesn't cause any significant problems in either case.

This idea assumes that the practical issues with migrating from string annotations to code object based annotations are resolved, but those are presumably going to have to be resolved anyway in order for PEP 649 to be accepted by the SC.

@ncoghlan
Copy link
Author

ncoghlan commented Oct 30, 2022

As per @zzzeek's comment at #17 (comment) , pursuing this "future annotations become equivalent" approach would require that code object annotations keep the "No default eval" property of string annotations.

If that property is preserved, libraries updated to deal with string annotations wouldn't need to switch to new APIs to get the raw annotations.

The downside is that this would make the transition from regular annotations more disruptive.

@ncoghlan
Copy link
Author

The accepted version of PEP 649 covers this.

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

No branches or pull requests

1 participant