# Path: snaked/plugins/python_repl/executor.py
# def execute(self, source, lineno=None):
#     oldstdout = sys.stdout
#     oldstderr = sys.stderr
#     sys.stdout = self.buffer
#     sys.stderr = self.buffer
#     try:
#         tree = ast.parse(source, '<repl>', 'exec')
#         if lineno:
#             ast.increment_lineno(tree, lineno-1)
# 
#         for node, etype in break_ast_to_exec_parts(tree):
#             result = eval(compile(node, '<repl>', etype), {}, self.locals)
#             if etype == 'eval':
#                 if result is not None:
#                     self.write(repr(result) + '\n')
#                 self.locals['___'] = self.locals.get('__', None)
#                 self.locals['__'] = self.locals.get('_', None)
#                 self.locals['_'] = result
# 
#     except SystemExit:
#         raise
#     except SyntaxError:
#         self.showsyntaxerror()
#     except:
#         self.showtraceback()
#     finally:
#         sys.stdout = oldstdout
#         sys.stderr = oldstderr
# 
# def patch(package_name, code):
#     pkg = sys.modules[package_name]
#     old_funcs = {}
#     for name, obj in pkg.__dict__.iteritems():
#         if isinstance(obj, types.FunctionType):
#             old_funcs[name] = obj
# 
#     eval(compile(code, pkg.__file__, 'exec'), pkg.__dict__)
# 
#     for name, obj in pkg.__dict__.iteritems():
#         if isinstance(obj, types.FunctionType):
#             if name in old_funcs and obj is not old_funcs[name]:
#                 replace_code(name, old_funcs[name], obj)
# 
# class Interpreter(code.InteractiveInterpreter):
#     def __init__(self):
#         code.InteractiveInterpreter.__init__(self)
#         self.buffer = StringIO.StringIO()
# 
#     def execute(self, source, lineno=None):
#         oldstdout = sys.stdout
#         oldstderr = sys.stderr
#         sys.stdout = self.buffer
#         sys.stderr = self.buffer
#         try:
#             tree = ast.parse(source, '<repl>', 'exec')
#             if lineno:
#                 ast.increment_lineno(tree, lineno-1)
# 
#             for node, etype in break_ast_to_exec_parts(tree):
#                 result = eval(compile(node, '<repl>', etype), {}, self.locals)
#                 if etype == 'eval':
#                     if result is not None:
#                         self.write(repr(result) + '\n')
#                     self.locals['___'] = self.locals.get('__', None)
#                     self.locals['__'] = self.locals.get('_', None)
#                     self.locals['_'] = result
# 
#         except SystemExit:
#             raise
#         except SyntaxError:
#             self.showsyntaxerror()
#         except:
#             self.showtraceback()
#         finally:
#             sys.stdout = oldstdout
#             sys.stderr = oldstderr
# 
#     def write(self, data):
#         self.buffer.write(data)
# 
#     def get_buffer(self):
#         data = self.buffer.getvalue()
#         self.buffer = StringIO.StringIO()
#         return data


import sys
from inspect import cleandoc
from snaked.plugins.python_repl.executor import execute, patch, Interpreter
    from tests.patcher.first import simple_func
    from tests.patcher.first import decorated_func, another_decorated_func
    from tests.patcher.first import decorated_func, another_decorated_func
    remove_test_modules()

    result = simple_func(1)
    assert result == 3

    code = '''
def simple_func(x):
    return x + CONST + 1
    '''

    patch('tests.patcher.first', code)

    result = simple_func(1)
    assert result == 4

def test_decorated_funcs_runtime_code_replace():
    remove_test_modules()

    result = decorated_func(1)
    assert result == 2

    result = another_decorated_func(3)
    assert result == 16

    code = '''
@decorator
def decorated_func(x):
    return x + 1
    '''


# Path: snaked/plugins/python_repl/executor.py
# def execute(self, source, lineno=None):
#     oldstdout = sys.stdout
#     oldstderr = sys.stderr
#     sys.stdout = self.buffer
#     sys.stderr = self.buffer
#     try:
#         tree = ast.parse(source, '<repl>', 'exec')
#         if lineno:
#             ast.increment_lineno(tree, lineno-1)
# 
#         for node, etype in break_ast_to_exec_parts(tree):
#             result = eval(compile(node, '<repl>', etype), {}, self.locals)
#             if etype == 'eval':
#                 if result is not None:
#                     self.write(repr(result) + '\n')
#                 self.locals['___'] = self.locals.get('__', None)
#                 self.locals['__'] = self.locals.get('_', None)
#                 self.locals['_'] = result
# 
#     except SystemExit:
#         raise
#     except SyntaxError:
#         self.showsyntaxerror()
#     except:
#         self.showtraceback()
#     finally:
#         sys.stdout = oldstdout
#         sys.stderr = oldstderr
# 
# def patch(package_name, code):
#     pkg = sys.modules[package_name]
#     old_funcs = {}
#     for name, obj in pkg.__dict__.iteritems():
#         if isinstance(obj, types.FunctionType):
#             old_funcs[name] = obj
# 
#     eval(compile(code, pkg.__file__, 'exec'), pkg.__dict__)
# 
#     for name, obj in pkg.__dict__.iteritems():
#         if isinstance(obj, types.FunctionType):
#             if name in old_funcs and obj is not old_funcs[name]:
#                 replace_code(name, old_funcs[name], obj)
# 
# class Interpreter(code.InteractiveInterpreter):
#     def __init__(self):
#         code.InteractiveInterpreter.__init__(self)
#         self.buffer = StringIO.StringIO()
# 
#     def execute(self, source, lineno=None):
#         oldstdout = sys.stdout
#         oldstderr = sys.stderr
#         sys.stdout = self.buffer
#         sys.stderr = self.buffer
#         try:
#             tree = ast.parse(source, '<repl>', 'exec')
#             if lineno:
#                 ast.increment_lineno(tree, lineno-1)
# 
#             for node, etype in break_ast_to_exec_parts(tree):
#                 result = eval(compile(node, '<repl>', etype), {}, self.locals)
#                 if etype == 'eval':
#                     if result is not None:
#                         self.write(repr(result) + '\n')
#                     self.locals['___'] = self.locals.get('__', None)
#                     self.locals['__'] = self.locals.get('_', None)
#                     self.locals['_'] = result
# 
#         except SystemExit:
#             raise
#         except SyntaxError:
#             self.showsyntaxerror()
#         except:
#             self.showtraceback()
#         finally:
#             sys.stdout = oldstdout
#             sys.stderr = oldstderr
# 
#     def write(self, data):
#         self.buffer.write(data)
# 
#     def get_buffer(self):
#         data = self.buffer.getvalue()
#         self.buffer = StringIO.StringIO()
#         return data


# Path: tests/test_python_repl.py
import sys
from inspect import cleandoc
from snaked.plugins.python_repl.executor import execute, patch, Interpreter
    from tests.patcher.first import simple_func
    from tests.patcher.first import decorated_func, another_decorated_func
    from tests.patcher.first import decorated_func, another_decorated_func

    remove_test_modules()

    result = simple_func(1)
    assert result == 3

    code = '''
def simple_func(x):
    return x + CONST + 1
    '''

    patch('tests.patcher.first', code)

    result = simple_func(1)
    assert result == 4

def test_decorated_funcs_runtime_code_replace():
    remove_test_modules()

    result = decorated_func(1)
    assert result == 2

    result = another_decorated_func(3)
    assert result == 16

    code = '''
@decorator
def decorated_func(x):
    return x + 1
    '''


    patch('tests.patcher.first', code)