diff --git a/Lib/runpy.py b/Lib/runpy.py
new file mode 100755
index 0000000..afb0098
--- /dev/null
+++ b/Lib/runpy.py
@@ -0,0 +1,431 @@
+"""runpy.py - locating and running Python code using the module namespace
+
+Provides support for locating and running Python scripts using the Python
+module namespace instead of the native filesystem.
+
+This allows Python code to play nicely with non-filesystem based PEP 302
+importers when locating support scripts as well as when importing modules.
+"""
+# Written by Nick Coghlan <ncoghlan at gmail.com>
+#    to implement PEP 338 (Executing Modules as Scripts)
+
+import sys
+import imp
+
+__all__ = [
+    "run_module",
+]
+
+try:
+    _get_loader = imp.get_loader
+except AttributeError:
+    # get_loader() is not provided by the imp module, so emulate it
+    # as best we can using the PEP 302 import machinery exposed since
+    # Python 2.3. The emulation isn't perfect, but the differences
+    # in the way names are shadowed shouldn't matter in practice.
+    import os.path
+    import marshal                           # Handle compiled Python files
+
+    # This helper is needed in order for the PEP 302 emulation to
+    # correctly handle compiled files
+    def _read_compiled_file(compiled_file):
+        magic = compiled_file.read(4)
+        if magic != imp.get_magic():
+            return None
+        try:
+            compiled_file.read(4) # Skip timestamp
+            return marshal.load(compiled_file)
+        except Exception:
+            return None
+
+    class _AbsoluteImporter(object):
+        """PEP 302 importer wrapper for top level import machinery"""
+        def find_module(self, mod_name, path=None):
+            if path is not None:
+                return None
+            try:
+                file, filename, mod_info = imp.find_module(mod_name)
+            except ImportError:
+                return None
+            suffix, mode, mod_type = mod_info
+            if mod_type == imp.PY_SOURCE:
+                loader = _SourceFileLoader(mod_name, file,
+                                           filename, mod_info)
+            elif mod_type == imp.PY_COMPILED:
+                loader = _CompiledFileLoader(mod_name, file,
+                                             filename, mod_info)
+            elif mod_type == imp.PKG_DIRECTORY:
+                loader = _PackageDirLoader(mod_name, file,
+                                           filename, mod_info)
+            elif mod_type == imp.C_EXTENSION:
+                loader = _FileSystemLoader(mod_name, file,
+                                           filename, mod_info)
+            else:
+                loader = _BasicLoader(mod_name, file,
+                                      filename, mod_info)
+            return loader
+
+
+    class _FileSystemImporter(object):
+        """PEP 302 importer wrapper for filesystem based imports"""
+        def __init__(self, path_item=None):
+            if path_item is not None:
+                if path_item != '' and not os.path.isdir(path_item):
+                    raise ImportError("%s is not a directory" % path_item)
+                self.path_dir = path_item
+            else:
+                raise ImportError("Filesystem importer requires "
+                                  "a directory name")
+
+        def find_module(self, mod_name, path=None):
+            if path is not None:
+                return None
+            path_dir = self.path_dir
+            if path_dir == '':
+                path_dir = os.getcwd()
+            sub_name = mod_name.rsplit(".", 1)[-1]
+            try:
+                file, filename, mod_info = imp.find_module(sub_name,
+                                                           [path_dir])
+            except ImportError:
+                return None
+            if not filename.startswith(path_dir):
+                return None
+            suffix, mode, mod_type = mod_info
+            if mod_type == imp.PY_SOURCE:
+                loader = _SourceFileLoader(mod_name, file,
+                                           filename, mod_info)
+            elif mod_type == imp.PY_COMPILED:
+                loader = _CompiledFileLoader(mod_name, file,
+                                             filename, mod_info)
+            elif mod_type == imp.PKG_DIRECTORY:
+                loader = _PackageDirLoader(mod_name, file,
+                                           filename, mod_info)
+            elif mod_type == imp.C_EXTENSION:
+                loader = _FileSystemLoader(mod_name, file,
+                                           filename, mod_info)
+            else:
+                loader = _BasicLoader(mod_name, file,
+                                      filename, mod_info)
+            return loader
+
+
+    class _BasicLoader(object):
+        """PEP 302 loader wrapper for top level import machinery"""
+        def __init__(self, mod_name, file, filename, mod_info):
+            self.mod_name = mod_name
+            self.file = file
+            self.filename = filename
+            self.mod_info = mod_info
+
+        def _fix_name(self, mod_name):
+            if mod_name is None:
+                mod_name = self.mod_name
+            elif mod_name != self.mod_name:
+                raise ImportError("Loader for module %s cannot handle "
+                                  "module %s" % (self.mod_name, mod_name))
+            return mod_name
+
+        def load_module(self, mod_name=None):
+            mod_name = self._fix_name(mod_name)
+            mod = imp.load_module(mod_name, self.file,
+                                  self.filename, self.mod_info)
+            mod.__loader__ = self  # for introspection
+            return mod
+
+        def get_code(self, mod_name=None):
+            return None
+
+        def get_source(self, mod_name=None):
+            return None
+
+        def is_package(self, mod_name=None):
+            return False
+
+        def close(self):
+            if self.file:
+                self.file.close()
+
+        def __del__(self):
+            self.close()
+
+
+    class _FileSystemLoader(_BasicLoader):
+        """PEP 302 loader wrapper for filesystem based imports"""
+        def get_code(self, mod_name=None):
+            mod_name = self._fix_name(mod_name)
+            return self._get_code(mod_name)
+
+        def get_data(self, pathname):
+            return open(pathname, "rb").read()
+
+        def get_filename(self, mod_name=None):
+            mod_name = self._fix_name(mod_name)
+            return self._get_filename(mod_name)
+
+        def get_source(self, mod_name=None):
+            mod_name = self._fix_name(mod_name)
+            return self._get_source(mod_name)
+
+        def is_package(self, mod_name=None):
+            mod_name = self._fix_name(mod_name)
+            return self._is_package(mod_name)
+
+        def _get_code(self, mod_name):
+            return None
+
+        def _get_filename(self, mod_name):
+            return self.filename
+
+        def _get_source(self, mod_name):
+            return None
+
+        def _is_package(self, mod_name):
+            return False
+
+    class _PackageDirLoader(_FileSystemLoader):
+        """PEP 302 loader wrapper for PKG_DIRECTORY directories"""
+        def _is_package(self, mod_name):
+            return True
+
+
+    class _SourceFileLoader(_FileSystemLoader):
+        """PEP 302 loader wrapper for PY_SOURCE modules"""
+        def _get_code(self, mod_name):
+            return compile(self._get_source(mod_name),
+                           self.filename, 'exec')
+
+        def _get_source(self, mod_name):
+            f = self.file
+            f.seek(0)
+            return f.read()
+
+
+    class _CompiledFileLoader(_FileSystemLoader):
+        """PEP 302 loader wrapper for PY_COMPILED modules"""
+        def _get_code(self, mod_name):
+            f = self.file
+            f.seek(0)
+            return _read_compiled_file(f)
+
+
+    def _get_importer(path_item):
+        """Retrieve a PEP 302 importer for the given path item
+
+        The returned importer is cached in sys.path_importer_cache
+        if it was newly created by a path hook.
+
+        If there is no importer, a wrapper around the basic import
+        machinery is returned. This wrapper is never inserted into
+        the importer cache (None is inserted instead).
+
+        The cache (or part of it) can be cleared manually if a
+        rescan of sys.path_hooks is necessary.
+        """
+        try:
+            importer = sys.path_importer_cache[path_item]
+        except KeyError:
+            for path_hook in sys.path_hooks:
+                try:
+                    importer = path_hook(path_item)
+                    break
+                except ImportError:
+                    pass
+            else:
+                importer = None
+            sys.path_importer_cache[path_item] = importer
+        if importer is None:
+            try:
+                importer = _FileSystemImporter(path_item)
+            except ImportError:
+                pass
+        return importer
+
+
+    def _get_path_loader(mod_name, path=None):
+        """Retrieve a PEP 302 loader using a path importer"""
+        if path is None:
+            path = sys.path
+            absolute_loader = _AbsoluteImporter().find_module(mod_name)
+            if isinstance(absolute_loader, _FileSystemLoader):
+                # Found in filesystem, so scan path hooks
+                # before accepting this one as the right one
+                loader = None
+            else:
+                # Not found in filesystem, so use top-level loader
+                loader = absolute_loader
+        else:
+            loader = absolute_loader = None
+        if loader is None:
+            for path_item in path:
+                importer = _get_importer(path_item)
+                if importer is not None:
+                    loader = importer.find_module(mod_name)
+                    if loader is not None:
+                        # Found a loader for our module
+                        break
+            else:
+                # No path hook found, so accept the top level loader
+                loader = absolute_loader
+        return loader
+
+    def _get_package(pkg_name):
+        """Retrieve a named package"""
+        pkg = __import__(pkg_name)
+        sub_pkg_names = pkg_name.split(".")
+        for sub_pkg in sub_pkg_names[1:]:
+            pkg = getattr(pkg, sub_pkg)
+        return pkg
+
+    def _get_loader(mod_name, path=None):
+        """Retrieve a PEP 302 loader for the given module or package
+
+        If the module or package is accessible via the normal import
+        mechanism, a wrapper around the relevant part of that machinery
+        is returned.
+
+        Non PEP 302 mechanisms (e.g. the Windows registry) used by the
+        standard import machinery to find files in alternative locations
+        are partially supported, but are searched AFTER sys.path. Normally,
+        these locations are searched BEFORE sys.path, preventing sys.path
+        entries from shadowing them.
+        For this to cause a visible difference in behaviour, there must
+        be a module or package name that is accessible via both sys.path
+        and one of the non PEP 302 file system mechanisms. In this case,
+        the emulation will find the former version, while the builtin
+        import mechanism will find the latter.
+        Items of the following types can be affected by this discrepancy:
+            imp.C_EXTENSION
+            imp.PY_SOURCE
+            imp.PY_COMPILED
+            imp.PKG_DIRECTORY
+        """
+        try:
+            loader = sys.modules[mod_name].__loader__
+        except (KeyError, AttributeError):
+            loader = None
+        if loader is None:
+            imp.acquire_lock()
+            try:
+                # Module not in sys.modules, or uses an unhooked loader
+                parts = mod_name.rsplit(".", 1)
+                if len(parts) == 2:
+                    # Sub package, so use parent package's path
+                    pkg_name, sub_name = parts
+                    if pkg_name and pkg_name[0] != '.':
+                        if path is not None:
+                            raise ImportError("Path argument must be None "
+                                            "for a dotted module name")
+                        pkg = _get_package(pkg_name)
+                        try:
+                            path = pkg.__path__
+                        except AttributeError:
+                            raise ImportError(pkg_name +
+                                            " is not a package")
+                    else:
+                        raise ImportError("Relative import syntax is not "
+                                          "supported by _get_loader()")
+                else:
+                    # Top level module, so stick with default path
+                    sub_name = mod_name
+
+                for importer in sys.meta_path:
+                    loader = importer.find_module(mod_name, path)
+                    if loader is not None:
+                        # Found a metahook to handle the module
+                        break
+                else:
+                    # Handling via the standard path mechanism
+                    loader = _get_path_loader(mod_name, path)
+            finally:
+                imp.release_lock()
+        return loader
+
+
+# This helper is needed due to a missing component in the PEP 302
+# loader protocol (specifically, "get_filename" is non-standard)
+def _get_filename(loader, mod_name):
+    try:
+        get_filename = loader.get_filename
+    except AttributeError:
+        return None
+    else:
+        return get_filename(mod_name)
+
+# ------------------------------------------------------------
+# Done with the import machinery emulation, on with the code!
+
+def _run_code(code, run_globals, init_globals,
+              mod_name, mod_fname, mod_loader):
+    """Helper for _run_module_code"""
+    if init_globals is not None:
+        run_globals.update(init_globals)
+    run_globals.update(__name__ = mod_name,
+                       __file__ = mod_fname,
+                       __loader__ = mod_loader)
+    exec code in run_globals
+    return run_globals
+
+def _run_module_code(code, init_globals=None,
+                    mod_name=None, mod_fname=None,
+                    mod_loader=None, alter_sys=False):
+    """Helper for run_module"""
+    # Set up the top level namespace dictionary
+    if alter_sys:
+        # Modify sys.argv[0] and sys.module[mod_name]
+        temp_module = imp.new_module(mod_name)
+        mod_globals = temp_module.__dict__
+        saved_argv0 = sys.argv[0]
+        restore_module = mod_name in sys.modules
+        if restore_module:
+            saved_module = sys.modules[mod_name]
+        imp.acquire_lock()
+        try:
+            sys.argv[0] = mod_fname
+            sys.modules[mod_name] = temp_module
+            try:
+                _run_code(code, mod_globals, init_globals,
+                          mod_name, mod_fname, mod_loader)
+            finally:
+                sys.argv[0] = saved_argv0
+                if restore_module:
+                    sys.modules[mod_name] = saved_module
+                else:
+                    del sys.modules[mod_name]
+        finally:
+            imp.release_lock()
+        # Copy the globals of the temporary module, as they
+        # may be cleared when the temporary module goes away
+        return mod_globals.copy()
+    else:
+        # Leave the sys module alone
+        return _run_code(code, {}, init_globals,
+                         mod_name, mod_fname, mod_loader)
+
+
+def run_module(mod_name, init_globals=None,
+                         run_name=None, alter_sys=False):
+    """Execute a module's code without importing it
+
+       Returns the resulting top level namespace dictionary
+    """
+    loader = _get_loader(mod_name)
+    if loader is None:
+        raise ImportError("No module named " + mod_name)
+    code = loader.get_code(mod_name)
+    if code is None:
+        raise ImportError("No code object available for " + mod_name)
+    filename = _get_filename(loader, mod_name)
+    if run_name is None:
+        run_name = mod_name
+    return _run_module_code(code, init_globals, run_name,
+                            filename, loader, alter_sys)
+
+
+if __name__ == "__main__":
+    # Run the module specified as the next command line argument
+    if len(sys.argv) < 2:
+        print >> sys.stderr, "No module specified for execution"
+    else:
+        del sys.argv[0] # Make the requested module sys.argv[0]
+        run_module(sys.argv[0], run_name="__main__", alter_sys=True)
