/** * @name Membership test with a non-container * @description A membership test, such as 'item in sequence', with a non-container on the right hand side will raise a 'TypeError'. * @kind problem * @tags reliability * correctness * @problem.severity error * @sub-severity high * @precision high * @id py/member-test-non-container */ import python predicate rhs_in_expr(ControlFlowNode rhs, Compare cmp) { exists(Cmpop op, int i | cmp.getOp(i) = op and cmp.getComparator(i) = rhs.getNode() | op instanceof In or op instanceof NotIn ) } from ControlFlowNode non_seq, Compare cmp, ClassObject cls, ControlFlowNode origin where rhs_in_expr(non_seq, cmp) and non_seq.refersTo(_, cls, origin) and not cls.failedInference() and not cls.hasAttribute("__contains__") and not cls.hasAttribute("__iter__") and not cls.hasAttribute("__getitem__") and not cls = theNoneType() select cmp, "This test may raise an Exception as the $@ may be of non-container class $@.", origin, "target", cls, cls.getName()