feat(types): add TupleType

This commit is contained in:
2026-06-23 12:26:39 +02:00
parent cf083fc0c3
commit 5e9ccd4e13
2 changed files with 38 additions and 0 deletions

View File

@@ -27,6 +27,7 @@ from midas.checker.types import (
Function,
GenericType,
OverloadedFunction,
TupleType,
Type,
TypeVar,
UnitType,
@@ -642,6 +643,11 @@ class PythonTyper(
def visit_subscript_expr(self, expr: p.SubscriptExpr) -> Type:
object: Type = self.type_of(expr.object)
unfolded: Type = unfold_type(object)
match unfolded:
case TupleType():
return self._visit_tuple_subscript(unfolded, expr)
operation: Optional[Type] = self.types.lookup_member(object, "__getitem__")
if operation is None:
self.reporter.error(
@@ -1231,3 +1237,18 @@ class PythonTyper(
expr.location, f"Cannot evaluate cast to {target_type} statically"
)
return False
def _visit_tuple_subscript(self, tup: TupleType, expr: p.SubscriptExpr) -> Type:
match expr.index:
case p.LiteralExpr(value=int() as index):
if index < 0 or index >= len(tup.items):
self.reporter.error(
expr.location, f"Index {index} out of range for tuple {tup}"
)
return UnknownType()
return tup.items[index]
case _:
self.reporter.error(
expr.location, f"Invalid index type {expr.index} on {tup}"
)
return UnknownType()

View File

@@ -156,6 +156,14 @@ class ConstraintType:
return f"{self.type} where {printer.print(self.constraint)}"
@dataclass(frozen=True, kw_only=True)
class TupleType:
items: tuple[Type, ...]
def __str__(self) -> str:
return f"({', '.join(map(str, self.items))})"
@dataclass(frozen=True, kw_only=True)
class ColumnType:
type: Type
@@ -280,6 +288,11 @@ def substitute_typevars(type: Type, substitutions: dict[str, Type]) -> Type:
body=substitute_typevars(body, substitutions),
)
case TupleType(items=items):
return TupleType(
items=tuple(substitute_typevars(item, substitutions) for item in items),
)
case ColumnType(type=items_type):
return ColumnType(
type=substitute_typevars(items_type, substitutions),
@@ -358,6 +371,9 @@ def to_annotation(type: Type) -> str:
case ConstraintType():
return str(type)
case TupleType(items=items):
return f"Tuple[{', '.join(map(to_annotation, items))}]"
case ColumnType():
return "pd.Series"
@@ -389,6 +405,7 @@ Type = (
| GenericType
| AppliedType
| ConstraintType
| TupleType
| ColumnType
| DataFrameType
)