feat!: remove Python constraint type

this feature was only partially implemented (parsing) and the syntax was not ideal so this commit removes it entirely
This commit is contained in:
2026-07-09 14:15:36 +02:00
parent f314a95e87
commit 4d343a61ff
17 changed files with 29 additions and 209 deletions

View File

@@ -44,11 +44,6 @@ class BaseType:
args: tuple[MidasType, ...]
class ConstraintType:
type: MidasType
constraint: ast.expr
class FrameColumn:
name: Optional[str]
type: Optional[MidasType]

View File

@@ -18,14 +18,6 @@ class PythonAstPrinter(
self._write_line(f"base: {node.base}")
self._write_sequence("args", node.args, last=True)
def visit_constraint_type(self, node: p.ConstraintType) -> None:
self._write_line("ConstraintType")
with self._child_level():
self._write_line("type")
with self._child_level(single=True):
node.type.accept(self)
self._write_line(f"constraint: {ast.unparse(node.constraint)}", last=True)
def visit_frame_column(self, node: p.FrameColumn) -> None:
self._write_line("FrameColumn")
with self._child_level():

View File

@@ -52,9 +52,6 @@ class MidasType(ABC):
@abstractmethod
def visit_base_type(self, node: BaseType) -> T: ...
@abstractmethod
def visit_constraint_type(self, node: ConstraintType) -> T: ...
@abstractmethod
def visit_frame_column(self, node: FrameColumn) -> T: ...
@@ -71,15 +68,6 @@ class BaseType(MidasType):
return visitor.visit_base_type(self)
@dataclass(frozen=True)
class ConstraintType(MidasType):
type: MidasType
constraint: ast.expr
def accept(self, visitor: MidasType.Visitor[T]) -> T:
return visitor.visit_constraint_type(self)
@dataclass(frozen=True)
class FrameColumn(MidasType):
name: Optional[str]

View File

@@ -985,10 +985,6 @@ class PythonTyper(
return self.types.apply_generic(base, args)
return base
def visit_constraint_type(self, node: p.ConstraintType) -> Type:
self.reporter.warning(node.location, "ConstraintType not yet supported")
return UnknownType()
def visit_frame_column(self, node: p.FrameColumn) -> ColumnType:
return ColumnType(
type=(

View File

@@ -437,8 +437,8 @@ def to_annotation(type: Type) -> str:
case AppliedType(name=name, args=args):
return f"{name}[{', '.join(map(to_annotation, args))}]"
case ConstraintType():
return str(type)
case ConstraintType(type=base):
return to_annotation(base)
case TupleType(items=items):
return f"Tuple[{', '.join(map(to_annotation, items))}]"

View File

@@ -138,10 +138,6 @@ class PythonHighlighter(
self.wrap(arg, "arg")
arg.accept(self)
def visit_constraint_type(self, node: p.ConstraintType) -> None:
self.wrap(node, "constraint-type")
node.type.accept(self)
def visit_frame_column(self, node: p.FrameColumn) -> None:
self.wrap(node, "frame-column")
if node.type is not None:

View File

@@ -7,10 +7,6 @@ span {
--col: 103, 192, 224;
}
&.constraint-type {
--col: 174, 200, 195;
}
&.frame-column {
--col: 216, 231, 81;
}

View File

@@ -9,7 +9,6 @@ from midas.ast.python import (
CallExpr,
CastExpr,
CompareExpr,
ConstraintType,
DictExpr,
Expr,
ExpressionStmt,
@@ -337,30 +336,6 @@ class PythonParser:
args=(),
)
case ast.BinOp(left=left_expr, op=ast.Add(), right=right_expr):
left = self._parse_type(left_expr)
match left:
# If chained constraints, separate base type and rebuild constraint
case ConstraintType(type=left_type, constraint=left_constraint):
constraint = ast.BinOp(
left=left_constraint,
op=ast.Add(),
right=right_expr,
)
ast.copy_location(constraint, type_expr)
return ConstraintType(
location=loc,
type=left_type,
constraint=constraint,
)
case _:
return ConstraintType(
location=loc,
type=left,
constraint=right_expr,
)
case ast.Constant(value=None):
return BaseType(
location=loc,

View File

@@ -5,7 +5,7 @@ from __future__ import annotations
df: Frame[
verified: bool,
birth_year: int,
height: float + ( _ > 0 ) + ( _ < 250 ),
height: float,
name: str,
date: datetime,
float,

View File

@@ -1,19 +1,5 @@
{
"diagnostics": [
{
"type": "Warning",
"location": {
"start": [
8,
12
],
"end": [
8,
43
]
},
"message": "ConstraintType not yet supported"
},
{
"type": "Warning",
"location": {

View File

@@ -5,7 +5,7 @@ from __future__ import annotations
df: Frame[
verified: bool,
birth_year: int,
height: float + ( _ > 0 ) + ( _ < 250 ),
height: float,
name: str,
date: datetime,
float,

View File

@@ -40,13 +40,9 @@
"_type": "FrameColumn",
"name": "height",
"type": {
"_type": "ConstraintType",
"type": {
"_type": "BaseType",
"base": "float",
"args": []
},
"constraint": "(_ > 0) + (_ < 250)"
"_type": "BaseType",
"base": "float",
"args": []
}
},
{

View File

@@ -16,10 +16,6 @@ lat2: Latitude = lat[1]
lat_diff: Difference[Latitude] = lat2 - lat1
df2: Frame[
age: int + (_ >= 0),
height: float + (_ >= 0),
]
df2_bis: Frame[
age: int + Positive,
height: float + Positive,
age: int,
height: float,
]

View File

@@ -227,61 +227,18 @@
"_type": "FrameColumn",
"name": "age",
"type": {
"_type": "ConstraintType",
"type": {
"_type": "BaseType",
"base": "int",
"args": []
},
"constraint": "_ >= 0"
"_type": "BaseType",
"base": "int",
"args": []
}
},
{
"_type": "FrameColumn",
"name": "height",
"type": {
"_type": "ConstraintType",
"type": {
"_type": "BaseType",
"base": "float",
"args": []
},
"constraint": "_ >= 0"
}
}
]
}
},
{
"_type": "TypeAssign",
"name": "df2_bis",
"type": {
"_type": "FrameType",
"columns": [
{
"_type": "FrameColumn",
"name": "age",
"type": {
"_type": "ConstraintType",
"type": {
"_type": "BaseType",
"base": "int",
"args": []
},
"constraint": "Positive"
}
},
{
"_type": "FrameColumn",
"name": "height",
"type": {
"_type": "ConstraintType",
"type": {
"_type": "BaseType",
"base": "float",
"args": []
},
"constraint": "Positive"
"_type": "BaseType",
"base": "float",
"args": []
}
}
]

View File

@@ -4,11 +4,10 @@ from __future__ import annotations
def func(
col1: Column[float + (0 <= _ <= 1)],
col2: Column[float + (0 <= _ <= 1)],
) -> Column[float + (0 <= _ <= 2)]:
result: Column[float + (0 <= _ <= 2)] = col1 + col2
return result
col1: Column[float],
col2: Column[float],
) -> Column[float]:
return col1 + col2
def func2(a: int, /, b: float, *, c: str):

View File

@@ -26,13 +26,9 @@
"base": "Column",
"args": [
{
"_type": "ConstraintType",
"type": {
"_type": "BaseType",
"base": "float",
"args": []
},
"constraint": "0 <= _ <= 1"
"_type": "BaseType",
"base": "float",
"args": []
}
]
},
@@ -45,13 +41,9 @@
"base": "Column",
"args": [
{
"_type": "ConstraintType",
"type": {
"_type": "BaseType",
"base": "float",
"args": []
},
"constraint": "0 <= _ <= 1"
"_type": "BaseType",
"base": "float",
"args": []
}
]
},
@@ -65,44 +57,15 @@
"base": "Column",
"args": [
{
"_type": "ConstraintType",
"type": {
"_type": "BaseType",
"base": "float",
"args": []
},
"constraint": "0 <= _ <= 2"
"_type": "BaseType",
"base": "float",
"args": []
}
]
},
"body": [
{
"_type": "TypeAssign",
"name": "result",
"type": {
"_type": "BaseType",
"base": "Column",
"args": [
{
"_type": "ConstraintType",
"type": {
"_type": "BaseType",
"base": "float",
"args": []
},
"constraint": "0 <= _ <= 2"
}
]
}
},
{
"_type": "AssignStmt",
"targets": [
{
"_type": "VariableExpr",
"name": "result"
}
],
"_type": "ReturnStmt",
"value": {
"_type": "BinaryExpr",
"left": {
@@ -115,13 +78,6 @@
"name": "col2"
}
}
},
{
"_type": "ReturnStmt",
"value": {
"_type": "VariableExpr",
"name": "result"
}
}
]
},

View File

@@ -8,7 +8,6 @@ from midas.ast.python import (
CallExpr,
CastExpr,
CompareExpr,
ConstraintType,
DictExpr,
Expr,
ExpressionStmt,
@@ -106,13 +105,6 @@ class PythonAstJsonSerializer(
"args": self._serialize_list(node.args),
}
def visit_constraint_type(self, node: ConstraintType) -> dict:
return {
"_type": "ConstraintType",
"type": node.type.accept(self),
"constraint": ast.unparse(node.constraint),
}
def visit_frame_column(self, node: FrameColumn) -> dict:
return {
"_type": "FrameColumn",