https://github.com/python/cpython/commit/5518c2ae09cd8f135981f362dabd000d44d26cac
commit: 5518c2ae09cd8f135981f362dabd000d44d26cac
branch: main
author: Jelle Zijlstra <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2025-04-03T09:52:17-07:00
summary:
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=()".
files:
M Doc/library/annotationlib.rst
M Doc/library/typing.rst
M Lib/test/test_typing.py
M Lib/typing.py
diff --git a/Doc/library/annotationlib.rst b/Doc/library/annotationlib.rst
index dcaff3d7fdbec5..ab9393e8cd8ab7 100644
--- a/Doc/library/annotationlib.rst
+++ b/Doc/library/annotationlib.rst
@@ -172,15 +172,31 @@ Classes
:class:`~ForwardRef`. The string may not be exactly equivalent
to the original source.
- .. method:: evaluate(*, globals=None, locals=None, type_params=None,
owner=None)
+ .. method:: evaluate(*, owner=None, globals=None, locals=None,
type_params=None)
Evaluate the forward reference, returning its value.
This may throw an exception, such as :exc:`NameError`, if the forward
- reference refers to names that do not exist. The arguments to this
+ reference refers to a name that cannot be resolved. The arguments to this
method can be used to provide bindings for names that would otherwise
be undefined.
+ The *owner* parameter provides the preferred mechanism for passing scope
+ information to this method. The owner of a :class:`~ForwardRef` is the
+ object that contains the annotation from which the :class:`~ForwardRef`
+ derives, such as a module object, type object, or function object.
+
+ The *globals*, *locals*, and *type_params* parameters provide a more
precise
+ mechanism for influencing the names that are available when the
:class:`~ForwardRef`
+ is evaluated. *globals* and *locals* are passed to :func:`eval`,
representing
+ the global and local namespaces in which the name is evaluated.
+ The *type_params* parameter is relevant for objects created using the
native
+ syntax for :ref:`generic classes <generic-classes>` and :ref:`functions
<generic-functions>`.
+ It is a tuple of :ref:`type parameters <type-params>` that are in scope
+ while the forward reference is being evaluated. For example, if
evaluating a
+ :class:`~ForwardRef` retrieved from an annotation found in the class
namespace
+ of a generic class ``C``, *type_params* should be set to
``C.__type_params__``.
+
:class:`~ForwardRef` instances returned by :func:`get_annotations`
retain references to information about the scope they originated from,
so calling this method with no further arguments may be sufficient to
@@ -188,14 +204,6 @@ Classes
means may not have any information about their scope, so passing
arguments to this method may be necessary to evaluate them successfully.
- *globals* and *locals* are passed to :func:`eval`, representing
- the global and local namespaces in which the name is evaluated.
- *type_params*, if given, must be a tuple of
- :ref:`type parameters <type-params>` that are in scope while the forward
- reference is being evaluated. *owner* is the object that owns the
- annotation from which the forward reference derives, usually a function,
- class, or module.
-
.. important::
Once a :class:`~ForwardRef` instance has been evaluated, it caches
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index 99394b01a3d9ce..d5870498fa35b9 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -3466,16 +3466,8 @@ Introspection helpers
* Supports the :attr:`~annotationlib.Format.FORWARDREF` and
:attr:`~annotationlib.Format.STRING` formats.
- *forward_ref* must be an instance of :class:`~annotationlib.ForwardRef`.
- *owner*, if given, should be the object that holds the annotations that
- the forward reference derived from, such as a module, class object, or
function.
- It is used to infer the namespaces to use for looking up names.
- *globals* and *locals* can also be explicitly given to provide
- the global and local namespaces.
- *type_params* is a tuple of :ref:`type parameters <type-params>` that
- are in scope when evaluating the forward reference.
- This parameter must be provided (though it may be an empty tuple) if *owner*
- is not given and the forward reference does not already have an owner set.
+ See the documentation for :meth:`annotationlib.ForwardRef.evaluate` for
+ the meaning of the *owner*, *globals*, *locals*, and *type_params*
parameters.
*format* specifies the format of the annotation and is a member of
the :class:`annotationlib.Format` enum.
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 2c0297313cb4ab..97d3a927160b8f 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -7311,20 +7311,7 @@ def test_evaluate_forward_ref(self):
def test_evaluate_forward_ref_no_type_params(self):
ref = ForwardRef('int')
- with self.assertWarnsRegex(
- DeprecationWarning,
- (
- "Failing to pass a value to the 'type_params' parameter "
- "of 'typing.evaluate_forward_ref' is deprecated, "
- "as it leads to incorrect behaviour"
- ),
- ):
- typing.evaluate_forward_ref(ref)
-
- # No warnings when `type_params` is passed:
- with warnings.catch_warnings(record=True) as w:
- typing.evaluate_forward_ref(ref, type_params=())
- self.assertEqual(w, [])
+ self.assertIs(typing.evaluate_forward_ref(ref), int)
class CollectionsAbcTests(BaseTestCase):
diff --git a/Lib/typing.py b/Lib/typing.py
index f7528258f43453..707c05d504065c 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -943,7 +943,7 @@ def evaluate_forward_ref(
owner=None,
globals=None,
locals=None,
- type_params=_sentinel,
+ type_params=None,
format=annotationlib.Format.VALUE,
_recursive_guard=frozenset(),
):
@@ -963,15 +963,12 @@ def evaluate_forward_ref(
infer the namespaces to use for looking up names. *globals* and *locals*
can also be explicitly given to provide the global and local namespaces.
*type_params* is a tuple of type parameters that are in scope when
- evaluating the forward reference. This parameter must be provided (though
+ evaluating the forward reference. This parameter should be provided (though
it may be an empty tuple) if *owner* is not given and the forward reference
does not already have an owner set. *format* specifies the format of the
annotation and is a member of the annotationlib.Format enum.
"""
- if type_params is _sentinel:
-
_deprecation_warning_for_no_type_params_passed("typing.evaluate_forward_ref")
- type_params = ()
if format == annotationlib.Format.STRING:
return forward_ref.__forward_arg__
if forward_ref.__forward_arg__ in _recursive_guard:
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]