def check_safesuper(tree, bindings, log):
    acceptable_uses = set()
    for call in find_all(tree, ast.CallFunc):
        if isinstance(call.node, ast.Name):
            binding = varbindings.get_only(call.node.bindings)
            if (binding.is_global and
                binding.name == "safesuper" and
                len(call.args) >= 1 and
                varbindings.map_node(call.args[0]).is_self_var()):
                acceptable_uses.add(call.node)
    for node in find_all(tree, ast.Name):
        binding = varbindings.get_only(node.bindings)
        if binding.name == "safesuper":
            if binding.is_global:
                if node not in acceptable_uses:
                    log.append(("Super", node))
            else:
                # Shadowing is not allowed.
                log.append(("SuperShadowed", node))
def check(tree, bindings):
    log = []
    for class_node in find_all(tree, ast.Class):
        for defn in class_node.code.nodes:
            if isinstance(defn, ast.Function):
                method_binding = varbindings.get_only(defn.bindings)
                if (defn.decorators is None and
                    not method_binding.is_read and
                    not method_binding.is_global and
                    len(defn.argnames) >= 1):
                    binding = defn.code.environ.lookup(defn.argnames[0])
                    if not binding.is_assigned:
                        binding.is_self_var = True
    for node, expr_node, attr_name in find_attribute_assignments(tree):
        if not varbindings.map_node(expr_node).is_self_var():
            log.append(("SetAttr", node))
        elif is_special_attr(attr_name):
            log.append(("SpecialAttr", node))
    for node in find_all(tree, ast.Getattr):
        if (not varbindings.map_node(node.expr).is_self_var() and
            is_private_attr(node.attrname)):
            log.append(("GetAttr", node))
        elif is_special_attr(node.attrname):
            log.append(("SpecialAttr", node))
    for node in find_all(tree, (ast.Print, ast.Printnl)):
        log.append(("Print", node))
    for node in find_all(tree, ast.Exec):
        log.append(("Exec", node))
    for node in find_all(tree, ast.From):
        for attr_name, as_name in node.names:
            if attr_name == "*":
                log.append(("BlanketImport", node))
    for binding in bindings:
        if is_special_var(binding.name):
            assert len(binding.references) > 0
            for var_ref in binding.references:
                log.append(("SpecialVar", var_ref.node))
    check_safesuper(tree, bindings, log)
    return log