From 309e1d4a5b5968b721dc057490bf9f92901cb8d2 Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Thu, 9 Jul 2026 22:04:39 +0200 Subject: [PATCH] tests: add generator test for simple syntax --- tests/cases/generator/03_simple_syntax.py | 49 ++++ .../generator/03_simple_syntax.py.ref.txt | 249 ++++++++++++++++++ tests/generator.py | 10 +- 3 files changed, 303 insertions(+), 5 deletions(-) create mode 100644 tests/cases/generator/03_simple_syntax.py create mode 100644 tests/cases/generator/03_simple_syntax.py.ref.txt diff --git a/tests/cases/generator/03_simple_syntax.py b/tests/cases/generator/03_simple_syntax.py new file mode 100644 index 0000000..9bf70f5 --- /dev/null +++ b/tests/cases/generator/03_simple_syntax.py @@ -0,0 +1,49 @@ +# type: ignore +# ruff: disable[F821] + +import module1 +import module2 as alias2 +from module3 import submodule3 +from module4 import submodule4 as alias4 + +a: int +b: Generic[int] +c: Generic2[int, float] +d: Frame[a:int, b:float] + +e = 3 +f: int = 4 +g = [] +h = [1, 0.1, " ", None, False, True] +i = {} +j = {"a": 1, "b": 2} +k = {"c": 3, **j} +l = cast(int, a) +m = unsafe_cast(int, a) + + +def n(a: int, /, b: float, *, c: str) -> Any: + return + + +def o(a: int = 1, /, b: float = 2.0, *, c: str = "") -> Any: + return 1 + + +for i in h: + pass + +if e == f: + pass +elif f == g: + pass +else: + pass + +p = +a + -b - ~c * d / e**f +q = not (a and b) or c +r = a & b | c ^ d + +s = a.b.c +t = a[b][c, d][e:f] +u = a(b)(c=d) diff --git a/tests/cases/generator/03_simple_syntax.py.ref.txt b/tests/cases/generator/03_simple_syntax.py.ref.txt new file mode 100644 index 0000000..4c67e28 --- /dev/null +++ b/tests/cases/generator/03_simple_syntax.py.ref.txt @@ -0,0 +1,249 @@ +Module( + body=[ + Import( + names=[ + alias(name='module1')]), + Import( + names=[ + alias(name='module2', asname='alias2')]), + ImportFrom( + module='module3', + names=[ + alias(name='submodule3')], + level=0), + ImportFrom( + module='module4', + names=[ + alias(name='submodule4', asname='alias4')], + level=0), + Assign( + targets=[ + Name(id='e')], + value=Constant(value=3)), + Assign( + targets=[ + Name(id='f')], + value=Constant(value=4)), + Assign( + targets=[ + Name(id='g')], + value=List(elts=[])), + Assign( + targets=[ + Name(id='h')], + value=List( + elts=[ + Constant(value=1), + Constant(value=0.1), + Constant(value=' '), + Constant(value=None), + Constant(value=False), + Constant(value=True)])), + Assign( + targets=[ + Name(id='i')], + value=Dict(keys=[], values=[])), + Assign( + targets=[ + Name(id='j')], + value=Dict( + keys=[ + Constant(value='a'), + Constant(value='b')], + values=[ + Constant(value=1), + Constant(value=2)])), + Assign( + targets=[ + Name(id='k')], + value=Dict( + keys=[ + Constant(value='c'), + None], + values=[ + Constant(value=3), + Name(id='j')])), + Assign( + targets=[ + Name(id='__midas_a0__')], + value=Name(id='a')), + Assert( + test=Call( + func=Name(id='isinstance'), + args=[ + Name(id='__midas_a0__'), + Name(id='int')], + keywords=[]), + msg=JoinedStr( + values=[ + Constant(value='03_simple_syntax.py:L21:5: CastError: Cannot cast '), + FormattedValue( + value=Attribute( + value=Call( + func=Name(id='type'), + args=[ + Name(id='__midas_a0__')], + keywords=[]), + attr='__name__'), + conversion=-1), + Constant(value=' to int')])), + Assign( + targets=[ + Name(id='l')], + value=Name(id='__midas_a0__')), + Delete( + targets=[ + Name(id='__midas_a0__')]), + Assign( + targets=[ + Name(id='m')], + value=Name(id='a')), + FunctionDef( + name='n', + args=arguments( + posonlyargs=[ + arg(arg='a')], + args=[ + arg(arg='b')], + kwonlyargs=[ + arg(arg='c')], + kw_defaults=[ + None], + defaults=[]), + body=[ + Return()], + decorator_list=[]), + FunctionDef( + name='o', + args=arguments( + posonlyargs=[ + arg(arg='a')], + args=[ + arg(arg='b')], + kwonlyargs=[ + arg(arg='c')], + kw_defaults=[ + Constant(value='')], + defaults=[ + Constant(value=1), + Constant(value=2.0)]), + body=[ + Return( + value=Constant(value=1))], + decorator_list=[]), + For( + target=Name(id='i'), + iter=Name(id='h'), + body=[ + Pass()], + orelse=[]), + If( + test=Compare( + left=Name(id='e'), + ops=[ + Eq()], + comparators=[ + Name(id='f')]), + body=[ + Pass()], + orelse=[ + If( + test=Compare( + left=Name(id='f'), + ops=[ + Eq()], + comparators=[ + Name(id='g')]), + body=[ + Pass()], + orelse=[])]), + Assign( + targets=[ + Name(id='p')], + value=BinOp( + left=BinOp( + left=UnaryOp( + op=UAdd(), + operand=Name(id='a')), + op=Add(), + right=UnaryOp( + op=USub(), + operand=Name(id='b'))), + op=Sub(), + right=BinOp( + left=BinOp( + left=UnaryOp( + op=Invert(), + operand=Name(id='c')), + op=Mult(), + right=Name(id='d')), + op=Div(), + right=BinOp( + left=Name(id='e'), + op=Pow(), + right=Name(id='f'))))), + Assign( + targets=[ + Name(id='q')], + value=BoolOp( + op=Or(), + values=[ + UnaryOp( + op=Not(), + operand=BoolOp( + op=And(), + values=[ + Name(id='a'), + Name(id='b')])), + Name(id='c')])), + Assign( + targets=[ + Name(id='r')], + value=BinOp( + left=BinOp( + left=Name(id='a'), + op=BitAnd(), + right=Name(id='b')), + op=BitOr(), + right=BinOp( + left=Name(id='c'), + op=BitXor(), + right=Name(id='d')))), + Assign( + targets=[ + Name(id='s')], + value=Attribute( + value=Attribute( + value=Name(id='a'), + attr='b'), + attr='c')), + Assign( + targets=[ + Name(id='t')], + value=Subscript( + value=Subscript( + value=Subscript( + value=Name(id='a'), + slice=Name(id='b')), + slice=Tuple( + elts=[ + Name(id='c'), + Name(id='d')])), + slice=Slice( + lower=Name(id='e'), + upper=Name(id='f')))), + Assign( + targets=[ + Name(id='u')], + value=Call( + func=Call( + func=Name(id='a'), + args=[ + Name(id='b')], + keywords=[]), + args=[], + keywords=[ + keyword( + arg='c', + value=Name(id='d'))]))], + type_ignores=[]) \ No newline at end of file diff --git a/tests/generator.py b/tests/generator.py index f04992b..e272fe6 100644 --- a/tests/generator.py +++ b/tests/generator.py @@ -3,7 +3,6 @@ from dataclasses import dataclass from pathlib import Path from midas.checker.checker import TypeChecker -from midas.checker.diagnostic import DiagnosticType from midas.generator.generator import Generator from midas.utils import TypedAST from tests.base import Tester @@ -44,10 +43,11 @@ class GeneratorTester(Tester): typed_ast: TypedAST = checker.type_check(path) - if not any(d.type == DiagnosticType.ERROR for d in checker.diagnostics): - generator = Generator(workdir=path.parent, types=checker.types) - generator.set_src_path(path) - result.compiled_ast = generator.generate_ast(typed_ast) + # Ignore errors and generate anyway, easier here and errors should be + # covered by checker tests + generator = Generator(workdir=path.parent, types=checker.types) + generator.set_src_path(path) + result.compiled_ast = generator.generate_ast(typed_ast) return result