Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

bpo-40397: Refactor typing._GenericAlias #19719

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

Merged
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Refactor __getitem__.
  • Loading branch information
serhiy-storchaka committed May 2, 2020
commit ee37e56d6c2d726ffd9244e240a4af9eef57f273
74 changes: 37 additions & 37 deletions 74 Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,28 +186,6 @@ def _collect_type_vars(types):
return tuple(tvars)


def _subs_tvars(tp, tvars, subs):
"""Substitute type variables 'tvars' with substitutions 'subs'.
These two must have the same length.
"""
if not isinstance(tp, (_BaseGenericAlias, GenericAlias)):
return tp
new_args = list(tp.__args__)
for a, arg in enumerate(tp.__args__):
if isinstance(arg, TypeVar):
for i, tvar in enumerate(tvars):
if arg == tvar:
new_args[a] = subs[i]
else:
new_args[a] = _subs_tvars(arg, tvars, subs)
if tp.__origin__ is Union:
return Union[tuple(new_args)]
if isinstance(tp, GenericAlias):
return GenericAlias(tp.__origin__, tuple(new_args))
else:
return tp.copy_with(tuple(new_args))


def _check_generic(cls, parameters):
"""Check correct count for parameters of a generic cls (internal helper).
This gives a nice error message in case of count mismatch.
Expand Down Expand Up @@ -653,18 +631,6 @@ def __init__(self, origin, params, *, inst=True, name=None):
if not name:
self.__module__ = origin.__module__

@_tp_cache
def __getitem__(self, params):
if self.__origin__ in (Generic, Protocol):
# Can't subscript Generic[...] or Protocol[...].
raise TypeError(f"Cannot subscript already-subscripted {self}")
if not isinstance(params, tuple):
params = (params,)
msg = "Parameters to generic types must be types."
params = tuple(_type_check(p, msg) for p in params)
_check_generic(self, params)
return _subs_tvars(self, self.__parameters__, params)

def __eq__(self, other):
if not isinstance(other, _BaseGenericAlias):
return NotImplemented
Expand Down Expand Up @@ -719,6 +685,28 @@ def __subclasscheck__(self, cls):


class _GenericAlias(_BaseGenericAlias, _root=True):
@_tp_cache
def __getitem__(self, params):
if self.__origin__ in (Generic, Protocol):
# Can't subscript Generic[...] or Protocol[...].
raise TypeError(f"Cannot subscript already-subscripted {self}")
if not isinstance(params, tuple):
params = (params,)
msg = "Parameters to generic types must be types."
params = tuple(_type_check(p, msg) for p in params)
_check_generic(self, params)

subst = dict(zip(self.__parameters__, params))
new_args = []
for arg in self.__args__:
if isinstance(arg, TypeVar):
arg = subst[arg]
elif isinstance(arg, (_BaseGenericAlias, GenericAlias)):
subargs = tuple(subst[x] for x in arg.__parameters__)
arg = arg[subargs]
new_args.append(arg)
return self.copy_with(tuple(new_args))

def copy_with(self, params):
return self.__class__(self.__origin__, params, name=self._name, inst=self._inst)

Expand Down Expand Up @@ -764,6 +752,16 @@ def __init__(self, origin, params, *, inst=True, name=None):
super().__init__(origin, params, inst=inst, name=name)
self.__doc__ = f'A generic version of {origin.__module__}.{origin.__qualname__}'

@_tp_cache
def __getitem__(self, params):
if not isinstance(params, tuple):
params = (params,)
msg = "Parameters to generic types must be types."
params = tuple(_type_check(p, msg) for p in params)
_check_generic(self, params)
assert self.__args__ == self.__parameters__
return self.copy_with(params)

def copy_with(self, params):
return _GenericAlias(self.__origin__, params,
serhiy-storchaka marked this conversation as resolved.
Show resolved Hide resolved
name=self._name, inst=self._inst)
Expand Down Expand Up @@ -841,6 +839,9 @@ def __getitem__(self, params):


class _UnionGenericAlias(_GenericAlias, _root=True):
def copy_with(self, params):
return Union[params]

def __eq__(self, other):
if not isinstance(other, _UnionGenericAlias):
return NotImplemented
Expand Down Expand Up @@ -1172,9 +1173,8 @@ def __reduce__(self):
def __eq__(self, other):
if not isinstance(other, _AnnotatedAlias):
return NotImplemented
if self.__origin__ != other.__origin__:
return False
return self.__metadata__ == other.__metadata__
return (self.__origin__ == other.__origin__
and self.__metadata__ == other.__metadata__)

def __hash__(self):
return hash((self.__origin__, self.__metadata__))
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.