From 45753395f18376a92ce7651be9f9af44126315d6 Mon Sep 17 00:00:00 2001 From: Claudiu Popa Date: Sun, 2 Jun 2019 11:20:21 +0200 Subject: [PATCH] ``assert`` only functions are properly inferred as returning ``None`` Close #668 --- ChangeLog | 4 ++++ astroid/scoped_nodes.py | 8 +++++++- astroid/tests/unittest_inference.py | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 64a300d002..921c86c615 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,10 @@ Release Date: TBA Close PyCQA/pylint#2326 Close PyCQA/pylint#2021 +* ``assert`` only functions are properly inferred as returning ``None`` + + Close #668 + * Add support for Python 3.8's `NamedExpr` nodes, which is part of assignment expressions. Close #674 diff --git a/astroid/scoped_nodes.py b/astroid/scoped_nodes.py index bd0b7bd419..ccea388565 100644 --- a/astroid/scoped_nodes.py +++ b/astroid/scoped_nodes.py @@ -1656,7 +1656,13 @@ def infer_call_result(self, caller=None, context=None): first_return = next(returns, None) if not first_return: - raise exceptions.InferenceError("Empty return iterator") + if self.body and isinstance(self.body[-1], node_classes.Assert): + yield node_classes.Const(None) + return + + raise exceptions.InferenceError( + "The function does not have any return statements" + ) for returnnode in itertools.chain((first_return,), returns): if returnnode.value is None: diff --git a/astroid/tests/unittest_inference.py b/astroid/tests/unittest_inference.py index 1f9c7e447f..59cc23a6be 100644 --- a/astroid/tests/unittest_inference.py +++ b/astroid/tests/unittest_inference.py @@ -5289,5 +5289,19 @@ def both_branches(): assert [third[0].value, third[1].value] == [1, 2] +def test_assert_last_function_returns_none_on_inference(): + code = """ + def check_equal(a, b): + res = do_something_with_these(a, b) + assert a == b == res + + check_equal(a, b) + """ + node = extract_node(code) + inferred = next(node.infer()) + assert isinstance(inferred, nodes.Const) + assert inferred.value is None + + if __name__ == "__main__": unittest.main()