U = TypeVar("U", covariant=True)
class IterableAndSized(Protocol[U], Sized, Iterable[U]): ...
I want to make a protocol as above that uses the Sized and Iterable abstract base classes to define an acceptable type; e.g.
T = TypeVar("T")
def tailvalue(index_from_rear: int, x: Iterable[T] | IterableAndSized[T]) -> T
if isinstance(x, Sized):
for i, val in enumerate(x):
if i == len(x) - index_from_rear:
return val
return list(x)[-index_from_rear]
this can help optimise retrieving values near the end of a generator expression.
Why do I need
TypeVar("U", covariant=True) rather than just TypeVar("U") there? IIUC it means subtypes are permitted or something, I'm sure that's okay but I don't know why it's a requirement here