Exemplo n.º 1
0
    def visit_tryexcept(self, node):
        """check for empty except"""
        exceptions_classes = []
        nb_handlers = len(node.handlers)
        for index, handler in enumerate(node.handlers):
            if handler.type is None:
                if not utils.is_raising(handler.body):
                    self.add_message('bare-except', node=handler)
                # check if a "except:" is followed by some other
                # except
                if index < (nb_handlers - 1):
                    msg = 'empty except clause should always appear last'
                    self.add_message('bad-except-order', node=node, args=msg)

            elif isinstance(handler.type, astroid.BoolOp):
                self.add_message('binary-op-exception',
                                 node=handler,
                                 args=handler.type.op)
            else:
                try:
                    excs = list(_annotated_unpack_infer(handler.type))
                except astroid.InferenceError:
                    continue

                for part, exc in excs:
                    if exc is astroid.YES:
                        continue
                    if (isinstance(exc, astroid.Instance)
                            and utils.inherit_from_std_ex(exc)):
                        # pylint: disable=protected-access
                        exc = exc._proxied

                    self._check_catching_non_exception(handler, exc, part)

                    if not isinstance(exc, astroid.ClassDef):
                        continue

                    exc_ancestors = [
                        anc for anc in exc.ancestors()
                        if isinstance(anc, astroid.ClassDef)
                    ]

                    for previous_exc in exceptions_classes:
                        if previous_exc in exc_ancestors:
                            msg = '%s is an ancestor class of %s' % (
                                previous_exc.name, exc.name)
                            self.add_message('bad-except-order',
                                             node=handler.type,
                                             args=msg)
                    if (exc.name in self.config.overgeneral_exceptions
                            and exc.root().name == utils.EXCEPTIONS_MODULE
                            and not utils.is_raising(handler.body)):
                        self.add_message('broad-except',
                                         args=exc.name,
                                         node=handler.type)

                    if exc in exceptions_classes:
                        self.add_message('duplicate-except',
                                         args=exc.name,
                                         node=handler.type)

                exceptions_classes += [exc for _, exc in excs]
Exemplo n.º 2
0
    def visit_tryexcept(self, node):
        """check for empty except"""
        exceptions_classes = []
        nb_handlers = len(node.handlers)
        for index, handler in enumerate(node.handlers):
            # `raise` as the first operator inside the except handler
            if utils.is_raising([handler.body[0]]):
                # flags when there is a bare raise
                if handler.body[0].exc is None:
                    self.add_message('try-except-raise', node=handler)
                else:
                    # not a bare raise
                    raise_type = None
                    if isinstance(handler.body[0].exc, astroid.Call):
                        raise_type = handler.body[0].exc.func

                    # flags only when the exception types of the handler
                    # and the raise statement match b/c we're raising the same
                    # type of exception that we're trying to handle. Example:
                    #
                    # except ValueError:
                    #   raise ValueError('some user friendly message')
                    if (isinstance(handler.type, astroid.Name)
                            and isinstance(raise_type, astroid.Name)
                            and raise_type.name == handler.type.name):
                        self.add_message('try-except-raise', node=handler)

            if handler.type is None:
                if not utils.is_raising(handler.body):
                    self.add_message('bare-except', node=handler)

                # check if an "except:" is followed by some other
                # except
                if index < (nb_handlers - 1):
                    msg = 'empty except clause should always appear last'
                    self.add_message('bad-except-order', node=node, args=msg)

            elif isinstance(handler.type, astroid.BoolOp):
                self.add_message('binary-op-exception',
                                 node=handler,
                                 args=handler.type.op)
            else:
                try:
                    excs = list(_annotated_unpack_infer(handler.type))
                except astroid.InferenceError:
                    continue

                for part, exc in excs:
                    if exc is astroid.Uninferable:
                        continue
                    if (isinstance(exc, astroid.Instance)
                            and utils.inherit_from_std_ex(exc)):
                        # pylint: disable=protected-access
                        exc = exc._proxied

                    self._check_catching_non_exception(handler, exc, part)

                    if not isinstance(exc, astroid.ClassDef):
                        continue

                    exc_ancestors = [
                        anc for anc in exc.ancestors()
                        if isinstance(anc, astroid.ClassDef)
                    ]

                    for previous_exc in exceptions_classes:
                        if previous_exc in exc_ancestors:
                            msg = '%s is an ancestor class of %s' % (
                                previous_exc.name, exc.name)
                            self.add_message('bad-except-order',
                                             node=handler.type,
                                             args=msg)
                    if (exc.name in self.config.overgeneral_exceptions
                            and exc.root().name == utils.EXCEPTIONS_MODULE
                            and not utils.is_raising(handler.body)):
                        self.add_message('broad-except',
                                         args=exc.name,
                                         node=handler.type)

                    if exc in exceptions_classes:
                        self.add_message('duplicate-except',
                                         args=exc.name,
                                         node=handler.type)

                exceptions_classes += [exc for _, exc in excs]
Exemplo n.º 3
0
    def visit_tryexcept(self, node):
        """check for empty except"""
        exceptions_classes = []
        nb_handlers = len(node.handlers)
        for index, handler in enumerate(node.handlers):
            # single except doing nothing but "pass" without else clause
            if is_empty(handler.body) and not node.orelse:
                self.add_message('pointless-except',
                                 node=handler.type or handler.body[0])
            if handler.type is None:
                if not is_raising(handler.body):
                    self.add_message('bare-except', node=handler)
                # check if a "except:" is followed by some other
                # except
                if index < (nb_handlers - 1):
                    msg = 'empty except clause should always appear last'
                    self.add_message('bad-except-order', node=node, args=msg)

            elif isinstance(handler.type, astroid.BoolOp):
                self.add_message('binary-op-exception',
                                 node=handler,
                                 args=handler.type.op)
            else:
                try:
                    excs = list(unpack_infer(handler.type))
                except astroid.InferenceError:
                    continue
                for exc in excs:
                    # XXX skip other non class nodes
                    if exc is YES or not isinstance(exc, astroid.Class):
                        continue
                    exc_ancestors = [
                        anc for anc in exc.ancestors()
                        if isinstance(anc, astroid.Class)
                    ]
                    for previous_exc in exceptions_classes:
                        if previous_exc in exc_ancestors:
                            msg = '%s is an ancestor class of %s' % (
                                previous_exc.name, exc.name)
                            self.add_message('bad-except-order',
                                             node=handler.type,
                                             args=msg)
                    if (exc.name in self.config.overgeneral_exceptions
                            and exc.root().name == EXCEPTIONS_MODULE
                            and not is_raising(handler.body)):
                        self.add_message('broad-except',
                                         args=exc.name,
                                         node=handler.type)

                    if (not inherit_from_std_ex(exc)
                            and exc.root().name != BUILTINS_NAME):
                        # try to see if the exception is based on a C based
                        # exception, by infering all the base classes and
                        # looking for inference errors
                        bases = infer_bases(exc)
                        fully_infered = all(inferit is not YES
                                            for inferit in bases)
                        if fully_infered:
                            self.add_message('catching-non-exception',
                                             node=handler.type,
                                             args=(exc.name, ))

                exceptions_classes += excs
Exemplo n.º 4
0
    def visit_tryexcept(self, node):
        """check for empty except"""
        exceptions_classes = []
        nb_handlers = len(node.handlers)
        for index, handler in enumerate(node.handlers):
            # single except doing nothing but "pass" without else clause
            if is_empty(handler.body) and not node.orelse:
                self.add_message('pointless-except',
                                 node=handler.type or handler.body[0])
            if handler.type is None:
                if not is_raising(handler.body):
                    self.add_message('bare-except', node=handler)
                # check if a "except:" is followed by some other
                # except
                if index < (nb_handlers - 1):
                    msg = 'empty except clause should always appear last'
                    self.add_message('bad-except-order', node=node, args=msg)

            elif isinstance(handler.type, astroid.BoolOp):
                self.add_message('binary-op-exception',
                                 node=handler,
                                 args=handler.type.op)
            else:
                try:
                    excs = list(_annotated_unpack_infer(handler.type))
                except astroid.InferenceError:
                    continue
                for part, exc in excs:
                    if exc is YES:
                        continue
                    if isinstance(
                            exc,
                            astroid.Instance) and inherit_from_std_ex(exc):
                        exc = exc._proxied
                    if not isinstance(exc, astroid.Class):
                        # Don't emit the warning if the infered stmt
                        # is None, but the exception handler is something else,
                        # maybe it was redefined.
                        if (isinstance(exc, astroid.Const)
                                and exc.value is None):
                            if ((isinstance(handler.type, astroid.Const)
                                 and handler.type.value is None)
                                    or handler.type.parent_of(exc)):
                                # If the exception handler catches None or
                                # the exception component, which is None, is
                                # defined by the entire exception handler, then
                                # emit a warning.
                                self.add_message('catching-non-exception',
                                                 node=handler.type,
                                                 args=(part.as_string(), ))
                        else:
                            self.add_message('catching-non-exception',
                                             node=handler.type,
                                             args=(part.as_string(), ))
                        continue

                    exc_ancestors = [
                        anc for anc in exc.ancestors()
                        if isinstance(anc, astroid.Class)
                    ]
                    for previous_exc in exceptions_classes:
                        if previous_exc in exc_ancestors:
                            msg = '%s is an ancestor class of %s' % (
                                previous_exc.name, exc.name)
                            self.add_message('bad-except-order',
                                             node=handler.type,
                                             args=msg)
                    if (exc.name in self.config.overgeneral_exceptions
                            and exc.root().name == EXCEPTIONS_MODULE
                            and not is_raising(handler.body)):
                        self.add_message('broad-except',
                                         args=exc.name,
                                         node=handler.type)

                    if (not inherit_from_std_ex(exc)
                            and exc.root().name != BUILTINS_NAME):
                        # try to see if the exception is based on a C based
                        # exception, by infering all the base classes and
                        # looking for inference errors
                        bases = infer_bases(exc)
                        fully_infered = all(inferit is not YES
                                            for inferit in bases)
                        if fully_infered:
                            self.add_message('catching-non-exception',
                                             node=handler.type,
                                             args=(exc.name, ))

                exceptions_classes += [exc for _, exc in excs]