class Interpreter(object): """ An interpreter object. fixme: needs to negotiate available formatters with frontends. """ def __init__(self, namespace=None, translator=None, magic=None, display_formatters=None, traceback_formatters=None, output_trap=None, history=None, message_cache=None, filename='<string>', config=None): # The namespace. if namespace is None: namespace = {} self.namespace = namespace # An object that will translate commands into executable Python. # The current translator does not work properly so for now we are going # without! # if translator is None: # from ipython1.core1.translator import IPythonTranslator # translator = IPythonTranslator() self.translator = translator # An object that maintains magic commands. if magic is None: from ipython1.core1.magic import Magic magic = Magic(self) self.magic = magic # A list of formatters for the displayhook. if display_formatters is None: display_formatters = default_display_formatters() self.display_formatters = display_formatters # A list of formatters for tracebacks. if traceback_formatters is None: traceback_formatters = default_traceback_formatters() self.traceback_formatters = traceback_formatters # The object trapping stdout/stderr. if output_trap is None: from ipython1.core1.output_trap import OutputTrap output_trap = OutputTrap() self.output_trap = output_trap # An object that manages the history. if history is None: from ipython1.core1.history import History history = History() self.history = history # An object that caches all of the return messages. if message_cache is None: from ipython1.core1.message_cache import SimpleMessageCache message_cache = SimpleMessageCache() self.message_cache = message_cache # The "filename" of the code that is executed in this interpreter. self.filename = filename # An object that contains much configuration information. if config is None: # fixme: Move this constant elsewhere! config = Bunch(ESC_MAGIC='%') self.config = config # Hook managers. # fixme: make the display callbacks configurable. In the meantime, # enable macros. self.display_trap = DisplayTrap( formatters=self.display_formatters, callbacks=[self._possible_macro], ) self.traceback_trap = TracebackTrap( formatters=self.traceback_formatters) # An object that can compile commands and remember __future__ # statements. self.command_compiler = codeop.CommandCompiler() # A replacement for the raw_input() and input() builtins. Change these # attributes later to configure them. self.raw_input_builtin = raw_input self.input_builtin = input # The number of the current cell. self.current_cell_number = 1 # This is the message dictionary assigned temporarily when running the # code. self.message = None self.setup_namespace() #### Public 'Interpreter' interface ######################################## def execute(self, commands): """ Execute some IPython commands. 1. Translate them into Python. 2. Run them. 3. Trap stdout/stderr. 4. Trap sys.displayhook(). 5. Trap exceptions. 6. Return a message object. Parameters ---------- commands : str The raw commands that the user typed into the prompt. Returns ------- message : dict The dictionary of responses. See the README.txt in this directory for an explanation of the format. """ # Create a message dictionary with all of the information we will be # returning to the frontend and other listeners. message = dict(number=self.current_cell_number) # Massage the input and store the raw and translated commands into # a dict. input = dict(raw=commands) if self.translator is not None: python = self.translator(commands, message) if python is None: # Something went wrong with the translation. The translator # should have added an appropriate entry to the message object. return message else: python = commands input['translated'] = python message['input'] = input # Set the message object so that any magics executed in the code have # access. self.message = message # Set all of the output/exception traps. self.set_traps() # Actually execute the Python code. status = self.execute_python(python) # Unset all of the traps. self.unset_traps() # Unset the message object. self.message = None # Update the history variables in the namespace. # E.g. In, Out, _, __, ___ if self.history is not None: self.history.update_history(self, python) # Let all of the traps contribute to the message and then clear their # stored information. self.output_trap.add_to_message(message) self.output_trap.clear() self.display_trap.add_to_message(message) self.display_trap.clear() self.traceback_trap.add_to_message(message) self.traceback_trap.clear() # Cache the message. self.message_cache.add_message(self.current_cell_number, message) # Bump the number. self.current_cell_number += 1 return message def execute_python(self, python): """ Actually run the Python code in the namespace. Parameters ---------- python : str Pure, exec'able Python code. Special IPython commands should have already been translated into pure Python. """ # We use a CommandCompiler instance to compile the code so as to keep # track of __future__ imports. try: commands = self.split_commands(python) except SyntaxError, e: # The code has incorrect syntax. Return the exception object with # the message. self.message['syntax_error'] = e return for cmd in commands: code = self.command_compiler(cmd, self.filename, 'single') try: exec code in self.namespace except: self.traceback_trap.args = sys.exc_info()
class Interpreter(object): """ An interpreter object. fixme: needs to negotiate available formatters with frontends. """ def __init__(self, namespace=None, translator=None, magic=None, display_formatters=None, traceback_formatters=None, output_trap=None, history=None, message_cache=None, filename='<string>', config=None): # The namespace. if namespace is None: namespace = {} self.namespace = namespace # An object that will translate commands into executable Python. # The current translator does not work properly so for now we are going # without! # if translator is None: # from ipython1.core.translator import IPythonTranslator # translator = IPythonTranslator() self.translator = translator # An object that maintains magic commands. if magic is None: from ipython1.core.magic import Magic magic = Magic(self) self.magic = magic # A list of formatters for the displayhook. if display_formatters is None: display_formatters = default_display_formatters() self.display_formatters = display_formatters # A list of formatters for tracebacks. if traceback_formatters is None: traceback_formatters = default_traceback_formatters() self.traceback_formatters = traceback_formatters # The object trapping stdout/stderr. if output_trap is None: from ipython1.core.output_trap import OutputTrap output_trap = OutputTrap() self.output_trap = output_trap # An object that manages the history. if history is None: from ipython1.core.history import History history = History() self.history = history # An object that caches all of the return messages. if message_cache is None: from ipython1.core.message_cache import SimpleMessageCache message_cache = SimpleMessageCache() self.message_cache = message_cache # The "filename" of the code that is executed in this interpreter. self.filename = filename # An object that contains much configuration information. if config is None: # fixme: Move this constant elsewhere! config = Bunch(ESC_MAGIC='%') self.config = config # Hook managers. # fixme: make the display callbacks configurable. In the meantime, # enable macros. self.display_trap = DisplayTrap( formatters=self.display_formatters, callbacks=[self._possible_macro], ) self.traceback_trap = TracebackTrap( formatters=self.traceback_formatters) # This is used temporarily for reformating exceptions in certain # cases. It will go away once the ultraTB stuff is ported # to ipython1 self.tbHandler = ultraTB.FormattedTB(color_scheme='NoColor', mode='Context', tb_offset=2) # An object that can compile commands and remember __future__ # statements. self.command_compiler = codeop.CommandCompiler() # A replacement for the raw_input() and input() builtins. Change these # attributes later to configure them. self.raw_input_builtin = raw_input self.input_builtin = input # The number of the current cell. self.current_cell_number = 1 # This is the message dictionary assigned temporarily when running the # code. self.message = None self.setup_namespace() #### Public 'Interpreter' interface ######################################## def formatTraceback(self, et, ev, tb, message=''): """Put a formatted version of the traceback into value and reraise. When exceptions have to be sent over the network, the traceback needs to be put into the value of the exception in a nicely formatted way. The method takes the type, value and tb of an exception and puts a string representation of the tb into the value of the exception and reraises it. Currently this method uses the ultraTb formatter from IPython trunk. Eventually it should simply use the traceback formatters in core that are loaded into self.tracback_trap.formatters. """ tbinfo = self.tbHandler.text(et,ev,tb) newValue = """\ %(ev)s *************************************************************************** An exception occurred in the IPython Interpreter due to a user action. This usually means that user code has a problem in it somewhere. %(message)s A full traceback from the actual interpreter: %(tbinfo)s *************************************************************************** """ % locals() return et, newValue, tb def execute(self, commands, raiseException=True): """ Execute some IPython commands. 1. Translate them into Python. 2. Run them. 3. Trap stdout/stderr. 4. Trap sys.displayhook(). 5. Trap exceptions. 6. Return a message object. Parameters ---------- commands : str The raw commands that the user typed into the prompt. Returns ------- message : dict The dictionary of responses. See the README.txt in this directory for an explanation of the format. """ # Create a message dictionary with all of the information we will be # returning to the frontend and other listeners. message = dict(number=self.current_cell_number) # Massage the input and store the raw and translated commands into # a dict. input = dict(raw=commands) if self.translator is not None: python = self.translator(commands, message) if python is None: # Something went wrong with the translation. The translator # should have added an appropriate entry to the message object. return message else: python = commands input['translated'] = python message['input'] = input # Set the message object so that any magics executed in the code have # access. self.message = message # Set all of the output/exception traps. self.set_traps() # Actually execute the Python code. status = self.execute_python(python) # Unset all of the traps. self.unset_traps() # Unset the message object. self.message = None # Update the history variables in the namespace. # E.g. In, Out, _, __, ___ if self.history is not None: self.history.update_history(self, python) # Let all of the traps contribute to the message and then clear their # stored information. self.output_trap.add_to_message(message) self.output_trap.clear() self.display_trap.add_to_message(message) self.display_trap.clear() self.traceback_trap.add_to_message(message) # Pull out the type, value and tb of the current exception # before clearing it. tracebackTuple = self.traceback_trap.args self.traceback_trap.clear() # Cache the message. self.message_cache.add_message(self.current_cell_number, message) # Bump the number. self.current_cell_number += 1 # This conditional lets the execute method either raise any # exception that has occured in user code OR return the message # dict containing the traceback and other useful info. if raiseException and tracebackTuple: raise tracebackTuple else: return message def execute_python(self, python): """ Actually run the Python code in the namespace. Parameters ---------- python : str Pure, exec'able Python code. Special IPython commands should have already been translated into pure Python. """ # We use a CommandCompiler instance to compile the code so as to keep # track of __future__ imports. try: commands = self.split_commands(python) except (SyntaxError, IndentationError), e: # The code has incorrect syntax. Return the exception object with # the message. self.message['syntax_error'] = e # Save the exc_info so compilation related exceptions can be # reraised self.traceback_trap.args = sys.exc_info() return for cmd in commands: code = self.command_compiler(cmd, self.filename, 'single') try: exec code in self.namespace except: self.traceback_trap.args = sys.exc_info()
class Interpreter(object): """ An interpreter object. fixme: needs to negotiate available formatters with frontends. """ def __init__(self, namespace=None, global_ns=None, translator=None, magic=None, display_formatters=None, traceback_formatters=None, output_trap=None, history=None, message_cache=None, filename='<string>', config=None): # The local/global namespaces for code execution local_ns = namespace # compatibility name if local_ns is None: local_ns = {} self.user_ns = local_ns # The local namespace if global_ns is None: global_ns = {} self.user_global_ns = global_ns # An object that will translate commands into executable Python. # The current translator does not work properly so for now we are going # without! # if translator is None: # from ipython1.core1.translator import IPythonTranslator # translator = IPythonTranslator() self.translator = translator # An object that maintains magic commands. if magic is None: from ipython1.core1.magic import Magic magic = Magic(self) self.magic = magic # A list of formatters for the displayhook. if display_formatters is None: display_formatters = default_display_formatters() self.display_formatters = display_formatters # A list of formatters for tracebacks. if traceback_formatters is None: traceback_formatters = default_traceback_formatters() self.traceback_formatters = traceback_formatters # The object trapping stdout/stderr. if output_trap is None: from ipython1.core1.output_trap import OutputTrap output_trap = OutputTrap() self.output_trap = output_trap # An object that manages the history. if history is None: from ipython1.core1.history import History history = History() self.history = history # An object that caches all of the return messages. if message_cache is None: from ipython1.core1.message_cache import SimpleMessageCache message_cache = SimpleMessageCache() self.message_cache = message_cache # The "filename" of the code that is executed in this interpreter. self.filename = filename # An object that contains much configuration information. if config is None: # fixme: Move this constant elsewhere! config = Bunch(ESC_MAGIC='%') self.config = config # Hook managers. # fixme: make the display callbacks configurable. In the meantime, # enable macros. self.display_trap = DisplayTrap( formatters=self.display_formatters, callbacks=[self._possible_macro], ) self.traceback_trap = TracebackTrap( formatters=self.traceback_formatters) # An object that can compile commands and remember __future__ # statements. self.command_compiler = codeop.CommandCompiler() # A replacement for the raw_input() and input() builtins. Change these # attributes later to configure them. self.raw_input_builtin = raw_input self.input_builtin = input # The number of the current cell. self.current_cell_number = 1 # Initialize cache, set in/out prompts and printing system self.outputcache = CachedOutput(self, rc.cache_size, rc.pprint, input_sep=rc.separate_in, output_sep=rc.separate_out, output_sep2=rc.separate_out2, ps1=rc.prompt_in1, ps2=rc.prompt_in2, ps_out=rc.prompt_out, pad_left=rc.prompts_pad_left) # Need to decide later if this is the right approach, but clients # commonly use sys.ps1/2, so it may be best to just set them here sys.ps1 = self.outputcache.prompt1.p_str sys.ps2 = self.outputcache.prompt2.p_str # This is the message dictionary assigned temporarily when running the # code. self.message = None self.setup_namespace() #### Public 'Interpreter' interface ######################################## def execute(self, commands): """ Execute some IPython commands. 1. Translate them into Python. 2. Run them. 3. Trap stdout/stderr. 4. Trap sys.displayhook(). 5. Trap exceptions. 6. Return a message object. Parameters ---------- commands : str The raw commands that the user typed into the prompt. Returns ------- message : dict The dictionary of responses. See the README.txt in this directory for an explanation of the format. """ # Create a message dictionary with all of the information we will be # returning to the frontend and other listeners. message = self.setup_message() # Massage the input and store the raw and translated commands into # a dict. user_input = dict(raw=commands) if self.translator is not None: python = self.translator(commands, message) if python is None: # Something went wrong with the translation. The translator # should have added an appropriate entry to the message object. return message else: python = commands user_input['translated'] = python message['input'] = user_input # Set the message object so that any magics executed in the code have # access. self.message = message # Set all of the output/exception traps. self.set_traps() # Actually execute the Python code. status = self.execute_python(python) # Unset all of the traps. self.unset_traps() # Unset the message object. self.message = None # Actually execute the Python code. self.history.update_history(self, python) # Let all of the traps contribute to the message and then clear their # stored information. self.output_trap.add_to_message(message) self.output_trap.clear() self.display_trap.add_to_message(message) self.display_trap.clear() self.traceback_trap.add_to_message(message) self.traceback_trap.clear() # Cache the message. self.message_cache.add_message(self.current_cell_number, message) # Bump the number. self.current_cell_number += 1 #print 'MESSAGE IS:',message # dbg return message def execute_python(self, python): """ Actually run the Python code in the namespace. :Parameters: python : str Pure, exec'able Python code. Special IPython commands should have already been translated into pure Python. """ # We use a CommandCompiler instance to compile the code so as to keep # track of __future__ imports. try: commands = self.split_commands(python) except (SyntaxError, IndentationError), e: # Save the exc_info so compilation related exceptions can be # reraised self.traceback_trap.args = sys.exc_info() self.pack_exception(self.message, e) return None for cmd in commands: try: code = self.command_compiler(cmd, self.filename, 'single') except (SyntaxError, OverflowError, ValueError), e: self.traceback_trap.args = sys.exc_info() self.pack_exception(self.message, e) # No point in continuing if one block raised return None else: self.execute_block(code)