Skip to content

Commit f74a56a

Browse files
Update PEP 649/749 implementation (#596)
1 parent d90a2f4 commit f74a56a

File tree

4 files changed

+29
-29
lines changed

4 files changed

+29
-29
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
- Drop support for Python 3.8 (including PyPy-3.8). Patch by [Victorien Plot](https://github.com/Viicos).
44
- Do not attempt to re-export names that have been removed from `typing`,
55
anticipating the removal of `typing.no_type_check_decorator` in Python 3.15.
6+
Patch by Jelle Zijlstra.
7+
- Update `typing_extensions.Format` and `typing_extensions.evaluate_forward_ref` to align
8+
with changes in Python 3.14. Patch by Jelle Zijlstra.
9+
- Fix tests for Python 3.14. Patch by Jelle Zijlstra.
610

711
New features:
812

913
- Add support for inline typed dictionaries ([PEP 764](https://peps.python.org/pep-0764/)).
1014
Patch by [Victorien Plot](https://github.com/Viicos).
1115
- Add `typing_extensions.Reader` and `typing_extensions.Writer`. Patch by
1216
Sebastian Rittau.
13-
- Fix tests for Python 3.14. Patch by Jelle Zijlstra.
1417

1518
# Release 4.13.2 (April 10, 2025)
1619

doc/index.rst

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ Functions
769769

770770
.. versionadded:: 4.2.0
771771

772-
.. function:: evaluate_forward_ref(forward_ref, *, owner=None, globals=None, locals=None, type_params=None, format=Format.VALUE)
772+
.. function:: evaluate_forward_ref(forward_ref, *, owner=None, globals=None, locals=None, type_params=None, format=None)
773773

774774
Evaluate an :py:class:`typing.ForwardRef` as a :py:term:`type hint`.
775775

@@ -796,7 +796,7 @@ Functions
796796
This parameter must be provided (though it may be an empty tuple) if *owner*
797797
is not given and the forward reference does not already have an owner set.
798798
*format* specifies the format of the annotation and is a member of
799-
the :class:`Format` enum.
799+
the :class:`Format` enum, defaulting to :attr:`Format.VALUE`.
800800

801801
.. versionadded:: 4.13.0
802802

@@ -952,9 +952,19 @@ Enums
952952
for the annotations. This format is identical to the return value for
953953
the function under earlier versions of Python.
954954

955+
.. attribute:: VALUE_WITH_FAKE_GLOBALS
956+
957+
Equal to 2. Special value used to signal that an annotate function is being
958+
evaluated in a special environment with fake globals. When passed this
959+
value, annotate functions should either return the same value as for
960+
the :attr:`Format.VALUE` format, or raise :exc:`NotImplementedError`
961+
to signal that they do not support execution in this environment.
962+
This format is only used internally and should not be passed to
963+
the functions in this module.
964+
955965
.. attribute:: FORWARDREF
956966

957-
Equal to 2. When :pep:`649` is implemented, this format will attempt to return the
967+
Equal to 3. When :pep:`649` is implemented, this format will attempt to return the
958968
conventional Python values for the annotations. However, if it encounters
959969
an undefined name, it dynamically creates a proxy object (a ForwardRef)
960970
that substitutes for that value in the expression.
@@ -964,7 +974,7 @@ Enums
964974

965975
.. attribute:: STRING
966976

967-
Equal to 3. When :pep:`649` is implemented, this format will produce an annotation
977+
Equal to 4. When :pep:`649` is implemented, this format will produce an annotation
968978
dictionary where the values have been replaced by strings containing
969979
an approximation of the original source code for the annotation expressions.
970980

src/test_typing_extensions.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
from _typed_dict_test_helper import Foo, FooGeneric, VeryAnnotated
3030
from typing_extensions import (
3131
_FORWARD_REF_HAS_CLASS,
32-
_PEP_649_OR_749_IMPLEMENTED,
3332
Annotated,
3433
Any,
3534
AnyStr,
@@ -8533,7 +8532,7 @@ def test_stock_annotations_in_module(self):
85338532
get_annotations(isa.MyClass, format=Format.STRING),
85348533
{"a": "int", "b": "str"},
85358534
)
8536-
mycls = "MyClass" if _PEP_649_OR_749_IMPLEMENTED else "inspect_stock_annotations.MyClass"
8535+
mycls = "MyClass" if sys.version_info >= (3, 14) else "inspect_stock_annotations.MyClass"
85378536
self.assertEqual(
85388537
get_annotations(isa.function, format=Format.STRING),
85398538
{"a": "int", "b": "str", "return": mycls},
@@ -8581,7 +8580,7 @@ def test_stock_annotations_on_wrapper(self):
85818580
get_annotations(wrapped, format=Format.FORWARDREF),
85828581
{"a": int, "b": str, "return": isa.MyClass},
85838582
)
8584-
mycls = "MyClass" if _PEP_649_OR_749_IMPLEMENTED else "inspect_stock_annotations.MyClass"
8583+
mycls = "MyClass" if sys.version_info >= (3, 14) else "inspect_stock_annotations.MyClass"
85858584
self.assertEqual(
85868585
get_annotations(wrapped, format=Format.STRING),
85878586
{"a": "int", "b": "str", "return": mycls},

src/typing_extensions.py

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3821,27 +3821,15 @@ def __eq__(self, other: object) -> bool:
38213821
__all__.append("CapsuleType")
38223822

38233823

3824-
# Using this convoluted approach so that this keeps working
3825-
# whether we end up using PEP 649 as written, PEP 749, or
3826-
# some other variation: in any case, inspect.get_annotations
3827-
# will continue to exist and will gain a `format` parameter.
3828-
_PEP_649_OR_749_IMPLEMENTED = (
3829-
hasattr(inspect, 'get_annotations')
3830-
and inspect.get_annotations.__kwdefaults__ is not None
3831-
and "format" in inspect.get_annotations.__kwdefaults__
3832-
)
3833-
3834-
3835-
class Format(enum.IntEnum):
3836-
VALUE = 1
3837-
VALUE_WITH_FAKE_GLOBALS = 2
3838-
FORWARDREF = 3
3839-
STRING = 4
3840-
3841-
3842-
if _PEP_649_OR_749_IMPLEMENTED:
3843-
get_annotations = inspect.get_annotations
3824+
if sys.version_info >= (3,14):
3825+
from annotationlib import Format, get_annotations
38443826
else:
3827+
class Format(enum.IntEnum):
3828+
VALUE = 1
3829+
VALUE_WITH_FAKE_GLOBALS = 2
3830+
FORWARDREF = 3
3831+
STRING = 4
3832+
38453833
def get_annotations(obj, *, globals=None, locals=None, eval_str=False,
38463834
format=Format.VALUE):
38473835
"""Compute the annotations dict for an object.
@@ -4122,7 +4110,7 @@ def evaluate_forward_ref(
41224110
globals=None,
41234111
locals=None,
41244112
type_params=None,
4125-
format=Format.VALUE,
4113+
format=None,
41264114
_recursive_guard=frozenset(),
41274115
):
41284116
"""Evaluate a forward reference as a type hint.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy