can you recover from reassigning __builtins__ in python?
Question: If I open up interactive mode and type:

    
    
    __builtins__ = 0 # breaks everything
    

have I completely broken the session? If so, what is going on behind the
scenes to assign __builtins__ to the builtin module that can't be handled by
the interpreter? If not, how can I recover from this?

Just a few of my own attempts to fix it:

  * Any attempt to import anything results in an error "ImportError __import__ not found"
  * all functions I might use to do anything other than evaluate numerical expressions are broken
  * There is another variable __package__ still accessible, but I don't know if/how it can be used.


Answer: You can usually get access to anything you need, even when `__builtins__` has
been removed. It's just a matter of digging far enough. For example:

    
    
    Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> __builtins__ = 0
    >>> open
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'open' is not defined
    >>> dir
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'dir' is not defined
    >>> int
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'int' is not defined
    >>> float
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'float' is not defined
    >>>
    >>> __builtins__ = [t for t in ().__class__.__bases__[0].__subclasses__() if 'warning' in t.__name__][0]()._module.__builtins__
    >>>
    >>> open
    <built-in function open>
    >>> int
    <type 'int'>
    >>> float
    <type 'float'>
    >>>
    

For an explanation of what the heck just happened here, read [Eval really is
dangerous](http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html),
where similar techniques are used to demonstrate that you cannot safely
execute untrusted Python code.

