diff --git a/midas/checker/frames/frame_manager.py b/midas/checker/frames/frame_manager.py index 74db171..72146b3 100644 --- a/midas/checker/frames/frame_manager.py +++ b/midas/checker/frames/frame_manager.py @@ -232,7 +232,7 @@ class FrameManager: if col.name == name: index = i replace = True - # TODO: check column type here to prevent changing it + # TODO: might want to check column type here to disallow changing it new_columns.append(col) new_col: DataFrameType.Column = DataFrameType.Column( diff --git a/midas/checker/python.py b/midas/checker/python.py index ef8e688..cb67492 100644 --- a/midas/checker/python.py +++ b/midas/checker/python.py @@ -454,7 +454,6 @@ class PythonTyper( self.env.define(stmt.name, function) def visit_type_assign(self, stmt: p.TypeAssign) -> None: - # TODO check not yet defined locally type: Type = self.resolve_type_expr(stmt.type) self.env.define(stmt.name, type) @@ -844,7 +843,7 @@ class PythonTyper( def visit_ternary_expr(self, expr: p.TernaryExpr) -> Type: test_type: Type = self.type_of(expr.test) - # TODO Allow subtypes or any type + # Strict: test must be a subtype of bool, or UnknownType if ( not self.is_subtype(test_type, self.types.get_type("bool")) and test_type != UnknownType() @@ -1154,8 +1153,9 @@ class PythonTyper( return False, None if key is None: - # TODO: check that value is always a dict - assert isinstance(value_val, dict) + # If literal value is not a dict, invalid Python -> abort + if not isinstance(value_val, dict): + return False, None pairs.extend(value_val.items()) else: pairs.append((key_val, value_val)) @@ -1281,9 +1281,7 @@ class PythonTyper( case BaseType(): # TODO: do we want to allow cast(float, int)? would require runtime conversion - if not self.types.is_subtype( - subject_type, target_type - ) or not self.types.is_subtype(target_type, subject_type): + if not self.types.are_equivalent(subject_type, target_type): self.reporter.error( expr.location, f"Value {lit_value!r} of type {subject_type} cannot be cast as {target_type}", diff --git a/midas/checker/registry.py b/midas/checker/registry.py index 0c97074..3ce265e 100644 --- a/midas/checker/registry.py +++ b/midas/checker/registry.py @@ -213,7 +213,6 @@ class TypesRegistry: return True case (ColumnType(type=inner1), ColumnType(type=inner2)): - # TODO: invariant, replace ColumnType with simple GenericType if not self.are_equivalent(inner1, inner2): return False return True diff --git a/midas/generator/generator.py b/midas/generator/generator.py index 08edda7..3cf2423 100644 --- a/midas/generator/generator.py +++ b/midas/generator/generator.py @@ -354,7 +354,6 @@ class Generator(p.Stmt.Visitor[ast.stmt], p.Expr.Visitor[ast.expr]): ) def visit_type_assign(self, stmt: p.TypeAssign) -> ast.stmt: - # TODO: is that ok? return ast.Pass() def visit_assign_stmt(self, stmt: p.AssignStmt) -> ast.stmt: diff --git a/midas/generator/stubs.py b/midas/generator/stubs.py index b228916..1875f93 100644 --- a/midas/generator/stubs.py +++ b/midas/generator/stubs.py @@ -53,7 +53,7 @@ class StubsGenerator: self.import_pandas = False for name, type in self.types._types.items(): # Skip builtin types, not just based on name so the user can override - # TODO: check if added members on builtin type + # TODO: check if added members on builtin type, or prevent it match type: case BaseType(name=name_) if name == name_: continue @@ -105,7 +105,9 @@ class StubsGenerator: """ base_type: Type = type - # TODO: improve + # Generate simple assignment for type aliases + # A type alias will have a name that is different from the type represents + # or will neither be a `DeriveType` nor a `GenericType` match type: case DerivedType(name=name_) | GenericType(name=name_) if name_ == name: pass