I may have missed an earlier discussion on this—I tried to read it all, but it’s a lot.
The current behavior with from future import __annotations__, IIUC, causes migration headaches; I think this has been discussed sufficiently. What is a library that wants to support all non-EOL Python versions to do? I think the only option is to retain that, and thus get the stringifying behavior. This also means there’s a flag day at EOL of Python 3.13, especially to get rid of the warnings. One migratory path is to make sure no code uses from __future__ import annotations.
There was a 2024 discussion of this in PEP649 means that PEP563 will see *more* usage, not less, and will break runtime typecheckers . Backporting PEP 749 is not going to happen.
In the original PEP 649, there was also the proposal to make this into a future import when released, from __future__ import co_annotations, but the decision was made to make it on-by-default.
PEP 749 recognizes the migration problem by pointing out that this is impossible:
# impossible
if sys.version_info < (3, 14):
from __future__ import annotations
I think there is one primitive, however, that would possibly make migrations easier: On Python versions that still get feature releases, introduce a
from __future__ import annotations_compat
with these semantics:
- On Python <3.14: It functions exactly as
from __future__ import annotations - On Python >=3.14, it will function as a no-op
Thus, it will explicitly provide different annotation semantics on older Python versions and on 3.14+, with an implied user promise that either behavior is ok.
I think if this is something that could be achieved for even one Python release <3.14, that might ease some migration headaches?