transpyle
transpyle copied to clipboard
C AST generalizer doesn't allow void functions
TLDR: If you run the Transpyler AST Generalizer on a C program with void functions, it will throw an isinstance assertion error because pycparser returns None for the function declaration, while the AST Generalizer expects a typed_ast3.arguments type. Here's a link to the relevant Transpyler function.
Transpyle version: 0.8.0
Pycparser version: 2.19
Minimal code example:
import pathlib
import transpyle
path = pathlib.Path('my_script.c')
code_reader = transpyle.general.code_reader.CodeReader()
code = code_reader.read_file(path)
from_language = transpyle.Language.find('C11')
to_language = transpyle.Language.find('Python 3.6')
translator = transpyle.AutoTranslator(from_language, to_language)
c_code = translator.translate(code, path)
print(c_code)
with my_script.c set to
void foo() {
int hello = 6;
}
My traceback is
Traceback (most recent call last):
File "test.py", line 11, in <module>
c_code = translator.translate(code, path)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/general/translator.py", line 26, in translate
general_ast = self.ast_generalizer.generalize(specific_ast, **ast_generalizer_kwargs)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/c/ast_generalizer.py", line 435, in generalize
general_ast = backend.visit(syntax)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/c/ast_generalizer.py", line 80, in visit
return super().visit(node)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/pycparser/c_ast.py", line 158, in visit
return visitor(node)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/c/ast_generalizer.py", line 83, in visit_FileAST
ext = [self.visit(subnode) for subnode in node.ext]
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/c/ast_generalizer.py", line 83, in <listcomp>
ext = [self.visit(subnode) for subnode in node.ext]
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/c/ast_generalizer.py", line 80, in visit
return super().visit(node)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/pycparser/c_ast.py", line 158, in visit
return visitor(node)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/c/ast_generalizer.py", line 91, in visit_FuncDef
name, args, return_type = self.visit(node.decl)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/c/ast_generalizer.py", line 80, in visit
return super().visit(node)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/pycparser/c_ast.py", line 158, in visit
return visitor(node)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/c/ast_generalizer.py", line 266, in visit_Decl
type_data = self.visit(node.type)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/c/ast_generalizer.py", line 80, in visit
return super().visit(node)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/pycparser/c_ast.py", line 158, in visit
return visitor(node)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/c/ast_generalizer.py", line 106, in visit_FuncDecl
assert isinstance(args, typed_ast3.arguments)
AssertionError
Note: it looks like simply commenting out that assertion doesn't work. While it passes the AST Generalization phase, the unparser then throws this error:
Traceback (most recent call last):
File "test.py", line 11, in <module>
c_code = translator.translate(code, path)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/general/translator.py", line 27, in translate
to_code = self.unparser.unparse(general_ast, **unparser_kwargs)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/transpyle/python/unparser.py", line 45, in unparse
code = horast.unparse(tree)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/horast/unparser.py", line 159, in unparse
Unparser(tree, *args, file=stream, **kwargs)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/astunparse/unparser.py", line 38, in __init__
self.dispatch(tree)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/static_typing/unparser.py", line 21, in dispatch
super().dispatch(tree)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/astunparse/unparser.py", line 66, in dispatch
meth(tree)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/astunparse/unparser.py", line 78, in _Module
self.dispatch(stmt)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/static_typing/unparser.py", line 21, in dispatch
super().dispatch(tree)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/astunparse/unparser.py", line 66, in dispatch
meth(tree)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/astunparse/unparser.py", line 347, in _FunctionDef
self.__FunctionDef_helper(t, "def")
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/astunparse/unparser.py", line 359, in __FunctionDef_helper
self.dispatch(t.args)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/static_typing/unparser.py", line 21, in dispatch
super().dispatch(tree)
File "/Users/sanjit/.pyenv/versions/3.8.1/lib/python3.8/site-packages/astunparse/unparser.py", line 65, in dispatch
meth = getattr(self, "_"+tree.__class__.__name__)
AttributeError: 'Unparser' object has no attribute '_NoneType'