diff options
-rw-r--r-- | _nodes_ast.py | 26 | ||||
-rw-r--r-- | builder.py | 22 | ||||
-rw-r--r-- | raw_building.py | 10 | ||||
-rw-r--r-- | test/unittest_builder.py | 75 |
4 files changed, 66 insertions, 67 deletions
diff --git a/_nodes_ast.py b/_nodes_ast.py index 4a3c4302..cfb0ea2c 100644 --- a/_nodes_ast.py +++ b/_nodes_ast.py @@ -25,28 +25,28 @@ __docformat__ = "restructuredtext en" from _ast import (Assert, Assign, AugAssign, BinOp, BoolOp, Break, Compare, Continue, - Delete, Dict, + Delete, Dict, Ellipsis, Exec, ExtSlice, For, - Global, + Global, If, IfExp, Import, Index, - Lambda, List, ListComp, - Module, + Lambda, List, ListComp, + Module, Name, Pass, Print, Raise, Return, - Slice, Subscript, + Slice, Subscript, TryExcept, TryFinally, Tuple, UnaryOp, While, With, Yield, - ) + ) # aliased nodes from _ast import (AST as Node, Attribute as Getattr, Call as CallFunc, ClassDef as Class, - Expr as Discard, + Expr as Discard, FunctionDef as Function, GeneratorExp as GenExpr, ImportFrom as From, @@ -178,7 +178,7 @@ class Const(Node): def __init__(self, value=None): super(Const, self).__init__() self.value = value - + class DelAttr(Node): """represent del attribute statements""" @@ -207,10 +207,10 @@ class TreeRebuilder(ASTVisitor): def visit_binop(self, node): node.op = _BIN_OP_CLASSES[node.op.__class__] - + def visit_boolop(self, node): node.op = _BOOL_OP_CLASSES[node.op.__class__] - + def visit_callfunc(self, node): node.args.extend(node.keywords) del node.keywords @@ -255,7 +255,7 @@ class TreeRebuilder(ASTVisitor): def visit_import(self, node): node.names = [(alias.name, alias.asname) for alias in node.names] - + def visit_from(self, node): node.names = [(alias.name, alias.asname) for alias in node.names] node.modname = node.module @@ -271,7 +271,7 @@ class TreeRebuilder(ASTVisitor): node.__class__ = DelName elif self.visitor.asscontext is not None: node.__class__ = AssName - + def visit_num(self, node): node.__class__ = Const node.value = node.n @@ -324,7 +324,7 @@ def _const_factory(value): node.value = value return node - + def function_factory(name, args, defaults, flag=0, doc=None): """create and initialize a astng Function node""" # XXX local import necessary due to cyclic deps @@ -47,13 +47,13 @@ try: except: from compiler import parse from logilab.astng import patchcomptransformer - + # ast NG builder ############################################################## class ASTNGBuilder: """provide astng building methods """ - + def __init__(self, manager=None): if manager is None: from logilab.astng import MANAGER as manager @@ -94,7 +94,7 @@ class ASTNGBuilder: self._done = {} self.object_build(node, module) return node - + def file_build(self, path, modname=None): """build astng from a source code file (i.e. from an ast) @@ -120,13 +120,13 @@ class ASTNGBuilder: finally: self._file = None sys.path.pop(0) - + return node - + def string_build(self, data, modname='', path=None): """build astng from a source code stream (i.e. from an ast)""" return self.ast_build(parse(data + '\n'), modname, path) - + def ast_build(self, node, modname='', path=None): """recurse on the ast (soon ng) to add some arguments et method""" if path is not None: @@ -138,7 +138,7 @@ class ASTNGBuilder: node.package = True else: node.package = path and path.find('__init__.py') > -1 or False - node.name = modname + node.name = modname node.pure_python = True if self._manager is not None: self._manager._cache[node.file] = node @@ -151,7 +151,7 @@ class ASTNGBuilder: # # this is actually a really minimal representation, including only Module, # Function and Class nodes and some others as guessed - + def object_build(self, node, obj): """recursive method which create a partial ast from real objects (only function, class, and method are handled) @@ -179,7 +179,7 @@ class ASTNGBuilder: if self._member_module(member) != self._module.__name__: imported_member(node, member, name) continue - object_build_methoddescriptor(node, member) + object_build_methoddescriptor(node, member) elif isclass(member): # verify this is not an imported class if self._member_module(member) != self._module.__name__: @@ -215,7 +215,7 @@ def imported_member(node, member, name): check if it's sound valid and then add an import node, else use a dummy node """ - # /!\ some classes like ExtensionClass doesn't have a + # /!\ some classes like ExtensionClass doesn't have a # __module__ attribute ! member_module = getattr(member, '__module__', '__builtin__') try: @@ -224,4 +224,4 @@ def imported_member(node, member, name): attach_dummy_node(node, name, member) else: attach_import_node(node, member_module, name) - + diff --git a/raw_building.py b/raw_building.py index f2cf29b3..41c1e7fc 100644 --- a/raw_building.py +++ b/raw_building.py @@ -27,7 +27,7 @@ from inspect import getargspec from logilab.astng import nodes - + def _attach_local_node(parent, node, name): node.name = name # needed by add_local_node parent.add_local_node(node) @@ -43,7 +43,7 @@ def attach_dummy_node(node, name, object=_marker): _attach_local_node(node, enode, name) nodes.EmptyNode.has_underlying_object = lambda self: self.object is not _marker - + def attach_const_node(node, name, value): """create a Const node and register it in the locals of the given node with the specified name @@ -107,7 +107,7 @@ else: def register_arguments(func, args=None): """add given arguments to local - + args is a list that may contains nested lists (i.e. def func(a, (b, c, d)): ...) """ @@ -181,8 +181,8 @@ def _base_class_object_build(node, member, basenames, name=None): return klass -__all__ = ('register_arguments', 'build_module', - 'object_build_class', 'object_build_function', +__all__ = ('register_arguments', 'build_module', + 'object_build_class', 'object_build_function', 'object_build_datadescriptor', 'object_build_methoddescriptor', 'attach_dummy_node', 'attach_const_node', 'attach_import_node') diff --git a/test/unittest_builder.py b/test/unittest_builder.py index 2a583428..636a6db2 100644 --- a/test/unittest_builder.py +++ b/test/unittest_builder.py @@ -97,7 +97,7 @@ class FromToLineNoTC(TestCase): self.assertIsInstance(return_, nodes.Return) self.assertEquals(return_.fromlineno, 18) self.assertEquals(return_.tolineno, 18) - + def test_decorated_function_lineno(self): if sys.version_info < (2, 4): self.skip('require python >=2.4') @@ -109,12 +109,12 @@ def function( ''', __name__, __file__) function = astng['function'] self.assertEquals(function.fromlineno, 3) # XXX discussable, but that's what is expected by pylint right now - self.assertEquals(function.tolineno, 5) + self.assertEquals(function.tolineno, 5) self.assertEquals(function.blockstart_tolineno, 4) self.assertEquals(function.decorators.fromlineno, 2) - self.assertEquals(function.decorators.tolineno, 2) - - + self.assertEquals(function.decorators.tolineno, 2) + + def test_class_lineno(self): stmts = self.astng.body # on line 20: @@ -165,7 +165,7 @@ else: stmt = astng.body[0] self.assertEquals(stmt.fromlineno, 2) self.assertEquals(stmt.tolineno, 6) - self.assertEquals(stmt.blockstart_tolineno, 2) + self.assertEquals(stmt.blockstart_tolineno, 2) self.assertEquals(stmt.orelse[0].fromlineno, 6) # XXX self.assertEquals(stmt.orelse[0].tolineno, 6) @@ -182,13 +182,13 @@ else: try_ = astng.body[0] self.assertEquals(try_.fromlineno, 2) self.assertEquals(try_.tolineno, 7) - self.assertEquals(try_.blockstart_tolineno, 2) + self.assertEquals(try_.blockstart_tolineno, 2) self.assertEquals(try_.orelse[0].fromlineno, 7) # XXX self.assertEquals(try_.orelse[0].tolineno, 7) hdlr = try_.handlers[0] self.assertEquals(hdlr.fromlineno, 4) self.assertEquals(hdlr.tolineno, 5) - self.assertEquals(hdlr.blockstart_tolineno, 4) + self.assertEquals(hdlr.blockstart_tolineno, 4) def test_try_finally_lineno(self): @@ -201,7 +201,7 @@ finally: try_ = astng.body[0] self.assertEquals(try_.fromlineno, 2) self.assertEquals(try_.tolineno, 5) - self.assertEquals(try_.blockstart_tolineno, 2) + self.assertEquals(try_.blockstart_tolineno, 2) self.assertEquals(try_.finalbody[0].fromlineno, 5) # XXX self.assertEquals(try_.finalbody[0].tolineno, 5) @@ -220,7 +220,7 @@ finally: try_ = astng.body[0] self.assertEquals(try_.fromlineno, 2) self.assertEquals(try_.tolineno, 7) - self.assertEquals(try_.blockstart_tolineno, 2) + self.assertEquals(try_.blockstart_tolineno, 2) self.assertEquals(try_.finalbody[0].fromlineno, 7) # XXX self.assertEquals(try_.finalbody[0].tolineno, 7) @@ -237,21 +237,21 @@ with file("/tmp/pouet") as f: self.assertEquals(with_.fromlineno, 3) self.assertEquals(with_.tolineno, 4) self.assertEquals(with_.blockstart_tolineno, 3) - - + + class BuilderTC(TestCase): - + def setUp(self): self.builder = builder.ASTNGBuilder() - + def test_border_cases(self): """check that a file with no trailing new line is parseable""" self.builder.file_build('data/noendingnewline.py', 'data.noendingnewline') self.assertRaises(builder.ASTNGBuildingException, self.builder.file_build, 'data/inexistant.py', 'whatever') - - def test_inspect_build(self): + + def test_inspect_build0(self): """test astng tree build from a living object""" builtin_astng = MANAGER.astng_from_module_name('__builtin__') fclass = builtin_astng['file'] @@ -260,7 +260,7 @@ class BuilderTC(TestCase): self.assert_('read' in fclass) self.assert_(fclass.newstyle) self.assert_(fclass.pytype(), '__builtin__.type') - self.assert_(isinstance(fclass['read'], nodes.Function)) + self.assertIsInstance(fclass['read'], nodes.Function) # check builtin function has args.args == None dclass = builtin_astng['dict'] self.assertEquals(dclass['has_key'].args.args, None) @@ -285,7 +285,6 @@ class BuilderTC(TestCase): self.assert_(time_astng) self.assertEquals(time_astng['time'].args.defaults, []) - def test_inspect_build2(self): """test astng tree build from a living object""" try: @@ -318,19 +317,19 @@ class BuilderTC(TestCase): def test_inspect_build_type_object(self): builtin_astng = MANAGER.astng_from_module_name('__builtin__') - + infered = list(builtin_astng.igetattr('object')) self.assertEquals(len(infered), 1) infered = infered[0] self.assertEquals(infered.name, 'object') as_string(infered) - + infered = list(builtin_astng.igetattr('type')) self.assertEquals(len(infered), 1) infered = infered[0] self.assertEquals(infered.name, 'type') as_string(infered) - + def test_package_name(self): """test base properties and method of a astng module""" datap = self.builder.file_build('data/__init__.py', 'data') @@ -361,13 +360,13 @@ def yiell(): data = ''' class A: "old style" - + class B(A): "old style" - + class C(object): "new style" - + class D(C): "new style" @@ -375,7 +374,7 @@ __metaclass__ = type class E(A): "old style" - + class F: "new style" ''' @@ -398,10 +397,10 @@ def update_global(): def global_no_effect(): global CSTE2 print CSTE -''' +''' astng = self.builder.string_build(data, __name__, __file__) self.failUnlessEqual(len(astng.getattr('CSTE')), 2) - self.failUnless(isinstance(astng.getattr('CSTE')[0], nodes.AssName)) + self.assertIsInstance(astng.getattr('CSTE')[0], nodes.AssName) self.failUnlessEqual(astng.getattr('CSTE')[0].fromlineno, 2) self.failUnlessEqual(astng.getattr('CSTE')[1].fromlineno, 6) self.assertRaises(nodes.NotFoundError, @@ -433,7 +432,7 @@ def global_no_effect(): self.failIf(n.scope() is astng) self.failUnlessEqual([i.__class__ for i in n.infer()], [YES.__class__]) - + class FileBuildTC(TestCase): def setUp(self): @@ -455,7 +454,7 @@ class FileBuildTC(TestCase): self.assert_(not module.is_statement) self.assertEquals(module.statement(), module) self.assertEquals(module.statement(), module) - + def test_module_locals(self): """test the 'locals' dictionary of a astng module""" module = self.module @@ -465,7 +464,7 @@ class FileBuildTC(TestCase): keys.sort() should = ['MY_DICT', 'YO', 'YOUPI', '__revision__', 'global_access','modutils', 'nested_args', - 'os', 'redirect', 'spawn', 'REDIRECT', 'LocalsVisitor', + 'os', 'redirect', 'spawn', 'REDIRECT', 'LocalsVisitor', 'ASTWalker', 'ASTVisitor', 'extend_class'] should.sort() self.assertEquals(keys, should) @@ -491,7 +490,7 @@ class FileBuildTC(TestCase): keys = _locals.keys() keys.sort() self.assertEquals(keys, ['i', 'key', 'local', 'val']) - + def test_class_base_props(self): """test base properties and method of a astng class""" module = self.module @@ -505,7 +504,7 @@ class FileBuildTC(TestCase): self.assertEquals(klass.root(), module) self.assertEquals(klass.basenames, []) self.assertEquals(klass.newstyle, False) - + def test_class_locals(self): """test the 'locals' dictionary of a astng class""" module = self.module @@ -533,7 +532,7 @@ class FileBuildTC(TestCase): klass2 = module['YOUPI'] self.assertEquals(klass1.basenames, []) self.assertEquals(klass2.basenames, ['YO']) - + def test_method_base_props(self): """test base properties and method of a astng method""" klass2 = self.module['YOUPI'] @@ -563,7 +562,7 @@ class FileBuildTC(TestCase): keys.sort() self.assertEquals(keys, ['a', 'autre', 'b', 'local', 'self']) - + class ModuleBuildTC(FileBuildTC): def setUp(self): @@ -572,10 +571,10 @@ class ModuleBuildTC(FileBuildTC): class MoreTC(TestCase): - + def setUp(self): self.builder = builder.ASTNGBuilder() - + def test_infered_build(self): code = '''class A: pass A.type = "class" @@ -590,7 +589,7 @@ A.ass_type = A_ass_type lclass = lclass[0] self.assert_('ass_type' in lclass.locals, lclass.locals.keys()) self.assert_('type' in lclass.locals.keys()) - + # def test_1(self): # from logilab import astng # import compiler @@ -639,6 +638,6 @@ def visit_if(self, node): ''' astng = self.builder.string_build(code) self.failUnless('body' in astng['visit_if'].locals) - + if __name__ == '__main__': unittest_main() |