builtin_trap.py
86 lines
| 2.9 KiB
| text/x-python
|
PythonLexer
Brian Granger
|
r2227 | """ | ||
Thomas Kluyver
|
r23129 | A context manager for managing things injected into :mod:`builtins`. | ||
Brian Granger
|
r2227 | """ | ||
Thomas Kluyver
|
r23129 | # Copyright (c) IPython Development Team. | ||
# Distributed under the terms of the Modified BSD License. | ||||
import builtins as builtin_mod | ||||
Brian Granger
|
r2227 | |||
Min RK
|
r21253 | from traitlets.config.configurable import Configurable | ||
Brian Granger
|
r2227 | |||
Min RK
|
r21253 | from traitlets import Instance | ||
Brian Granger
|
r2229 | |||
Brian Granger
|
r2227 | |||
Fernando Perez
|
r2404 | class __BuiltinUndefined(object): pass | ||
BuiltinUndefined = __BuiltinUndefined() | ||||
Brian Granger
|
r2227 | |||
Erik Tollerud
|
r3185 | class __HideBuiltin(object): pass | ||
HideBuiltin = __HideBuiltin() | ||||
Brian Granger
|
r2227 | |||
Brian Granger
|
r2731 | class BuiltinTrap(Configurable): | ||
Brian Granger
|
r2227 | |||
Sylvain Corlay
|
r20940 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', | ||
allow_none=True) | ||||
Brian Granger
|
r2731 | |||
Brian Granger
|
r2740 | def __init__(self, shell=None): | ||
super(BuiltinTrap, self).__init__(shell=shell, config=None) | ||||
Brian Granger
|
r2244 | self._orig_builtins = {} | ||
Brian Granger
|
r2245 | # We define this to track if a single BuiltinTrap is nested. | ||
# Only turn off the trap when the outermost call to __exit__ is made. | ||||
self._nested_level = 0 | ||||
Brian Granger
|
r2731 | self.shell = shell | ||
Erik Tollerud
|
r3185 | # builtins we always add - if set to HideBuiltin, they will just | ||
# be removed instead of being replaced by something else | ||||
self.auto_builtins = {'exit': HideBuiltin, | ||||
'quit': HideBuiltin, | ||||
Fernando Perez
|
r2957 | 'get_ipython': self.shell.get_ipython, | ||
} | ||||
Brian Granger
|
r2227 | |||
def __enter__(self): | ||||
Brian Granger
|
r2245 | if self._nested_level == 0: | ||
Fernando Perez
|
r2957 | self.activate() | ||
Brian Granger
|
r2245 | self._nested_level += 1 | ||
Brian Granger
|
r2227 | # I return self, so callers can use add_builtin in a with clause. | ||
return self | ||||
def __exit__(self, type, value, traceback): | ||||
Brian Granger
|
r2245 | if self._nested_level == 1: | ||
Fernando Perez
|
r2957 | self.deactivate() | ||
Brian Granger
|
r2245 | self._nested_level -= 1 | ||
Brian Granger
|
r2281 | # Returning False will cause exceptions to propagate | ||
return False | ||||
Brian Granger
|
r2227 | |||
def add_builtin(self, key, value): | ||||
"""Add a builtin and save the original.""" | ||||
Thomas Kluyver
|
r13351 | bdict = builtin_mod.__dict__ | ||
Fernando Perez
|
r2957 | orig = bdict.get(key, BuiltinUndefined) | ||
Erik Tollerud
|
r3185 | if value is HideBuiltin: | ||
Erik Tollerud
|
r3191 | if orig is not BuiltinUndefined: #same as 'key in bdict' | ||
self._orig_builtins[key] = orig | ||||
del bdict[key] | ||||
Erik Tollerud
|
r3185 | else: | ||
Erik Tollerud
|
r3191 | self._orig_builtins[key] = orig | ||
Erik Tollerud
|
r3185 | bdict[key] = value | ||
Brian Granger
|
r2227 | |||
Fernando Perez
|
r5491 | def remove_builtin(self, key, orig): | ||
Brian Granger
|
r2227 | """Remove an added builtin and re-set the original.""" | ||
Fernando Perez
|
r5491 | if orig is BuiltinUndefined: | ||
Thomas Kluyver
|
r13351 | del builtin_mod.__dict__[key] | ||
Brian Granger
|
r2227 | else: | ||
Thomas Kluyver
|
r13351 | builtin_mod.__dict__[key] = orig | ||
Brian Granger
|
r2227 | |||
Fernando Perez
|
r2957 | def activate(self): | ||
Brian Granger
|
r2227 | """Store ipython references in the __builtin__ namespace.""" | ||
Fernando Perez
|
r2957 | add_builtin = self.add_builtin | ||
Srinivas Reddy Thatiparthy
|
r23036 | for name, func in self.auto_builtins.items(): | ||
Fernando Perez
|
r2957 | add_builtin(name, func) | ||
Brian Granger
|
r2227 | |||
Fernando Perez
|
r2957 | def deactivate(self): | ||
Brian Granger
|
r2227 | """Remove any builtins which might have been added by add_builtins, or | ||
restore overwritten ones to their previous values.""" | ||||
Fernando Perez
|
r2957 | remove_builtin = self.remove_builtin | ||
Srinivas Reddy Thatiparthy
|
r23036 | for key, val in self._orig_builtins.items(): | ||
Fernando Perez
|
r5491 | remove_builtin(key, val) | ||
Brian Granger
|
r2227 | self._orig_builtins.clear() | ||
self._builtins_added = False | ||||