diff --git a/IPython/core/builtin_trap.py b/IPython/core/builtin_trap.py index 029b2ff..38a8097 100755 --- a/IPython/core/builtin_trap.py +++ b/IPython/core/builtin_trap.py @@ -1,18 +1,17 @@ -#!/usr/bin/env python -# encoding: utf-8 """ A context manager for managing things injected into :mod:`__builtin__`. Authors: * Brian Granger +* Fernando Perez """ - #----------------------------------------------------------------------------- -# Copyright (C) 2008-2009 The IPython Development Team +# Copyright (C) 2010 The IPython Development Team. +# +# Distributed under the terms of the BSD License. # -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. +# Complete license in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- @@ -30,7 +29,6 @@ from IPython.utils.traitlets import Instance # Classes and functions #----------------------------------------------------------------------------- - class __BuiltinUndefined(object): pass BuiltinUndefined = __BuiltinUndefined() @@ -46,26 +44,41 @@ class BuiltinTrap(Configurable): # Only turn off the trap when the outermost call to __exit__ is made. self._nested_level = 0 self.shell = shell + # builtins we always add + self.auto_builtins = {'exit': Quitter(self.shell, 'exit'), + 'quit': Quitter(self.shell, 'quit'), + 'get_ipython': self.shell.get_ipython, + } + # Recursive reload function + try: + from IPython.lib import deepreload + if self.shell.deep_reload: + self.auto_builtins['reload'] = deepreload.reload + else: + self.auto_builtins['dreload']= deepreload.reload + except ImportError: + pass def __enter__(self): if self._nested_level == 0: - self.set() + self.activate() self._nested_level += 1 # I return self, so callers can use add_builtin in a with clause. return self def __exit__(self, type, value, traceback): if self._nested_level == 1: - self.unset() + self.deactivate() self._nested_level -= 1 # Returning False will cause exceptions to propagate return False def add_builtin(self, key, value): """Add a builtin and save the original.""" - orig = __builtin__.__dict__.get(key, BuiltinUndefined) + bdict = __builtin__.__dict__ + orig = bdict.get(key, BuiltinUndefined) self._orig_builtins[key] = orig - __builtin__.__dict__[key] = value + bdict[key] = value def remove_builtin(self, key): """Remove an added builtin and re-set the original.""" @@ -79,34 +92,26 @@ class BuiltinTrap(Configurable): else: __builtin__.__dict__[key] = orig - def set(self): + def activate(self): """Store ipython references in the __builtin__ namespace.""" - self.add_builtin('exit', Quitter(self.shell, 'exit')) - self.add_builtin('quit', Quitter(self.shell, 'quit')) - self.add_builtin('get_ipython', self.shell.get_ipython) - # Recursive reload function - try: - from IPython.lib import deepreload - if self.shell.deep_reload: - self.add_builtin('reload', deepreload.reload) - else: - self.add_builtin('dreload', deepreload.reload) - del deepreload - except ImportError: - pass + add_builtin = self.add_builtin + for name, func in self.auto_builtins.iteritems(): + add_builtin(name, func) # Keep in the builtins a flag for when IPython is active. We set it # with setdefault so that multiple nested IPythons don't clobber one - # another. Each will increase its value by one upon being activated, - # which also gives us a way to determine the nesting level. - __builtin__.__dict__.setdefault('__IPYTHON__active',0) + # another. + __builtin__.__dict__.setdefault('__IPYTHON__active', 0) - def unset(self): + def deactivate(self): """Remove any builtins which might have been added by add_builtins, or restore overwritten ones to their previous values.""" + # Note: must iterate over a static keys() list because we'll be + # mutating the dict itself + remove_builtin = self.remove_builtin for key in self._orig_builtins.keys(): - self.remove_builtin(key) + remove_builtin(key) self._orig_builtins.clear() self._builtins_added = False try: diff --git a/IPython/testing/globalipapp.py b/IPython/testing/globalipapp.py index cafd9ab..1439ed7 100644 --- a/IPython/testing/globalipapp.py +++ b/IPython/testing/globalipapp.py @@ -144,7 +144,7 @@ def start_ipython(): # These traps are normally only active for interactive use, set them # permanently since we'll be mocking interactive sessions. - shell.builtin_trap.set() + shell.builtin_trap.activate() # Modify the IPython system call with one that uses getoutput, so that we # can capture subcommands and print them to Python's stdout, otherwise the