Description
C++11 recently introduced the notion of variadic templates, which I believe Python could benefit from in a simplified form.
The idea is that you can have a generic class with a variable number of type variables, like typing.Tuple[]
has. Here is a real-world variadic-generic class which is not Tuple
; it is variadic in TagVar
. As you can see, TagVar
only appears in tuple contexts. Those tuples are sometimes heterogenous (Caution: annotations are a homegrown 3.4-compatible mishmash of nonsense), so repeating TagVar
as shown is actually incorrect (but the closest approximation I could find).
Here's one possible syntax:
class MultiField(AbstractField[GetSetVar], Generic[(*TagVar,)]):
def __init__(self, nbt_names: ty.Sequence[str], *, default:
GetSetVar=None) -> None:
...
@abc.abstractmethod
def to_python(self, *tags: (*TagVar,)) -> GetSetVar:
...
@abc.abstractmethod
def from_python(self, value: GetSetVar) -> ty.Tuple[(*TagVar,)]:
...
This is syntactically valid in Python 3.5 (if a bit ugly with the parentheses and trailing comma, which cannot be omitted without language changes), but doesn't currently work because type variables are not sequences and cannot be unpacked. It could be implemented by adding something like this to the TypeVar class:
def __iter__(self):
yield StarredTypeVar(self)
StarredTypeVar would be a wrapper class that prefixes the repr with a star and delegates all other functionality to the wrapped TypeVar.
Of course, syntax isn't everything; I'd be fine with any syntax that lets me do this. The other immediately obvious syntax is to follow the TypeVar with an ellipsis, which conveniently does not require changes to typing.py. However, that might require disambiguation in some contexts (particularly since Tuple
is likely to be involved with these classes).