https://github.com/python/cpython/commit/ec9d12be9648ee60a2eb02d67069d74f8b314df9
commit: ec9d12be9648ee60a2eb02d67069d74f8b314df9
branch: main
author: Jelle Zijlstra <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2024-05-10T16:55:49Z
summary:
Rename typing._collect_parameters (#118900)
Unfortunately, released versions of typing_extensions
monkeypatch this function without the extra parameter, which makes
it so things break badly if current main is used with typing_extensions.
Fortunately, the monkeypatching is not needed on Python 3.13, because CPython
now implements PEP 696. By renaming the function, we prevent the monkeypatch
from breaking typing.py internals.
We keep the old name (raising a DeprecationWarning) to help other external
users who call it.
files:
M Lib/test/test_typing.py
M Lib/typing.py
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 81fea41e9b9823..f10b0aea3cd7b9 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -45,7 +45,7 @@
import weakref
import types
-from test.support import captured_stderr, cpython_only, infinite_recursion,
requires_docstrings
+from test.support import captured_stderr, cpython_only, infinite_recursion,
requires_docstrings, import_helper
from test.typinganndata import ann_module695, mod_generics_cache,
_typed_dict_helper
@@ -6325,6 +6325,8 @@ def test_or(self):
self.assertEqual(X | "x", Union[X, "x"])
self.assertEqual("x" | X, Union["x", X])
+
+class InternalsTests(BaseTestCase):
def test_deprecation_for_no_type_params_passed_to__evaluate(self):
with self.assertWarnsRegex(
DeprecationWarning,
@@ -6350,6 +6352,15 @@ def
test_deprecation_for_no_type_params_passed_to__evaluate(self):
self.assertEqual(cm.filename, __file__)
+ def test_collect_parameters(self):
+ typing = import_helper.import_fresh_module("typing")
+ with self.assertWarnsRegex(
+ DeprecationWarning,
+ "The private _collect_parameters function is deprecated"
+ ) as cm:
+ typing._collect_parameters
+ self.assertEqual(cm.filename, __file__)
+
@lru_cache()
def cached_func(x, y):
diff --git a/Lib/typing.py b/Lib/typing.py
index e75a627d226e50..434574559e04fc 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -256,15 +256,15 @@ def _type_repr(obj):
return repr(obj)
-def _collect_parameters(args, *, enforce_default_ordering: bool = True):
- """Collect all type variables and parameter specifications in args
+def _collect_type_parameters(args, *, enforce_default_ordering: bool = True):
+ """Collect all type parameters in args
in order of first appearance (lexicographic order).
For example::
>>> P = ParamSpec('P')
>>> T = TypeVar('T')
- >>> _collect_parameters((T, Callable[P, T]))
+ >>> _collect_type_parameters((T, Callable[P, T]))
(~T, ~P)
"""
# required type parameter cannot appear after parameter with default
@@ -280,7 +280,7 @@ def _collect_parameters(args, *, enforce_default_ordering:
bool = True):
# `t` might be a tuple, when `ParamSpec` is substituted with
# `[T, int]`, or `[int, *Ts]`, etc.
for x in t:
- for collected in _collect_parameters([x]):
+ for collected in _collect_type_parameters([x]):
if collected not in parameters:
parameters.append(collected)
elif hasattr(t, '__typing_subst__'):
@@ -320,7 +320,7 @@ def _check_generic_specialization(cls, arguments):
if actual_len < expected_len:
# If the parameter at index `actual_len` in the parameters list
# has a default, then all parameters after it must also have
- # one, because we validated as much in _collect_parameters().
+ # one, because we validated as much in _collect_type_parameters().
# That means that no error needs to be raised here, despite
# the number of arguments being passed not matching the number
# of parameters: all parameters that aren't explicitly
@@ -1255,7 +1255,7 @@ def _generic_init_subclass(cls, *args, **kwargs):
if error:
raise TypeError("Cannot inherit from plain Generic")
if '__orig_bases__' in cls.__dict__:
- tvars = _collect_parameters(cls.__orig_bases__)
+ tvars = _collect_type_parameters(cls.__orig_bases__)
# Look for Generic[T1, ..., Tn].
# If found, tvars must be a subset of it.
# If not found, tvars is it.
@@ -1417,7 +1417,7 @@ def __init__(self, origin, args, *, inst=True, name=None):
self.__args__ = tuple(... if a is _TypingEllipsis else
a for a in args)
enforce_default_ordering = origin in (Generic, Protocol)
- self.__parameters__ = _collect_parameters(
+ self.__parameters__ = _collect_type_parameters(
args,
enforce_default_ordering=enforce_default_ordering,
)
@@ -3770,6 +3770,16 @@ def __getattr__(attr):
elif attr in {"ContextManager", "AsyncContextManager"}:
import contextlib
obj = _alias(getattr(contextlib, f"Abstract{attr}"), 2, name=attr,
defaults=(bool | None,))
+ elif attr == "_collect_parameters":
+ import warnings
+
+ depr_message = (
+ "The private _collect_parameters function is deprecated and will
be"
+ " removed in a future version of Python. Any use of private
functions"
+ " is discouraged and may break in the future."
+ )
+ warnings.warn(depr_message, category=DeprecationWarning, stacklevel=2)
+ obj = _collect_type_parameters
else:
raise AttributeError(f"module {__name__!r} has no attribute {attr!r}")
globals()[attr] = obj
_______________________________________________
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]