It seems that mypy has a special case for type-checking tuples by index:
from typing_extensions import Unpack, TypeVarTuple
_Ts = TypeVarTuple("_Ts")
def tuple_get(t: tuple[Unpack[_Ts]], i: int) -> _Ts[i]:
return t[i]
def tuple_dynamic(t: tuple[int, str, float]) -> str:
return tuple_get(t, 1)
def tuple_static(t: tuple[int, str, float]) -> str:
return t[1]
If I run mypy, it says that types are correct for tuple_static
, but incorrect for tuple_dynamic
:
$ mypy mypy-tuple.py --strict
mypy-tuple.py:4: error: TypeVarTuple "_Ts" is only valid with an unpack [valid-type]
mypy-tuple.py:7: error: Returning Any from function declared to return "str" [no-any-return]
Found 2 errors in 1 file (checked 1 source file)
Is there a way to type tuple_get
such that tuple_dynamic
would pass mypy --strict
as written?
Context
I am trying to write a stub for the pyasn1 abstract type univ.Sequence
, which should behave like a combination of TypedDict and NamedTuple:
I would like to write a stub for VarBind as follows:
class VarBind(univ.Sequence[rfc1902.ObjectName, _BindValue]): ...
and have it cause this code to type-resolve as rfc1902.ObjectName
:
varBind.getComponentByPosition(0)
pyasn1 and pysnmp are older libraries that have barely migrated away from python2. pyasn1 in particular has a lot of conceptual similarities with pydantic (parser/serializer library where you define types at import time and validate them at runtime), but, without using any of the newer python3 features that make pydantic work (namely, Annotations and Metaclasses)