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):
        #  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 ) : #  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.
Check if the node ends with an explicit return statement .