https://github.com/python/cpython/commit/5518c2ae09cd8f135981f362dabd000d44d26cac
commit: 5518c2ae09cd8f135981f362dabd000d44d26cac
branch: main
author: Jelle Zijlstra <jelle.zijls...@gmail.com>
committer: JelleZijlstra <jelle.zijls...@gmail.com>
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 -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to