diff options
author | Sylvain Thénault <sylvain.thenault@logilab.fr> | 2009-03-19 09:55:41 +0100 |
---|---|---|
committer | Sylvain Thénault <sylvain.thenault@logilab.fr> | 2009-03-19 09:55:41 +0100 |
commit | 3993719a083006b98df1d06258f7a1b31b049e5f (patch) | |
tree | cd2021fe422a018d7ededef7f5c5280527100b00 | |
parent | 439dea370cdb048a0871510dae9818ec7fbaa5c4 (diff) | |
download | astroid-git-3993719a083006b98df1d06258f7a1b31b049e5f.tar.gz |
fix line numbering of
* decorated function for _ast
* decorators node for compiler
--HG--
branch : _ast_compat
-rw-r--r-- | _nodes_ast.py | 4 | ||||
-rw-r--r-- | patchcomptransformer.py | 3 | ||||
-rw-r--r-- | scoped_nodes.py | 3 | ||||
-rw-r--r-- | test/unittest_builder.py | 19 |
4 files changed, 26 insertions, 3 deletions
diff --git a/_nodes_ast.py b/_nodes_ast.py index 670e5c1d..cb66c9aa 100644 --- a/_nodes_ast.py +++ b/_nodes_ast.py @@ -231,6 +231,8 @@ class TreeRebuilder(ASTVisitor): _init_set_doc(node) if node.decorators: node.decorators = Decorators(node.decorators) + else: + node.decorators = None def visit_getattr(self, node): node.attrname = node.attr @@ -318,7 +320,7 @@ def function_factory(name, args, defaults, flag=0, doc=None): # XXX local import necessary due to cyclic deps from logilab.astng.nodes import const_factory node = Function() - node.decorators = [] + node.decorators = None node.body = [] node.name = name # XXX ensure we get a compatible representation diff --git a/patchcomptransformer.py b/patchcomptransformer.py index b14d249e..5f3e3c92 100644 --- a/patchcomptransformer.py +++ b/patchcomptransformer.py @@ -112,7 +112,8 @@ class ASTNGTransformer(BaseTransformer): def funcdef(self, nodelist): node = BaseTransformer.funcdef(self, nodelist) - # XXX decorators + if node.decorators is not None: + fix_lineno(node.decorators, nodelist[0]) return fix_lineno(node, nodelist[-5], nodelist[-1], nodelist[-3]) def lambdef(self, nodelist): diff --git a/scoped_nodes.py b/scoped_nodes.py index a8f9bdc8..68053fc7 100644 --- a/scoped_nodes.py +++ b/scoped_nodes.py @@ -339,6 +339,9 @@ class FunctionNG(object): def set_line_info(self, lastchild): self.fromlineno = self.lineno + # lineno is the line number of the first decorator, we want the def statement lineno + if self.decorators is not None: + self.fromlineno += len(self.decorators.nodes) self.tolineno = lastchild.tolineno self.blockstart_tolineno = self.args.tolineno diff --git a/test/unittest_builder.py b/test/unittest_builder.py index 8ef5043d..8d864381 100644 --- a/test/unittest_builder.py +++ b/test/unittest_builder.py @@ -97,7 +97,24 @@ 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') + astng = builder.ASTNGBuilder().string_build(''' +@decorator +def function( + arg): + print arg +''', __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.blockstart_tolineno, 4) + self.assertEquals(function.decorators.fromlineno, 2) + self.assertEquals(function.decorators.tolineno, 2) + + def test_class_lineno(self): stmts = self.astng.body # on line 20: |