# Path: ayrton/castt.py
#     class NameConstant (_ast.Name):
# class CrazyASTTransformer (ast.NodeTransformer):
#         def __init__ (self, value, *args):
# def append_to_tuple (t, o):
# def pop_from_tuple (t, n=-1):
# def is_executable (node):
# def is_option (arg):
# def has_keyword (node, keyword):
# def update_keyword (node, keyword):
# def func_name2dotted_exec (node):
#     def __init__ (self, environ, file_name=None):
#     def modify (self, tree):
#     def bind (self, o):
#     def unbind (self, name, remove_from_stack=False):
#     def visit_Import (self, node):
#     def visit_ClassDef (self, node):
#     def visit_FunctionDef (self, node):
#     def visit_For (self, node):
#     def visit_ExceptHandler (self, node):
#     def visit_Assign (self, node):
#     def visit_Delete (self, node):
#     def visit_BinOp (self, node):
#     def visit_Compare (self, node):
#     def visit_Call (self, node):
#     def visit_With (self, node):
# 
# Path: ayrton/execute.py
# class o (object):
#     def __init__ (self, **kwargs):
#         option= list (kwargs.items ())[0]
#         self.key=   option[0]
#         self.value= option[1]
# 
# Path: ayrton/functions.py
# class cd (object):
#     def __init__ (self, dir):
#         self.old_dir= os.getcwd ()
#         os.chdir (dir)
# 
#     def __enter__ (self):
#         pass
# 
#     def __exit__ (self, *args):
#         os.chdir (self.old_dir)
# 
# def define(*varnames, **defaults):
#     # defaults have priority over simple names (because they provide a value)
#     for varname in varnames:
#         if varname not in defaults:
#             defaults[varname] = None
# 
#     for varname, value in defaults.items():
#         if not isinstance(varname, str):
#             raise ValueError('variable name cannot be non-string: %r' % varname)
# 
#         if varname not in ayrton.runner.globals:
#             ayrton.runner.globals[varname] = value


import unittest
import ast
import ayrton
from ast import Attribute, Name, Load, Subscript, Index, Num, With, Str
from ast import Break, Continue, Return, Raise, Yield
from ast import Del, Pass, Import, ImportFrom, Global, Assert
from ayrton import castt
from ayrton.execute import o
from ayrton.functions import cd, define

    def testFunctionOArgs (self):
        # NOTE: I need to give the implementation for o();
        # otherwise it will also be converted to Command()
        c= castt.CrazyASTTransformer ({ 'o': o})
        t= ast.parse ("""dict (o (a=53))""")

        node= c.visit_Call (t.body[0].value)

        self.assertEqual (len (node.args), 1, ast.dump (node))
        self.assertEqual (len (node.keywords), 0, ast.dump (node))
        self.check_attrs (node)

    def testDoubleKeywordCommand (self):
        c= castt.CrazyASTTransformer ({ 'o': o})
        t= ayrton.parse ("""foo (p= True, p=False)""")

        node= c.visit_Call (t.body[0].value)

        # Call(func=Call(func=Name(id='Command', ctx=Load()), args=[Str(s='foo')], keywords=[], starargs=None, kwargs=None),
        #      args=[Call(func=Name(id='o', ctx=Load()), args=[], keywords=[keyword(arg='p', value=Name(id='True', ctx=Load()))], starargs=None, kwargs=None),
        #            Call(func=Name(id='o', ctx=Load()), args=[], keywords=[keyword(arg='p', value=Name(id='False', ctx=Load()))], starargs=None, kwargs=None)],
        #      keywords=[], starargs=None, kwargs=None)
        # both arguments have the same name!
        self.assertEqual (node.args[0].keywords[0].arg,
                          node.args[1].keywords[0].arg,
                          "\n%s\n%s\n" % (ast.dump (node.args[0]), ast.dump (node.args[1])))
        self.check_attrs (node)

    def testDoubleKeywordFunction (self):

# Path: ayrton/castt.py
#     class NameConstant (_ast.Name):
# class CrazyASTTransformer (ast.NodeTransformer):
#         def __init__ (self, value, *args):
# def append_to_tuple (t, o):
# def pop_from_tuple (t, n=-1):
# def is_executable (node):
# def is_option (arg):
# def has_keyword (node, keyword):
# def update_keyword (node, keyword):
# def func_name2dotted_exec (node):
#     def __init__ (self, environ, file_name=None):
#     def modify (self, tree):
#     def bind (self, o):
#     def unbind (self, name, remove_from_stack=False):
#     def visit_Import (self, node):
#     def visit_ClassDef (self, node):
#     def visit_FunctionDef (self, node):
#     def visit_For (self, node):
#     def visit_ExceptHandler (self, node):
#     def visit_Assign (self, node):
#     def visit_Delete (self, node):
#     def visit_BinOp (self, node):
#     def visit_Compare (self, node):
#     def visit_Call (self, node):
#     def visit_With (self, node):
# 
# Path: ayrton/execute.py
# class o (object):
#     def __init__ (self, **kwargs):
#         option= list (kwargs.items ())[0]
#         self.key=   option[0]
#         self.value= option[1]
# 
# Path: ayrton/functions.py
# class cd (object):
#     def __init__ (self, dir):
#         self.old_dir= os.getcwd ()
#         os.chdir (dir)
# 
#     def __enter__ (self):
#         pass
# 
#     def __exit__ (self, *args):
#         os.chdir (self.old_dir)
# 
# def define(*varnames, **defaults):
#     # defaults have priority over simple names (because they provide a value)
#     for varname in varnames:
#         if varname not in defaults:
#             defaults[varname] = None
# 
#     for varname, value in defaults.items():
#         if not isinstance(varname, str):
#             raise ValueError('variable name cannot be non-string: %r' % varname)
# 
#         if varname not in ayrton.runner.globals:
#             ayrton.runner.globals[varname] = value


# Path: ayrton/tests/test_castt.py
import unittest
import ast
import ayrton
from ast import Attribute, Name, Load, Subscript, Index, Num, With, Str
from ast import Break, Continue, Return, Raise, Yield
from ast import Del, Pass, Import, ImportFrom, Global, Assert
from ayrton import castt
from ayrton.execute import o
from ayrton.functions import cd, define


    def testFunctionOArgs (self):
        # NOTE: I need to give the implementation for o();
        # otherwise it will also be converted to Command()
        c= castt.CrazyASTTransformer ({ 'o': o})
        t= ast.parse ("""dict (o (a=53))""")

        node= c.visit_Call (t.body[0].value)

        self.assertEqual (len (node.args), 1, ast.dump (node))
        self.assertEqual (len (node.keywords), 0, ast.dump (node))
        self.check_attrs (node)

    def testDoubleKeywordCommand (self):
        c= castt.CrazyASTTransformer ({ 'o': o})
        t= ayrton.parse ("""foo (p= True, p=False)""")

        node= c.visit_Call (t.body[0].value)

        # Call(func=Call(func=Name(id='Command', ctx=Load()), args=[Str(s='foo')], keywords=[], starargs=None, kwargs=None),
        #      args=[Call(func=Name(id='o', ctx=Load()), args=[], keywords=[keyword(arg='p', value=Name(id='True', ctx=Load()))], starargs=None, kwargs=None),
        #            Call(func=Name(id='o', ctx=Load()), args=[], keywords=[keyword(arg='p', value=Name(id='False', ctx=Load()))], starargs=None, kwargs=None)],
        #      keywords=[], starargs=None, kwargs=None)
        # both arguments have the same name!
        self.assertEqual (node.args[0].keywords[0].arg,
                          node.args[1].keywords[0].arg,
                          "\n%s\n%s\n" % (ast.dump (node.args[0]), ast.dump (node.args[1])))
        self.check_attrs (node)

    def testDoubleKeywordFunction (self):

        c= castt.CrazyASTTransformer ({ 'o': o, 'dict': dict})