Beispiel #1
0
    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.infered()[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.
            return_stmts = [self._is_node_return_ended(_child) for _child in node.get_children()
                            if not isinstance(_child, astroid.FunctionDef)]
            return sum(return_stmts) == 2
        # 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))
Beispiel #2
0
    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.infered()[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.
            return_stmts = [self._is_node_return_ended(_child) for _child in node.get_children()
                            if not isinstance(_child, astroid.FunctionDef)]
            return sum(return_stmts) == 2
        # 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))