def visit_unaryop(self, node): if node.op != 'not': return operand = node.operand if isinstance(operand, astroid.UnaryOp) and operand.op == 'not': self.add_message('unneeded-not', node=node, args=(node.as_string(), operand.operand.as_string())) elif isinstance(operand, astroid.Compare): left = operand.left # ignore multiple comparisons if len(operand.ops) > 1: return operator, right = operand.ops[0] if operator not in self.reverse_op: return # Ignore __ne__ as function of __eq__ frame = node.frame() if frame.name == '__ne__' and operator == '==': return for _type in (utils.node_type(left), utils.node_type(right)): if not _type: return if isinstance(_type, self.skipped_nodes): return if (isinstance(_type, astroid.Instance) and _type.qname() in self.skipped_classnames): return suggestion = '%s %s %s' % ( left.as_string(), self.reverse_op[operator], right.as_string()) self.add_message('unneeded-not', node=node, args=(node.as_string(), suggestion))
def visit_unaryop(self, node): if node.op != 'not': return operand = node.operand if isinstance(operand, astroid.UnaryOp) and operand.op == 'not': self.add_message('unneeded-not', node=node, args=(node.as_string(), operand.operand.as_string())) elif isinstance(operand, astroid.Compare): left = operand.left # ignore multiple comparisons if len(operand.ops) > 1: return operator, right = operand.ops[0] if operator not in self.reverse_op: return # Ignore __ne__ as function of __eq__ frame = node.frame() if frame.name == '__ne__' and operator == '==': return for _type in (utils.node_type(left), utils.node_type(right)): if not _type: return if isinstance(_type, self.skipped_nodes): return if (isinstance(_type, astroid.Instance) and _type.qname() in self.skipped_classnames): return suggestion = '%s %s %s' % (left.as_string(), self.reverse_op[operator], right.as_string()) self.add_message('unneeded-not', node=node, args=(node.as_string(), suggestion))
def _detect_nonboolean_not(self, node): if node.op != 'not': return if isinstance(node.operand, astroid.Call): operand_type = utils.node_type(node.operand.func) operand_type = operand_type.returns if operand_type else None if isinstance(operand_type, astroid.Subscript): # This means return is like Optional[Something]. Ignore these cases # as it's not possible to determine the type afaics return else: operand_type = utils.node_type(node.operand) if operand_type is None: return if operand_type.name != 'bool': self.add_message(NONBOOLEANNOT_SYMBOL, node=node)
def visit_assign(self, node): # we don't handle multiple assignment nor slice assignment target = node.targets[0] if isinstance(target, (astroid.Tuple, astroid.Subscript)): return # ignore NoneType if is_none(node): return _type = node_type(node.value) if _type: self._assigns[-1].setdefault(target.as_string(), []).append( (node, _type.pytype()))
def visit_unaryop(self, node: nodes.UnaryOp) -> None: if node.op != "not": return operand = node.operand if isinstance(operand, nodes.UnaryOp) and operand.op == "not": self.add_message( "unneeded-not", node=node, args=(node.as_string(), operand.operand.as_string()), ) elif isinstance(operand, nodes.Compare): left = operand.left # ignore multiple comparisons if len(operand.ops) > 1: return operator, right = operand.ops[0] if operator not in self.reverse_op: return # Ignore __ne__ as function of __eq__ frame = node.frame(future=True) if frame.name == "__ne__" and operator == "==": return for _type in (utils.node_type(left), utils.node_type(right)): if not _type: return if isinstance(_type, self.skipped_nodes): return if (isinstance(_type, astroid.Instance) and _type.qname() in self.skipped_classnames): return suggestion = ( f"{left.as_string()} {self.reverse_op[operator]} {right.as_string()}" ) self.add_message("unneeded-not", node=node, args=(node.as_string(), suggestion))