Skip to content

Commit

Permalink
FunctionDef.is_generator properly handles yield nodes in While
Browse files Browse the repository at this point in the history
…tests

Close pylint-dev/pylint#3519
  • Loading branch information
PCManticore committed May 12, 2020
1 parent 27ebf13 commit 54b7a11
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ 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?
============================
Expand Down
5 changes: 5 additions & 0 deletions astroid/node_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4500,6 +4500,11 @@ def get_children(self):
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,
Expand Down
2 changes: 1 addition & 1 deletion astroid/scoped_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1661,7 +1661,7 @@ def is_generator(self):
: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.
Expand Down
12 changes: 12 additions & 0 deletions tests/unittest_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit 54b7a11

Please sign in to comment.