diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | as_string.py | 6 | ||||
-rw-r--r-- | scoped_nodes.py | 2 | ||||
-rw-r--r-- | test/data/module2.py | 23 | ||||
-rw-r--r-- | test/unittest_scoped_nodes.py | 5 |
5 files changed, 32 insertions, 8 deletions
@@ -5,6 +5,10 @@ Change log for the astng package * #123062 [pylint-brain]: Use correct names for keywords for urlparse * #123056 [pylint-brain]: Add missing methods for hashlib + * #123068: Fix inference for generator methods to correctly handle yields + in lambdas. + * #123068: Make sure .as_string() returns valid code for yields in + expressions. 2013-02-27 -- 0.24.2 * pylint-brain: more subprocess.Popen faking (see #46273) diff --git a/as_string.py b/as_string.py index 0a42668d..d3478610 100644 --- a/as_string.py +++ b/as_string.py @@ -385,7 +385,11 @@ class AsStringVisitor(object): def visit_yield(self, node): """yield an ast.Yield node as string""" yi_val = node.value and (" " + node.value.accept(self)) or "" - return 'yield' + yi_val + expr = 'yield' + yi_val + if node.parent.is_statement: + return expr + else: + return "(%s)" % (expr,) class AsStringVisitor3k(AsStringVisitor): diff --git a/scoped_nodes.py b/scoped_nodes.py index 9c23ebfa..46815ac3 100644 --- a/scoped_nodes.py +++ b/scoped_nodes.py @@ -608,7 +608,7 @@ class Function(Statement, Lambda): """return true if this is a generator function""" # XXX should be flagged, not computed try: - return self.nodes_of_class(Yield, skip_klass=Function).next() + return self.nodes_of_class(Yield, skip_klass=(Function, Lambda)).next() except StopIteration: return False diff --git a/test/data/module2.py b/test/data/module2.py index 2b729c0d..a22a4c0f 100644 --- a/test/data/module2.py +++ b/test/data/module2.py @@ -38,10 +38,10 @@ class MyError(MyException): class AbstractClass(object): - + def to_override(self, whatever): raise NotImplementedError() - + def return_something(self, param): if param: return 'toto' @@ -102,12 +102,12 @@ print >> stream, 'salut', def make_class(any, base=data.module.YO, *args, **kwargs): """check base is correctly resolved to Concrete0""" - - + + class Aaaa(base): """dynamic class""" - - + + return Aaaa from os.path import abspath import os as myos @@ -122,3 +122,14 @@ class A(A): pass +def generator(): + """A generator.""" + yield + +def not_a_generator(): + """A function that contains generator, but is not one.""" + + def generator(): + yield + genl = lambda : (yield) + diff --git a/test/unittest_scoped_nodes.py b/test/unittest_scoped_nodes.py index 9da0e322..2046cf54 100644 --- a/test/unittest_scoped_nodes.py +++ b/test/unittest_scoped_nodes.py @@ -232,6 +232,11 @@ def nested_args(a, (b, c, d)): func = MODULE['four_args'] self.assertEqual(func.args.format_args(), 'a, b, c, d') + def test_is_generator(self): + self.assertTrue(MODULE2['generator'].is_generator()) + self.assertFalse(MODULE2['not_a_generator'].is_generator()) + self.assertFalse(MODULE2['make_class'].is_generator()) + def test_is_abstract(self): method = MODULE2['AbstractClass']['to_override'] self.assertTrue(method.is_abstract(pass_is_abstract=False)) |