pylint/checkers/refactoring.py
def _is_node_return_ended(self, node):
        """Check if the node ends with an explicit return statement.

        Args:
            node (astroid.NodeNG): node to be checked.

        Returns:
            bool: True if the node ends with an explicit statement, False otherwise.

        """
        #  Recursion base case
        if isinstance(node, astroid.Return):
            return True
        if isinstance(node, astroid.Call):
            try:
                funcdef_node = node.func.inferred()[0]
                if self._is_function_def_never_returning(funcdef_node):
                    return True
            except astroid.InferenceError:
                pass
        # Avoid the check inside while loop as we don't know
        #  if they will be completed
        if isinstance(node, astroid.While):
            return True
        if isinstance(node, astroid.Raise):
            # a Raise statement doesn't need to end with a return statement
            # but if the exception raised is handled, then the handler has to
            # ends with a return statement
            if not node.exc:
                # Ignore bare raises
                return True
            if not utils.is_node_inside_try_except(node):
                # If the raise statement is not inside a try/except statement
                #  then the exception is raised and cannot be caught. No need
                #  to infer it.
                return True
            exc = utils.safe_infer(node.exc)
            if exc is None or exc is astroid.Uninferable:
                return False
            exc_name = exc.pytype().split(".")[-1]
            handlers = utils.get_exception_handlers(node, exc_name)
            handlers = list(handlers) if handlers is not None else []
            if handlers:
                # among all the handlers handling the exception at least one
                # must end with a return statement
                return any(
                    self._is_node_return_ended(_handler) for _handler in handlers
                )
            # if no handlers handle the exception then it's ok
            return True
        if isinstance(node, astroid.If):
            # if statement is returning if there are exactly two return statements in its
            #  children : one for the body part, the other for the orelse part
            # Do not check if inner function definition are return ended.
            is_orelse_returning = any(
                self._is_node_return_ended(_ore)
                for _ore in node.orelse
                if not isinstance(_ore, astroid.FunctionDef)
            )
            is_if_returning = any(
                self._is_node_return_ended(_ifn)
                for _ifn in node.body
                if not isinstance(_ifn, astroid.FunctionDef)
            )
            return is_if_returning and is_orelse_returning
        #  recurses on the children of the node except for those which are except handler
        # because one cannot be sure that the handler will really be used
        return any(
            self._is_node_return_ended(_child)
            for _child in node.get_children()
            if not isinstance(_child, astroid.ExceptHandler)
        )
def _is_node_return_ended(self, node):
        """Check if the node ends with an explicit return statement.

        Args:
            node (astroid.NodeNG): node to be checked.

        Returns:
            bool: True if the node ends with an explicit statement, False otherwise.

        """
        #  Recursion base case
        if isinstance(node, astroid.Return):
            return True
        if isinstance(node, astroid.Call):
            try:
                funcdef_node = node.func.inferred()[0]
                if self._is_function_def_never_returning(funcdef_node):
                    return True
            except astroid.InferenceError:
                pass
        # Avoid the check inside while loop as we don't know
        #  if they will be completed
        if isinstance(node, astroid.While):
            return True
        if isinstance(node, astroid.Raise):
            # a Raise statement doesn't need to end with a return statement
            # but if the exception raised is handled, then the handler has to
            # ends with a return statement
            if not node.exc:
                # Ignore bare raises
                return True
            if not utils.is_node_inside_try_except(node):
                # If the raise statement is not inside a try/except statement
                #  then the exception is raised and cannot be caught. No need
                #  to infer it.
                return True
            exc = utils.safe_infer(node.exc)
            if exc is None or exc is astroid.Uninferable:
                return False
            exc_name = exc.pytype().split(".")[-1]
            handlers = utils.get_exception_handlers(node, exc_name)
            handlers = list(handlers) if handlers is not None else []
            if handlers:
                # among all the handlers handling the exception at least one
                # must end with a return statement
                return any(
                    self._is_node_return_ended(_handler) for _handler in handlers
                )
            # if no handlers handle the exception then it's ok
            return True
        if isinstance(node, astroid.If):
            # if statement is returning if there are exactly two return statements in its
            #  children : one for the body part, the other for the orelse part
            # Do not check if inner function definition are return ended.
            is_orelse_returning = any(
                self._is_node_return_ended(_ore)
                for _ore in node.orelse
                if not isinstance(_ore, astroid.FunctionDef)
            )
            is_if_returning = any(
                self._is_node_return_ended(_ifn)
                for _ifn in node.body
                if not isinstance(_ifn, astroid.FunctionDef)
            )
            return is_if_returning and is_orelse_returning
        #  recurses on the children of the node except for those which are except handler
        # because one cannot be sure that the handler will really be used
        return any(
            self._is_node_return_ended(_child)
            for _child in node.get_children()
            if not isinstance(_child, astroid.ExceptHandler)
        )
Check if the node ends with an explicit return statement.

        Args:
            node (astroid.NodeNG): node to be checked.

        Returns:
            bool: True if the node ends with an explicit statement, False otherwise.