Skip to content

Commit 22a8bef

Browse files
committed
experiment
1 parent d5feeb1 commit 22a8bef

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

src/typing_extensions.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3203,6 +3203,13 @@ def _is_unpacked_typevartuple(x) -> bool:
32033203
)
32043204

32053205

3206+
def _is_typevar_like(x: Any) -> bool:
3207+
tv_types = (TypeVar, ParamSpec, typing.TypeVar)
3208+
if hasattr("typing", "ParamSpec"):
3209+
tv_types += typing.ParamSpec
3210+
return isinstance(x, tv_types) or _is_unpacked_typevartuple(x)
3211+
3212+
32063213
# Python 3.11+ _collect_type_vars was renamed to _collect_parameters
32073214
if hasattr(typing, '_collect_type_vars'):
32083215
def _collect_type_vars(types, typevar_types=None):
@@ -4257,6 +4264,60 @@ def type_repr(value):
42574264
return repr(value)
42584265

42594266

4267+
if sys.version_info < (3, 11):
4268+
def _generic_class_getitem(cls, params):
4269+
"""Parameterizes a generic class.
4270+
4271+
At least, parameterizing a generic class is the *main* thing this method
4272+
does. For example, for some generic class `Foo`, this is called when we
4273+
do `Foo[int]` - there, with `cls=Foo` and `params=int`.
4274+
4275+
However, note that this method is also called when defining generic
4276+
classes in the first place with `class Foo(Generic[T]): ...`.
4277+
"""
4278+
if not isinstance(params, tuple):
4279+
params = (params,)
4280+
4281+
params = tuple(typing._type_convert(p) for p in params)
4282+
if cls in (Generic, Protocol):
4283+
# Generic and Protocol can only be subscripted with unique type variables.
4284+
if not params:
4285+
raise TypeError(
4286+
f"Parameter list to {cls.__qualname__}[...] cannot be empty"
4287+
)
4288+
if not all(_is_typevar_like(p) for p in params):
4289+
raise TypeError(
4290+
f"Parameters to {cls.__name__}[...] must all be type variables "
4291+
f"or parameter specification variables."
4292+
)
4293+
if len(set(params)) != len(params):
4294+
raise TypeError(
4295+
f"Parameters to {cls.__name__}[...] must all be unique"
4296+
)
4297+
else:
4298+
# Subscripting a regular Generic subclass.
4299+
for param in cls.__parameters__:
4300+
prepare = getattr(param, '__typing_prepare_subst__', None)
4301+
if prepare is not None:
4302+
params = prepare(cls, params)
4303+
_check_generic(cls, params, len(cls.__parameters__))
4304+
4305+
new_args = []
4306+
for param, new_arg in zip(cls.__parameters__, params):
4307+
if isinstance(param, TypeVarTuple):
4308+
new_args.extend(new_arg)
4309+
else:
4310+
new_args.append(new_arg)
4311+
params = tuple(new_args)
4312+
4313+
return typing._GenericAlias(
4314+
cls, params,
4315+
_paramspec_tvars=True
4316+
)
4317+
4318+
typing.Generic.__class_getitem__ = classmethod(_generic_class_getitem)
4319+
4320+
42604321
# Aliases for items that are in typing in all supported versions.
42614322
# We use hasattr() checks so this library will continue to import on
42624323
# future versions of Python that may remove these names.

0 commit comments

Comments
 (0)