From a795e4a101bbb79abe26d9fa1e2979994a51aaa5 Mon Sep 17 00:00:00 2001 From: cyrillemidingoyi Date: Sun, 29 Mar 2026 13:38:09 +0200 Subject: [PATCH] update documentation --- README.rst | 8 +-- src/pycropml/transpiler/ast_transform.py | 63 +++++++++++++++++++---- test/cyml/logs/test_array_declaration.log | 12 ++--- test/cyml/test_cyml_operations.py | 4 +- 4 files changed, 65 insertions(+), 22 deletions(-) diff --git a/README.rst b/README.rst index 75085cc..62791e8 100644 --- a/README.rst +++ b/README.rst @@ -58,17 +58,17 @@ Using pytest :: # Run all tests - python -m pytest test/test_cyml_operations.py -v + python -m pytest test/cyml/test_cyml_operations.py -v # Run a specific test class - python -m pytest test/test_cyml_operations.py::TestCyMLOperations -v + python -m pytest test/cyml/test_cyml_operations.py::TestCyMLOperations -v # Run a single test - python -m pytest test/test_cyml_operations.py::TestCyMLOperations::test_modulo_operation -v + python -m pytest test/cyml/test_cyml_operations.py::TestCyMLOperations::test_modulo_operation -v Using unittest ~~~~~~~~~~~~~~ :: - cd test + cd test/cyml python -m unittest test_cyml_operations diff --git a/src/pycropml/transpiler/ast_transform.py b/src/pycropml/transpiler/ast_transform.py index 9f1ecc0..3af2e68 100644 --- a/src/pycropml/transpiler/ast_transform.py +++ b/src/pycropml/transpiler/ast_transform.py @@ -231,14 +231,25 @@ def visit_singleassignmentnode(self, node, lhs, rhs, location): if e is None: self.notdeclared(name, location) elif e: - if e in ("list", "dict", "tuple", "array", "intlist", "floatlist", "intarray", "floatarray"): - a = self._compatible_types( - e, value_node['pseudo_type'], "Type error for variable '%s' in function '%s' at line %s: expected type does not match assigned type" % (name, self.function_name, location[0])) - else: - #if value_node["type"] =="custom_call" and value_node["pseudo_type"] is None: value_node["pseudo_type"] = e - if value_node["type"] != "none": - a = self._compatible_types(e, value_node['pseudo_type'], "Type error for variable '%s' in function '%s' at line %s: expected type does not match assigned type" % ( - name, self.function_name, location[0])) + # if value_node["type"] =="custom_call" and value_node["pseudo_type"] is None: value_node["pseudo_type"] = e + if value_node["type"] != "none": + err_msg = ( + "Type error for variable '%s' in function '%s' at line %s: " + "expected type does not match assigned type" + ) % (name, self.function_name, location[0]) + compatibility = self._compatible_types( + e, + value_node['pseudo_type'], + err_msg, + silent=True + ) + if compatibility is False: + raise type_check_error( + err_msg, + location, + self.lines[location[0]], + wrong_type=value_node['pseudo_type'] + ) z = { 'type': 'assignment', 'target': { @@ -908,11 +919,25 @@ def _translate_builtin_method_call(self, class_type, base, message, args, locati if base["pseudo_type"] =="list": self.type_env.top[base["name"]] = [ "list", args[0]["pseudo_type"]] - return api.expand([base] + args) + try: + return api.expand([base] + args) + except PseudoCythonTypeCheckError as exc: + raise type_check_error( + str(exc), + location, + self.lines[location[0]] + ) from None else: for count, b in api.items(): if len(args) == count: - return b.expand([base] + args) + try: + return b.expand([base] + args) + except PseudoCythonTypeCheckError as exc: + raise type_check_error( + str(exc), + location, + self.lines[location[0]] + ) from None raise translation_error( 'pseudo-cython doesn\'t support %s%s with %d args' % ( serialize_type(class_type), message, len(args)), @@ -1437,6 +1462,24 @@ def visit_cvardefnode(self, node, base_type, declarators, location): typearray = ["intarray","floatarray","booleanarray","stringarray", "strarray"] is_enum_type = actual_type_name in self._enum_names() for de in declarators: + # Every declaration must define an explicit variable name. + if isinstance(de, Nodes.CArrayDeclaratorNode): + if hasattr(de, 'base') and hasattr(de.base, 'base') and hasattr(de.base.base, 'name'): + declared_name = de.base.base.name + elif hasattr(de, 'base') and hasattr(de.base, 'name'): + declared_name = de.base.name + else: + declared_name = None + else: + declared_name = getattr(de, 'name', None) + + if not declared_name: + raise type_check_error( + "invalid declaration: missing variable name", + location, + self.lines[location[0]] if location and getattr(self, 'lines', None) else None + ) + if not isinstance(de, Nodes.CArrayDeclaratorNode): if not self.isattr and self.type_env[de.name]: raise PseudoCythonTypeCheckError( diff --git a/test/cyml/logs/test_array_declaration.log b/test/cyml/logs/test_array_declaration.log index 5f3d84e..bef7fc6 100644 --- a/test/cyml/logs/test_array_declaration.log +++ b/test/cyml/logs/test_array_declaration.log @@ -1,6 +1,6 @@ -2026-03-29 11:49:28 DEBUG [pycropml.transpiler.main] Parsing source input -2026-03-29 11:49:28 DEBUG [pycropml.transpiler.parser] Starting parse (input type=str) -2026-03-29 11:49:28 DEBUG [pycropml.transpiler.parser] Parse succeeded -2026-03-29 11:49:28 DEBUG [pycropml.transpiler.main] Parsing completed -2026-03-29 11:49:28 DEBUG [pycropml.transpiler.main] Building AST -2026-03-29 11:49:28 DEBUG [pycropml.transpiler.main] AST build completed +2026-03-29 13:34:36 DEBUG [pycropml.transpiler.main] Parsing source input +2026-03-29 13:34:36 DEBUG [pycropml.transpiler.parser] Starting parse (input type=str) +2026-03-29 13:34:36 DEBUG [pycropml.transpiler.parser] Parse succeeded +2026-03-29 13:34:36 DEBUG [pycropml.transpiler.main] Parsing completed +2026-03-29 13:34:36 DEBUG [pycropml.transpiler.main] Building AST +2026-03-29 13:34:36 DEBUG [pycropml.transpiler.main] AST build completed diff --git a/test/cyml/test_cyml_operations.py b/test/cyml/test_cyml_operations.py index 04e01e8..27bcb9a 100644 --- a/test/cyml/test_cyml_operations.py +++ b/test/cyml/test_cyml_operations.py @@ -223,7 +223,7 @@ def test_list(): cdef int length, total length = len(numbers) total = sum(numbers) - numbers.append(6) + numbers.append(4) return total """ result = self._transpile_code(code) @@ -235,7 +235,7 @@ def test_array_declaration(self): from tata import toto def test_array(int s=5): cdef float temps[10] # declare a C-style array of 10 floats - cdef floatarray[10] + cdef floatarray a cdef int size size = len(temps) return size