summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2020-05-12 08:31:49 +0200
committerClaudiu Popa <pcmanticore@gmail.com>2020-05-12 08:51:21 +0200
commit6484b53c73b68969113acd502e091f935f29af07 (patch)
treec933125b9763148ee868e69a69aa5d869b039e85
parent60290ea135bb2b53ab87ad6d60f042d20a72db0b (diff)
downloadastroid-git-6484b53c73b68969113acd502e091f935f29af07.tar.gz
`FunctionDef.is_generator` properly handles `yield` nodes in `While` tests
Close PyCQA/pylint#3519
-rw-r--r--ChangeLog10
-rw-r--r--astroid/node_classes.py5
-rw-r--r--astroid/scoped_nodes.py2
-rw-r--r--tests/unittest_nodes.py12
4 files changed, 28 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 63edff03..0c790f5c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,6 +10,16 @@ Release Date: TBA
* Added a brain for ``sqlalchemy.orm.session``
+
+What's New in astroid 2.4.2?
+============================
+Release Date: TBA
+
+* `FunctionDef.is_generator` properly handles `yield` nodes in `While` tests
+
+ Close PyCQA/pylint#3519
+
+
What's New in astroid 2.4.1?
============================
Release Date: 2020-05-05
diff --git a/astroid/node_classes.py b/astroid/node_classes.py
index a7fcf190..621dc5f2 100644
--- a/astroid/node_classes.py
+++ b/astroid/node_classes.py
@@ -4496,6 +4496,11 @@ class While(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement):
yield from self.body
yield from self.orelse
+ def _get_yield_nodes_skip_lambdas(self):
+ """A While node can contain a Yield node in the test"""
+ yield from self.test._get_yield_nodes_skip_lambdas()
+ yield from super()._get_yield_nodes_skip_lambdas()
+
class With(
mixins.MultiLineBlockMixin,
diff --git a/astroid/scoped_nodes.py b/astroid/scoped_nodes.py
index 0406946f..8561e745 100644
--- a/astroid/scoped_nodes.py
+++ b/astroid/scoped_nodes.py
@@ -1661,7 +1661,7 @@ class FunctionDef(mixins.MultiLineBlockMixin, node_classes.Statement, Lambda):
:returns: True is this is a generator function, False otherwise.
:rtype: bool
"""
- return next(self._get_yield_nodes_skip_lambdas(), False)
+ return bool(next(self._get_yield_nodes_skip_lambdas(), False))
def infer_call_result(self, caller=None, context=None):
"""Infer what the function returns when called.
diff --git a/tests/unittest_nodes.py b/tests/unittest_nodes.py
index 0e8863b8..07733e5f 100644
--- a/tests/unittest_nodes.py
+++ b/tests/unittest_nodes.py
@@ -1335,5 +1335,17 @@ def test_const_itered():
assert [elem.value for elem in itered] == list("string")
+def test_is_generator_for_yield_in_while():
+ code = """
+ def paused_iter(iterable):
+ while True:
+ # Continue to yield the same item until `next(i)` or `i.send(False)`
+ while (yield value):
+ pass
+ """
+ node = astroid.extract_node(code)
+ assert bool(node.is_generator())
+
+
if __name__ == "__main__":
unittest.main()