Skip to content
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
Merge branch 'main' into fix-typevar-test
  • Loading branch information
serhiy-storchaka committed Jun 21, 2022
commit a7a6074f6b38621eea867f526b2e10fb6f67ff52
87 changes: 87 additions & 0 deletions Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -1014,10 +1014,97 @@ def __init__(self, name, *constraints, bound=None,
if def_mod != 'typing':
self.__module__ = def_mod

def __typing_subst__(self, arg):
msg = "Parameters to generic types must be types."
arg = _type_check(arg, msg, is_argument=True)
if ((isinstance(arg, _GenericAlias) and arg.__origin__ is Unpack) or
(isinstance(arg, GenericAlias) and getattr(arg, '__unpacked__', False))):
raise TypeError(f"{arg} is not valid as type argument")
return arg

def __mro_entries__(self, bases):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be added not here, but in _TypeVarLike. ParamSpec instances are not subclassable too.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And add it also in TypeVarTuple.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! I'll get to this soon and ping you when done (I'm currently in the process of moving across the country and starting a job)

raise TypeError("Cannot subclass an instance of TypeVar.")


class TypeVarTuple(_Final, _Immutable, _PickleUsingNameMixin, _root=True):
"""Type variable tuple.

Usage:

Ts = TypeVarTuple('Ts') # Can be given any name

Just as a TypeVar (type variable) is a placeholder for a single type,
a TypeVarTuple is a placeholder for an *arbitrary* number of types. For
example, if we define a generic class using a TypeVarTuple:

class C(Generic[*Ts]): ...

Then we can parameterize that class with an arbitrary number of type
arguments:

C[int] # Fine
C[int, str] # Also fine
C[()] # Even this is fine

For more details, see PEP 646.

Note that only TypeVarTuples defined in global scope can be pickled.
"""

def __init__(self, name):
self.__name__ = name

# Used for pickling.
def_mod = _caller()
if def_mod != 'typing':
self.__module__ = def_mod

def __iter__(self):
yield Unpack[self]

def __repr__(self):
return self.__name__

def __typing_subst__(self, arg):
raise TypeError("Substitution of bare TypeVarTuple is not supported")

def __typing_prepare_subst__(self, alias, args):
params = alias.__parameters__
typevartuple_index = params.index(self)
for param in enumerate(params[typevartuple_index + 1:]):
if isinstance(param, TypeVarTuple):
raise TypeError(f"More than one TypeVarTuple parameter in {alias}")

alen = len(args)
plen = len(params)
left = typevartuple_index
right = plen - typevartuple_index - 1
var_tuple_index = None
fillarg = None
for k, arg in enumerate(args):
if not isinstance(arg, type):
subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)
if subargs and len(subargs) == 2 and subargs[-1] is ...:
if var_tuple_index is not None:
raise TypeError("More than one unpacked arbitrary-length tuple argument")
var_tuple_index = k
fillarg = subargs[0]
if var_tuple_index is not None:
left = min(left, var_tuple_index)
right = min(right, alen - var_tuple_index - 1)
elif left + right > alen:
raise TypeError(f"Too few arguments for {alias};"
f" actual {alen}, expected at least {plen-1}")

return (
*args[:left],
*([fillarg]*(typevartuple_index - left)),
tuple(args[left: alen - right]),
*([fillarg]*(plen - right - left - typevartuple_index - 1)),
*args[alen - right:],
)


class ParamSpecArgs(_Final, _Immutable, _root=True):
"""The args for a ParamSpec object.

Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.