diff --git a/IPython/core/fakemodule.py b/IPython/core/fakemodule.py
deleted file mode 100644
index 41029f5..0000000
--- a/IPython/core/fakemodule.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-Class which mimics a module.
-
-Needed to allow pickle to correctly resolve namespaces during IPython
-sessions.
-"""
-
-#*****************************************************************************
-#       Copyright (C) 2002-2004 Fernando Perez. <fperez@colorado.edu>
-#
-#  Distributed under the terms of the BSD License.  The full license is in
-#  the file COPYING, distributed as part of this software.
-#*****************************************************************************
-
-import types
-
-def init_fakemod_dict(fm,adict=None):
-    """Initialize a FakeModule instance __dict__.
-
-    Kept as a standalone function and not a method so the FakeModule API can
-    remain basically empty.
-
-    This should be considered for private IPython use, used in managing
-    namespaces for %run.
-
-    Parameters
-    ----------
-
-    fm : FakeModule instance
-
-    adict : dict, optional
-    """
-
-    dct = {}
-    # It seems pydoc (and perhaps others) needs any module instance to
-    # implement a __nonzero__ method, so we add it if missing:
-    dct.setdefault('__nonzero__',lambda : True)
-    dct.setdefault('__file__',__file__)
-
-    if adict is not None:
-        dct.update(adict)
-
-    # Hard assignment of the object's __dict__.  This is nasty but deliberate.
-    fm.__dict__.clear()
-    fm.__dict__.update(dct)
-
-
-class FakeModule(types.ModuleType):
-    """Simple class with attribute access to fake a module.
-
-    This is not meant to replace a module, but to allow inserting a fake
-    module in sys.modules so that systems which rely on run-time module
-    importing (like shelve and pickle) work correctly in interactive IPython
-    sessions.
-
-    Do NOT use this code for anything other than this IPython private hack."""
-
-    def __init__(self,adict=None):
-        
-        # tmp to force __dict__ instance creation, else self.__dict__ fails
-        self.__iptmp = None
-        # cleanup our temp trick
-        del self.__iptmp
-        # Now, initialize the actual data in the instance dict.
-        init_fakemod_dict(self,adict)
diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py
index 9aea028..5a9cc38 100644
--- a/IPython/core/interactiveshell.py
+++ b/IPython/core/interactiveshell.py
@@ -47,7 +47,6 @@ from IPython.core.displayhook import DisplayHook
 from IPython.core.displaypub import DisplayPublisher
 from IPython.core.error import UsageError
 from IPython.core.extensions import ExtensionManager
-from IPython.core.fakemodule import FakeModule, init_fakemod_dict
 from IPython.core.formatters import DisplayFormatter
 from IPython.core.history import HistoryManager
 from IPython.core.inputsplitter import IPythonInputSplitter, ESC_MAGIC, ESC_MAGIC2
@@ -826,15 +825,18 @@ class InteractiveShell(SingletonConfigurable):
     # Things related to the "main" module
     #-------------------------------------------------------------------------
 
-    def new_main_mod(self, filename):
+    def new_main_mod(self, filename, modname):
         """Return a new 'main' module object for user code execution.
         
         ``filename`` should be the path of the script which will be run in the
         module. Requests with the same filename will get the same module, with
         its namespace cleared.
         
+        ``modname`` should be the module name - normally either '__main__' or
+        the basename of the file without the extension.
+        
         When scripts are executed via %run, we must keep a reference to their
-        __main__ module (a FakeModule instance) around so that Python doesn't
+        __main__ module around so that Python doesn't
         clear it, rendering references to module globals useless.
 
         This method keeps said reference in a private dict, keyed by the
@@ -847,9 +849,16 @@ class InteractiveShell(SingletonConfigurable):
         try:
             main_mod = self._main_mod_cache[filename]
         except KeyError:
-            main_mod = self._main_mod_cache[filename] = FakeModule()
+            main_mod = self._main_mod_cache[filename] = types.ModuleType(modname,
+                        doc="Module created for script run in IPython")
         else:
-            init_fakemod_dict(main_mod)
+            main_mod.__dict__.clear()
+            main_mod.__name__ = modname
+        
+        main_mod.__file__ = filename
+        # It seems pydoc (and perhaps others) needs any module instance to
+        # implement a __nonzero__ method
+        main_mod.__nonzero__ = lambda : True
         
         return main_mod
 
@@ -863,7 +872,7 @@ class InteractiveShell(SingletonConfigurable):
 
         In [15]: import IPython
 
-        In [16]: m = _ip.new_main_mod(IPython.__file__)
+        In [16]: m = _ip.new_main_mod(IPython.__file__, 'IPython')
 
         In [17]: len(_ip._main_mod_cache) > 0
         Out[17]: True
diff --git a/IPython/core/magics/execution.py b/IPython/core/magics/execution.py
index e01c978..28a6c69 100644
--- a/IPython/core/magics/execution.py
+++ b/IPython/core/magics/execution.py
@@ -550,6 +550,11 @@ python-profiler package from non-free.""")
             __name__save = self.shell.user_ns['__name__']
             prog_ns['__name__'] = '__main__'
             main_mod = self.shell.user_module
+            
+            # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
+            # set the __file__ global in the script's namespace
+            # TK: Is this necessary in interactive mode?
+            prog_ns['__file__'] = filename
         else:
             # Run in a fresh, empty namespace
             if 'n' in opts:
@@ -560,13 +565,8 @@ python-profiler package from non-free.""")
             # The shell MUST hold a reference to prog_ns so after %run
             # exits, the python deletion mechanism doesn't zero it out
             # (leaving dangling references). See interactiveshell for details
-            main_mod = self.shell.new_main_mod(filename)
+            main_mod = self.shell.new_main_mod(filename, name)
             prog_ns = main_mod.__dict__
-            prog_ns['__name__'] = name
-
-        # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
-        # set the __file__ global in the script's namespace
-        prog_ns['__file__'] = filename
 
         # pickle fix.  See interactiveshell for an explanation.  But we need to
         # make sure that, if we overwrite __main__, we replace it at the end
diff --git a/IPython/core/tests/test_fakemodule.py b/IPython/core/tests/test_fakemodule.py
deleted file mode 100644
index d12bd5d..0000000
--- a/IPython/core/tests/test_fakemodule.py
+++ /dev/null
@@ -1,17 +0,0 @@
-"""Tests for the FakeModule objects.
-"""
-
-import nose.tools as nt
-
-from IPython.core.fakemodule import FakeModule
-
-# Make a fakemod and check a few properties
-def test_mk_fakemod():
-    fm = FakeModule()
-    yield nt.assert_true,fm
-    yield nt.assert_true,lambda : hasattr(fm,'__file__')
-
-def test_mk_fakemod_fromdict():
-    """Test making a FakeModule object with initial data"""
-    fm = FakeModule(dict(hello=True))
-    nt.assert_true(fm.hello)
diff --git a/IPython/core/tests/test_imports.py b/IPython/core/tests/test_imports.py
index 04d83f4..88caef0 100644
--- a/IPython/core/tests/test_imports.py
+++ b/IPython/core/tests/test_imports.py
@@ -9,9 +9,6 @@ def test_import_crashhandler():
 def test_import_debugger():
     from IPython.core import debugger
 
-def test_import_fakemodule():
-    from IPython.core import fakemodule
-
 def test_import_excolors():
     from IPython.core import excolors
 
diff --git a/IPython/core/tests/test_run.py b/IPython/core/tests/test_run.py
index 9ec10f2..9183d96 100644
--- a/IPython/core/tests/test_run.py
+++ b/IPython/core/tests/test_run.py
@@ -15,6 +15,7 @@ from __future__ import absolute_import
 
 import functools
 import os
+from os.path import join as pjoin
 import random
 import sys
 import tempfile
@@ -359,6 +360,17 @@ tclass.py: deleting object: C-third
         self.mktmp(src)
         _ip.magic('run -t -N 1 %s' % self.fname)
         _ip.magic('run -t -N 10 %s' % self.fname)
+    
+    def test_ignore_sys_exit(self):
+        """Test the -e option to ignore sys.exit()"""
+        src = "import sys; sys.exit(1)"
+        self.mktmp(src)
+        with tt.AssertPrints('SystemExit'):
+            _ip.magic('run %s' % self.fname)
+        
+        with tt.AssertNotPrints('SystemExit'):
+            _ip.magic('run -e %s' % self.fname)
+        
 
 
 class TestMagicRunWithPackage(unittest.TestCase):
@@ -398,6 +410,7 @@ class TestMagicRunWithPackage(unittest.TestCase):
         self.tempdir.cleanup()
 
     def check_run_submodule(self, submodule, opts=''):
+        _ip.user_ns.pop('x', None)
         _ip.magic('run {2} -m {0}.{1}'.format(self.package, submodule, opts))
         self.assertEqual(_ip.user_ns['x'], self.value,
                          'Variable `x` is not loaded from module `{0}`.'
@@ -430,3 +443,16 @@ class TestMagicRunWithPackage(unittest.TestCase):
     @with_fake_debugger
     def test_debug_run_submodule_with_relative_import(self):
         self.check_run_submodule('relative', '-d')
+
+def test_run__name__():
+    with TemporaryDirectory() as td:
+        path = pjoin(td, 'foo.py')
+        with open(path, 'w') as f:
+            f.write("q = __name__")
+        
+        _ip.user_ns.pop('q', None)
+        _ip.magic('run {}'.format(path))
+        nt.assert_equal(_ip.user_ns.pop('q'), '__main__')
+        
+        _ip.magic('run -n {}'.format(path))
+        nt.assert_equal(_ip.user_ns.pop('q'), 'foo')
diff --git a/IPython/extensions/storemagic.py b/IPython/extensions/storemagic.py
index 4323b66..b4c698f 100644
--- a/IPython/extensions/storemagic.py
+++ b/IPython/extensions/storemagic.py
@@ -27,7 +27,6 @@ import inspect, os, sys, textwrap
 # Our own
 from IPython.config.configurable import Configurable
 from IPython.core.error import UsageError
-from IPython.core.fakemodule import FakeModule
 from IPython.core.magic import Magics, magics_class, line_magic
 from IPython.testing.skipdoctest import skip_doctest
 from IPython.utils.traitlets import Bool
@@ -224,7 +223,8 @@ class StoreMagics(Magics, Configurable):
                     raise UsageError("Unknown variable '%s'" % args[0])
 
             else:
-                if isinstance(inspect.getmodule(obj), FakeModule):
+                modname = getattr(inspect.getmodule(obj), '__name__', '')
+                if modname == '__main__':
                     print textwrap.dedent("""\
                     Warning:%s is %s
                     Proper storage of interactively declared classes (or instances
diff --git a/docs/autogen_api.py b/docs/autogen_api.py
index 74f841d..b0d831e 100755
--- a/docs/autogen_api.py
+++ b/docs/autogen_api.py
@@ -35,7 +35,7 @@ if __name__ == '__main__':
                                         r'\.zmq',
                                         ]
 
-    docwriter.module_skip_patterns += [ r'\.core\.fakemodule',
+    docwriter.module_skip_patterns += [
                                         r'\.testing\.iptest',
                                         # Keeping these disabled is OK
                                         r'\.parallel\.controller\.mongodb',
diff --git a/docs/source/whatsnew/pr/incompat-drop-fakemodule.rst b/docs/source/whatsnew/pr/incompat-drop-fakemodule.rst
new file mode 100644
index 0000000..65bfa11
--- /dev/null
+++ b/docs/source/whatsnew/pr/incompat-drop-fakemodule.rst
@@ -0,0 +1 @@
+* The module ``IPython.core.fakemodule`` has been removed.