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]
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]
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
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]