diff options
author | ldore <laurent.dore@gmail.com> | 2018-01-17 14:31:30 +0100 |
---|---|---|
committer | Eli Bendersky <eliben@users.noreply.github.com> | 2018-01-17 05:31:30 -0800 |
commit | 216823845b2d123f7d443cf27ee057cd1943f0c1 (patch) | |
tree | 0b195f522ea964d900442c5b8013893468c49f97 | |
parent | 97e74649a2aadbf317a74d421121af8060e841f3 (diff) | |
download | pycparser-216823845b2d123f7d443cf27ee057cd1943f0c1.tar.gz |
Implement __repr__ on Nodes (Issue #226) (#227)
* Implement __repr__ on Nodes.
-rw-r--r-- | pycparser/_ast_gen.py | 29 | ||||
-rw-r--r-- | pycparser/c_ast.py | 27 | ||||
-rw-r--r-- | tests/test_c_ast.py | 53 |
3 files changed, 107 insertions, 2 deletions
diff --git a/pycparser/_ast_gen.py b/pycparser/_ast_gen.py index 526d1ec..4dab963 100644 --- a/pycparser/_ast_gen.py +++ b/pycparser/_ast_gen.py @@ -63,6 +63,7 @@ class NodeCfg(object): contents: a list of contents - attributes and child nodes See comment at the top of the configuration file for details. """ + def __init__(self, name, contents): self.name = name self.all_entries = [] @@ -85,6 +86,7 @@ class NodeCfg(object): src = self._gen_init() src += '\n' + self._gen_children() src += '\n' + self._gen_iter() + src += '\n' + self._gen_attr_names() return src @@ -187,11 +189,38 @@ r'''#----------------------------------------------------------------- _PROLOGUE_CODE = r''' import sys +def _repr(obj): + """ + Get the representation of an object, with dedicated pprint-like format for lists. + """ + if isinstance(obj, list): + return '[' + (',\n '.join((_repr(e).replace('\n', '\n ') for e in obj))) + '\n]' + else: + return repr(obj) class Node(object): __slots__ = () """ Abstract base class for AST nodes. """ + def __repr__(self): + """ Generates a python representation of the current node + """ + result = self.__class__.__name__ + '(' + + indent = '' + separator = '' + for name in self.__slots__[:-2]: + result += separator + result += indent + result += name + '=' + (_repr(getattr(self, name)).replace('\n', '\n ' + (' ' * (len(name) + len(self.__class__.__name__))))) + + separator = ',' + indent = '\n ' + (' ' * len(self.__class__.__name__)) + + result += indent + ')' + + return result + def children(self): """ A sequence of all children that are Nodes """ diff --git a/pycparser/c_ast.py b/pycparser/c_ast.py index 99cd6a4..219f07b 100644 --- a/pycparser/c_ast.py +++ b/pycparser/c_ast.py @@ -18,11 +18,38 @@ import sys +def _repr(obj): + """ + Get the representation of an object, with dedicated pprint-like format for lists and tuples. + """ + if isinstance(obj, list): + return '[' + (',\n '.join((_repr(e).replace('\n', '\n ') for e in obj))) + '\n]' + else: + return repr(obj) class Node(object): __slots__ = () """ Abstract base class for AST nodes. """ + def __repr__(self): + """ Generates a python representation of the current node + """ + result = self.__class__.__name__ + '(' + + indent = '' + separator = '' + for name in self.__slots__[:-2]: + result += separator + result += indent + result += name + '=' + (_repr(getattr(self, name)).replace('\n', '\n ' + (' ' * (len(name) + len(self.__class__.__name__))))) + + separator = ',' + indent = '\n ' + (' ' * len(self.__class__.__name__)) + + result += indent + ')' + + return result + def children(self): """ A sequence of all children that are Nodes """ diff --git a/tests/test_c_ast.py b/tests/test_c_ast.py index bfe301a..8e95d55 100644 --- a/tests/test_c_ast.py +++ b/tests/test_c_ast.py @@ -38,7 +38,6 @@ class Test_c_ast(unittest.TestCase): self.assertEqual(weakref.getweakrefcount(coord), 1) - class TestNodeVisitor(unittest.TestCase): class ConstantVisitor(c_ast.NodeVisitor): def __init__(self): @@ -94,7 +93,57 @@ class TestNodeVisitor(unittest.TestCase): cv.visit(comp) self.assertEqual(cv.values, - ['5.6', 't', '5.6', 't', 't', '5.6', 't']) + ['5.6', 't', '5.6', 't', 't', '5.6', 't']) + + def test_repr(self): + c1 = c_ast.Constant(type='float', value='5.6') + c2 = c_ast.Constant(type='char', value='t') + + b1 = c_ast.BinaryOp( + op='+', + left=c1, + right=c2) + + b2 = c_ast.BinaryOp( + op='-', + left=b1, + right=c2) + + comp = c_ast.Compound( + block_items=[b1, b2, c1, c2]) + + expected = ("Compound(block_items=[BinaryOp(op='+',\n" + " left=Constant(type='float',\n" + " value='5.6'\n" + " ),\n" + " right=Constant(type='char',\n" + " value='t'\n" + " )\n" + " ),\n" + " BinaryOp(op='-',\n" + " left=BinaryOp(op='+',\n" + " left=Constant(type='float',\n" + " value='5.6'\n" + " ),\n" + " right=Constant(type='char',\n" + " value='t'\n" + " )\n" + " ),\n" + " right=Constant(type='char',\n" + " value='t'\n" + " )\n" + " ),\n" + " Constant(type='float',\n" + " value='5.6'\n" + " ),\n" + " Constant(type='char',\n" + " value='t'\n" + " )\n" + " ]\n" + " )") + + self.assertEqual(repr(comp), + expected) if __name__ == '__main__': |