# Path: py3kwarn2to3/fixer_base.py
# class BaseFix(object):
# class ConditionalFix(BaseFix):
#     PATTERN = None  # Most subclasses should override with a string literal
#             PC = PatternCompiler()
#     def __init__(self, options, log):
#     def compile_pattern(self):
#     def set_filename(self, filename):
#     def match(self, node):
#     def transform(self, node, results):
#     def new_name(self, template=u"xxx_todo_changeme"):
#     def log_message(self, message):
#     def cannot_convert(self, node, reason=None):
#     def warning(self, node, reason):
#     def start_tree(self, tree, filename):
#     def finish_tree(self, tree, filename):
#     def start_tree(self, *args):
#     def should_skip(self, node):
# 
# Path: py3kwarn2to3/fixer_util.py
# def Call(func_name, args=None, prefix=None):
#     """A function call"""
#     node = Node(syms.power, [func_name, ArgList(args)])
#     if prefix is not None:
#         node.prefix = prefix
#     return node
# 
# def Name(name, prefix=None):
#     """Return a NAME leaf"""
#     return Leaf(token.NAME, name, prefix=prefix)
# 
# def String(string, prefix=None):
#     """A string leaf"""
#     return Leaf(token.STRING, string, prefix=prefix)
# 
# def Attr(obj, attr):
#     """A node tuple for obj.attr"""
#     return [obj, Node(syms.trailer, [Dot(), attr])]
# 
# def touch_import(package, name, node):
#     """ Works like `does_tree_import` but adds an import statement
#         if it was not imported. """
#     def is_import_stmt(node):
#         return (node.type == syms.simple_stmt and node.children and
#                 is_import(node.children[0]))
# 
#     root = find_root(node)
# 
#     if does_tree_import(package, name, root):
#         return
# 
#     # figure out where to insert the new import.  First try to find
#     # the first import and then skip to the last one.
#     insert_pos = offset = 0
#     for idx, node in enumerate(root.children):
#         if not is_import_stmt(node):
#             continue
#         for offset, node2 in enumerate(root.children[idx:]):
#             if not is_import_stmt(node2):
#                 break
#         insert_pos = idx + offset
#         break
# 
#     # if there are no imports where we can insert, find the docstring.
#     # if that also fails, we stick to the beginning of the file
#     if insert_pos == 0:
#         for idx, node in enumerate(root.children):
#             if (node.type == syms.simple_stmt and node.children and
#                node.children[0].type == token.STRING):
#                 insert_pos = idx + 1
#                 break
# 
#     if package is None:
#         import_ = Node(syms.import_name, [
#             Leaf(token.NAME, u"import"),
#             Leaf(token.NAME, name, prefix=u" ")
#         ])
#     else:
#         import_ = FromImport(package, [Leaf(token.NAME, name, prefix=u" ")])
# 
#     children = [import_, Newline()]
#     root.insert_child(insert_pos, Node(syms.simple_stmt, children))


from py3kwarn2to3 import fixer_base
from py3kwarn2to3.fixer_util import Call, Name, String, Attr, touch_import

"""Fixer for callable().

This converts callable(obj) into isinstance(obj, collections.Callable), adding a
collections import if needed."""

# Local imports

class FixCallable(fixer_base.BaseFix):
    BM_compatible = True

    order = "pre"

    # Ignore callable(*args) or use of keywords.
    # Either could be a hint that the builtin callable() is not being used.
    PATTERN = """
    power< 'callable'
           trailer< lpar='('
                    ( not(arglist | argument<any '=' any>) func=any
                      | func=arglist<(not argument<any '=' any>) any ','> )
                    rpar=')' >
           after=any*
    >
    """

    def transform(self, node, results):
        func = results['func']

        touch_import(None, u'collections', node=node)


# Path: py3kwarn2to3/fixer_base.py
# class BaseFix(object):
# class ConditionalFix(BaseFix):
#     PATTERN = None  # Most subclasses should override with a string literal
#             PC = PatternCompiler()
#     def __init__(self, options, log):
#     def compile_pattern(self):
#     def set_filename(self, filename):
#     def match(self, node):
#     def transform(self, node, results):
#     def new_name(self, template=u"xxx_todo_changeme"):
#     def log_message(self, message):
#     def cannot_convert(self, node, reason=None):
#     def warning(self, node, reason):
#     def start_tree(self, tree, filename):
#     def finish_tree(self, tree, filename):
#     def start_tree(self, *args):
#     def should_skip(self, node):
# 
# Path: py3kwarn2to3/fixer_util.py
# def Call(func_name, args=None, prefix=None):
#     """A function call"""
#     node = Node(syms.power, [func_name, ArgList(args)])
#     if prefix is not None:
#         node.prefix = prefix
#     return node
# 
# def Name(name, prefix=None):
#     """Return a NAME leaf"""
#     return Leaf(token.NAME, name, prefix=prefix)
# 
# def String(string, prefix=None):
#     """A string leaf"""
#     return Leaf(token.STRING, string, prefix=prefix)
# 
# def Attr(obj, attr):
#     """A node tuple for obj.attr"""
#     return [obj, Node(syms.trailer, [Dot(), attr])]
# 
# def touch_import(package, name, node):
#     """ Works like `does_tree_import` but adds an import statement
#         if it was not imported. """
#     def is_import_stmt(node):
#         return (node.type == syms.simple_stmt and node.children and
#                 is_import(node.children[0]))
# 
#     root = find_root(node)
# 
#     if does_tree_import(package, name, root):
#         return
# 
#     # figure out where to insert the new import.  First try to find
#     # the first import and then skip to the last one.
#     insert_pos = offset = 0
#     for idx, node in enumerate(root.children):
#         if not is_import_stmt(node):
#             continue
#         for offset, node2 in enumerate(root.children[idx:]):
#             if not is_import_stmt(node2):
#                 break
#         insert_pos = idx + offset
#         break
# 
#     # if there are no imports where we can insert, find the docstring.
#     # if that also fails, we stick to the beginning of the file
#     if insert_pos == 0:
#         for idx, node in enumerate(root.children):
#             if (node.type == syms.simple_stmt and node.children and
#                node.children[0].type == token.STRING):
#                 insert_pos = idx + 1
#                 break
# 
#     if package is None:
#         import_ = Node(syms.import_name, [
#             Leaf(token.NAME, u"import"),
#             Leaf(token.NAME, name, prefix=u" ")
#         ])
#     else:
#         import_ = FromImport(package, [Leaf(token.NAME, name, prefix=u" ")])
# 
#     children = [import_, Newline()]
#     root.insert_child(insert_pos, Node(syms.simple_stmt, children))


# Path: py3kwarn2to3/fixes/fix_callable.py
from py3kwarn2to3 import fixer_base
from py3kwarn2to3.fixer_util import Call, Name, String, Attr, touch_import


"""Fixer for callable().

This converts callable(obj) into isinstance(obj, collections.Callable), adding a
collections import if needed."""

# Local imports

class FixCallable(fixer_base.BaseFix):
    BM_compatible = True

    order = "pre"

    # Ignore callable(*args) or use of keywords.
    # Either could be a hint that the builtin callable() is not being used.
    PATTERN = """
    power< 'callable'
           trailer< lpar='('
                    ( not(arglist | argument<any '=' any>) func=any
                      | func=arglist<(not argument<any '=' any>) any ','> )
                    rpar=')' >
           after=any*
    >
    """

    def transform(self, node, results):
        func = results['func']

        touch_import(None, u'collections', node=node)


        args = [func.clone(), String(u', ')]