Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename typing._collect_parameters #118900

Merged
merged 6 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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,
Expand All @@ -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):
Expand Down
24 changes: 17 additions & 7 deletions Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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__'):
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
)
Expand Down Expand Up @@ -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
Expand Down
Loading