summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--as_string.py6
-rw-r--r--scoped_nodes.py2
-rw-r--r--test/data/module2.py23
-rw-r--r--test/unittest_scoped_nodes.py5
5 files changed, 32 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index e9e9eeb6..c246480a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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))