Skip to content

Commit 5518c2a

Browse files
gh-128661: Remove DeprecationWarning in evaluate_forward_ref (#128930)
It doesn't make sense to use a deprecation for evaluate_forward_ref, as it is a new function in Python 3.14 and doesn't have compatibility guarantees. I considered making it throw an error if type_params it not passed and there is no owner. However, I think this is too unfriendly for users. The case where this param is really needed is fairly esoteric and I don't think this case is worth the pain of forcing users to write "type_params=()".
1 parent 24decb0 commit 5518c2a

File tree

4 files changed

+23
-39
lines changed

4 files changed

+23
-39
lines changed

Doc/library/annotationlib.rst

+18-10
Original file line numberDiff line numberDiff line change
@@ -172,30 +172,38 @@ Classes
172172
:class:`~ForwardRef`. The string may not be exactly equivalent
173173
to the original source.
174174

175-
.. method:: evaluate(*, globals=None, locals=None, type_params=None, owner=None)
175+
.. method:: evaluate(*, owner=None, globals=None, locals=None, type_params=None)
176176

177177
Evaluate the forward reference, returning its value.
178178

179179
This may throw an exception, such as :exc:`NameError`, if the forward
180-
reference refers to names that do not exist. The arguments to this
180+
reference refers to a name that cannot be resolved. The arguments to this
181181
method can be used to provide bindings for names that would otherwise
182182
be undefined.
183183

184+
The *owner* parameter provides the preferred mechanism for passing scope
185+
information to this method. The owner of a :class:`~ForwardRef` is the
186+
object that contains the annotation from which the :class:`~ForwardRef`
187+
derives, such as a module object, type object, or function object.
188+
189+
The *globals*, *locals*, and *type_params* parameters provide a more precise
190+
mechanism for influencing the names that are available when the :class:`~ForwardRef`
191+
is evaluated. *globals* and *locals* are passed to :func:`eval`, representing
192+
the global and local namespaces in which the name is evaluated.
193+
The *type_params* parameter is relevant for objects created using the native
194+
syntax for :ref:`generic classes <generic-classes>` and :ref:`functions <generic-functions>`.
195+
It is a tuple of :ref:`type parameters <type-params>` that are in scope
196+
while the forward reference is being evaluated. For example, if evaluating a
197+
:class:`~ForwardRef` retrieved from an annotation found in the class namespace
198+
of a generic class ``C``, *type_params* should be set to ``C.__type_params__``.
199+
184200
:class:`~ForwardRef` instances returned by :func:`get_annotations`
185201
retain references to information about the scope they originated from,
186202
so calling this method with no further arguments may be sufficient to
187203
evaluate such objects. :class:`~ForwardRef` instances created by other
188204
means may not have any information about their scope, so passing
189205
arguments to this method may be necessary to evaluate them successfully.
190206

191-
*globals* and *locals* are passed to :func:`eval`, representing
192-
the global and local namespaces in which the name is evaluated.
193-
*type_params*, if given, must be a tuple of
194-
:ref:`type parameters <type-params>` that are in scope while the forward
195-
reference is being evaluated. *owner* is the object that owns the
196-
annotation from which the forward reference derives, usually a function,
197-
class, or module.
198-
199207
.. important::
200208

201209
Once a :class:`~ForwardRef` instance has been evaluated, it caches

Doc/library/typing.rst

+2-10
Original file line numberDiff line numberDiff line change
@@ -3466,16 +3466,8 @@ Introspection helpers
34663466
* Supports the :attr:`~annotationlib.Format.FORWARDREF` and
34673467
:attr:`~annotationlib.Format.STRING` formats.
34683468

3469-
*forward_ref* must be an instance of :class:`~annotationlib.ForwardRef`.
3470-
*owner*, if given, should be the object that holds the annotations that
3471-
the forward reference derived from, such as a module, class object, or function.
3472-
It is used to infer the namespaces to use for looking up names.
3473-
*globals* and *locals* can also be explicitly given to provide
3474-
the global and local namespaces.
3475-
*type_params* is a tuple of :ref:`type parameters <type-params>` that
3476-
are in scope when evaluating the forward reference.
3477-
This parameter must be provided (though it may be an empty tuple) if *owner*
3478-
is not given and the forward reference does not already have an owner set.
3469+
See the documentation for :meth:`annotationlib.ForwardRef.evaluate` for
3470+
the meaning of the *owner*, *globals*, *locals*, and *type_params* parameters.
34793471
*format* specifies the format of the annotation and is a member of
34803472
the :class:`annotationlib.Format` enum.
34813473

Lib/test/test_typing.py

+1-14
Original file line numberDiff line numberDiff line change
@@ -7311,20 +7311,7 @@ def test_evaluate_forward_ref(self):
73117311

73127312
def test_evaluate_forward_ref_no_type_params(self):
73137313
ref = ForwardRef('int')
7314-
with self.assertWarnsRegex(
7315-
DeprecationWarning,
7316-
(
7317-
"Failing to pass a value to the 'type_params' parameter "
7318-
"of 'typing.evaluate_forward_ref' is deprecated, "
7319-
"as it leads to incorrect behaviour"
7320-
),
7321-
):
7322-
typing.evaluate_forward_ref(ref)
7323-
7324-
# No warnings when `type_params` is passed:
7325-
with warnings.catch_warnings(record=True) as w:
7326-
typing.evaluate_forward_ref(ref, type_params=())
7327-
self.assertEqual(w, [])
7314+
self.assertIs(typing.evaluate_forward_ref(ref), int)
73287315

73297316

73307317
class CollectionsAbcTests(BaseTestCase):

Lib/typing.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@ def evaluate_forward_ref(
943943
owner=None,
944944
globals=None,
945945
locals=None,
946-
type_params=_sentinel,
946+
type_params=None,
947947
format=annotationlib.Format.VALUE,
948948
_recursive_guard=frozenset(),
949949
):
@@ -963,15 +963,12 @@ def evaluate_forward_ref(
963963
infer the namespaces to use for looking up names. *globals* and *locals*
964964
can also be explicitly given to provide the global and local namespaces.
965965
*type_params* is a tuple of type parameters that are in scope when
966-
evaluating the forward reference. This parameter must be provided (though
966+
evaluating the forward reference. This parameter should be provided (though
967967
it may be an empty tuple) if *owner* is not given and the forward reference
968968
does not already have an owner set. *format* specifies the format of the
969969
annotation and is a member of the annotationlib.Format enum.
970970
971971
"""
972-
if type_params is _sentinel:
973-
_deprecation_warning_for_no_type_params_passed("typing.evaluate_forward_ref")
974-
type_params = ()
975972
if format == annotationlib.Format.STRING:
976973
return forward_ref.__forward_arg__
977974
if forward_ref.__forward_arg__ in _recursive_guard:

0 commit comments

Comments
 (0)