[pypy-svn] r70053 - in pypy/branch/import-builtin/pypy: interpreter module/__builtin__ module/__builtin__/test module/__pypy__ module/imp module/imp/test

afa at codespeak.net afa at codespeak.net
Thu Dec 10 18:05:45 CET 2009


Author: afa
Date: Thu Dec 10 18:05:42 2009
New Revision: 70053

Added:
   pypy/branch/import-builtin/pypy/module/imp/   (props changed)
   pypy/branch/import-builtin/pypy/module/imp/__init__.py   (contents, props changed)
   pypy/branch/import-builtin/pypy/module/imp/importing.py
      - copied, changed from r70029, pypy/branch/import-builtin/pypy/module/__builtin__/importing.py
   pypy/branch/import-builtin/pypy/module/imp/test/   (props changed)
   pypy/branch/import-builtin/pypy/module/imp/test/test_import.py
      - copied, changed from r70029, pypy/branch/import-builtin/pypy/module/__builtin__/test/test_import.py
Removed:
   pypy/branch/import-builtin/pypy/module/__builtin__/app_misc.py
   pypy/branch/import-builtin/pypy/module/__builtin__/importing.py
   pypy/branch/import-builtin/pypy/module/__builtin__/test/test_import.py
Modified:
   pypy/branch/import-builtin/pypy/interpreter/baseobjspace.py
   pypy/branch/import-builtin/pypy/module/__builtin__/__init__.py
   pypy/branch/import-builtin/pypy/module/__pypy__/__init__.py
Log:
A large rewrite of the import mechanisms,
this ensures that different hooks are processed in the correct order,
and the imp module correctly handles builtin modules.


Modified: pypy/branch/import-builtin/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/import-builtin/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/branch/import-builtin/pypy/interpreter/baseobjspace.py	Thu Dec 10 18:05:42 2009
@@ -421,16 +421,18 @@
         "NOT_RPYTHON: only for initializing the space."
 
         from pypy.module.exceptions import Module
-        w_name_exceptions = self.wrap('exceptions')
-        self.exceptions_module = Module(self, w_name_exceptions)
+        w_name = self.wrap('exceptions')
+        self.exceptions_module = Module(self, w_name)
+        self.builtin_modules['exceptions'] = self.wrap(self.exceptions_module)
 
         from pypy.module.sys import Module
         w_name = self.wrap('sys')
         self.sys = Module(self, w_name)
-        w_modules = self.sys.get('modules')
         self.builtin_modules['sys'] = self.wrap(self.sys)
 
-        self.builtin_modules['exceptions'] = self.wrap(self.exceptions_module)
+        from pypy.module.imp import Module
+        w_name = self.wrap('imp')
+        self.builtin_modules['imp'] = self.wrap(Module(self, w_name))
 
         from pypy.module.__builtin__ import Module
         w_name = self.wrap('__builtin__')
@@ -439,7 +441,7 @@
         self.builtin_modules['__builtin__'] = self.wrap(w_builtin)
         self.setitem(self.builtin.w_dict, self.wrap('__builtins__'), w_builtin)
 
-        bootstrap_modules = ['sys', '__builtin__', 'exceptions']
+        bootstrap_modules = ['sys', 'imp', '__builtin__', 'exceptions']
         installed_builtin_modules = bootstrap_modules[:]
 
         self.export_builtin_exceptions()
@@ -511,6 +513,7 @@
     def setup_builtin_modules(self):
         "NOT_RPYTHON: only for initializing the space."
         self.getbuiltinmodule('sys')
+        self.getbuiltinmodule('imp')
         self.getbuiltinmodule('__builtin__')
         for mod in self.builtin_modules.values():
             mod.setup_after_space_initialization()

Modified: pypy/branch/import-builtin/pypy/module/__builtin__/__init__.py
==============================================================================
--- pypy/branch/import-builtin/pypy/module/__builtin__/__init__.py	(original)
+++ pypy/branch/import-builtin/pypy/module/__builtin__/__init__.py	Thu Dec 10 18:05:42 2009
@@ -1,6 +1,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter import module
 from pypy.interpreter.mixedmodule import MixedModule
+import pypy.module.imp.importing
 
 # put builtins here that should be optimized somehow
 
@@ -35,9 +36,6 @@
         'vars'          : 'app_inspect.vars',
         'dir'           : 'app_inspect.dir',
 
-        '_find_module'  : 'app_misc.find_module',
-        'reload'        : 'app_misc.reload',
-
         '__filestub'    : 'app_file_stub.file',
     }
 
@@ -88,7 +86,8 @@
         'compile'       : 'compiling.compile',
         'eval'          : 'compiling.eval',
 
-        '__import__'    : 'importing.importhook',
+        '__import__'    : 'pypy.module.imp.importing.importhook',
+        'reload'        : 'pypy.module.imp.importing.reload',
 
         'range'         : 'functional.range_int',
         'xrange'        : 'functional.W_XRange',

Modified: pypy/branch/import-builtin/pypy/module/__pypy__/__init__.py
==============================================================================
--- pypy/branch/import-builtin/pypy/module/__pypy__/__init__.py	(original)
+++ pypy/branch/import-builtin/pypy/module/__pypy__/__init__.py	Thu Dec 10 18:05:42 2009
@@ -1,7 +1,7 @@
 
 # Package initialisation
 from pypy.interpreter.mixedmodule import MixedModule
-from pypy.module.__builtin__.importing import get_pyc_magic
+from pypy.module.imp.importing import get_pyc_magic
 
 class Module(MixedModule):
     appleveldefs = {

Added: pypy/branch/import-builtin/pypy/module/imp/__init__.py
==============================================================================
--- (empty file)
+++ pypy/branch/import-builtin/pypy/module/imp/__init__.py	Thu Dec 10 18:05:42 2009
@@ -0,0 +1,179 @@
+from pypy.interpreter.mixedmodule import MixedModule
+
+names = ['C_BUILTIN', 'C_EXTENSION', 'IMP_HOOK', 'NullImporter', 'PKG_DIRECTORY',
+ 'PY_CODERESOURCE', 'PY_COMPILED', 'PY_FROZEN', 'PY_RESOURCE', 'PY_SOURCE',
+ 'SEARCH_ERROR', '__doc__', '__name__', '__package__', 'acquire_lock', 'find_module',
+ 'get_frozen_object', 'get_magic', 'get_suffixes', 'init_builtin', 'init_frozen',
+ 'is_builtin', 'is_frozen', 'load_compiled', 'load_dynamic', 'load_module',
+ 'load_package', 'load_source', 'lock_held', 'new_module', 'release_lock', 'reload']
+
+
+class Module(MixedModule):
+    """
+    This module provides the components needed to build your own
+    __import__ function.
+    """
+    interpleveldefs = {
+        'PY_SOURCE':       'space.wrap(importing.PY_SOURCE)',
+        'PY_COMPILED':     'space.wrap(importing.PY_COMPILED)',
+        'PKG_DIRECTORY':   'space.wrap(importing.PKG_DIRECTORY)',
+        'C_BUILTIN':       'space.wrap(importing.C_BUILTIN)',
+
+        'get_magic':       'interp_imp.get_magic',
+        'find_module':     'interp_imp.find_module',
+        'load_module':     'interp_imp.load_module',
+        'new_module':      'interp_imp.new_module',
+        # XXX CPython testing hack: delegate to the real imp.get_magic
+        # get_magic = __import__('imp').get_magic
+        }
+
+    appleveldefs = {
+        }
+
+# PyPy-specific interface
+try:
+    import __pypy__
+    def get_magic():
+        """Return the magic number for .pyc or .pyo files."""
+        import struct
+        return struct.pack('<i', __pypy__.PYC_MAGIC)
+except ImportError:
+    # XXX CPython testing hack: delegate to the real imp.get_magic
+    get_magic = __import__('imp').get_magic
+
+def get_suffixes():
+    """Return a list of (suffix, mode, type) tuples describing the files
+    that find_module() looks for."""
+    return [('.py', 'U', PY_SOURCE),
+            ('.pyc', 'rb', PY_COMPILED)]
+
+
+def find_module(name, path=None):
+    """find_module(name, [path]) -> (file, filename, (suffix, mode, type))
+    Search for a module.  If path is omitted or None, search for a
+    built-in, frozen or special module and continue search in sys.path.
+    The module name cannot contain '.'; to search for a submodule of a
+    package, pass the submodule name and the package's __path__.
+    """
+    if path is None:
+        if name in sys.builtin_module_names:
+            return (None, name, ('', '', C_BUILTIN))
+        path = sys.path
+    for base in path:
+        filename = os.path.join(base, name)
+        if os.path.isdir(filename):
+            return (None, filename, ('', '', PKG_DIRECTORY))
+        for ext, mode, kind in get_suffixes():
+            if os.path.exists(filename+ext):
+                return (file(filename+ext, mode), filename+ext, (ext, mode, kind))
+    raise ImportError, 'No module named %s' % (name,)
+
+
+def load_module(name, file, filename, description):
+    """Load a module, given information returned by find_module().
+    The module name must include the full package name, if any.
+    """
+    suffix, mode, type = description
+
+    if type == PY_SOURCE:
+        return load_source(name, filename, file)
+
+    if type == PKG_DIRECTORY:
+        initfilename = os.path.join(filename, '__init__.py')
+        module = sys.modules.setdefault(name, new_module(name))
+        module.__name__ = name
+        module.__doc__ = None
+        module.__file__ = initfilename
+        module.__path__ = [filename]
+        execfile(initfilename, module.__dict__)
+        return module
+
+    if type == C_BUILTIN:
+        module = __import__(name, {}, {}, None)
+        return module
+    if type == PY_COMPILED:
+       return  load_compiled(name, filename, file)
+    raise ValueError, 'invalid description argument: %r' % (description,)
+
+def load_dynamic(name, *args, **kwds):
+    raise ImportError(name)
+
+def load_source(name, pathname, file=None):
+    autoopen = file is None
+    if autoopen:
+        file = open(pathname, 'U')
+    source = file.read()
+    if autoopen:
+        file.close()
+    co = compile(source, pathname, 'exec')
+    return run_module(name, pathname, co)
+
+def load_compiled(name, pathname, file=None):
+    import marshal
+    autoopen = file is None
+    if autoopen:
+        file = open(pathname, 'rb')
+    magic = file.read(4)
+    if magic != get_magic():
+        raise ImportError("Bad magic number in %s" % pathname)
+    file.read(4)    # skip timestamp
+    co = marshal.load(file)
+    if autoopen:
+        file.close()
+    return run_module(name, pathname, co)
+
+def run_module(name, pathname, co):
+    module = sys.modules.setdefault(name, new_module(name))
+    module.__name__ = name
+    module.__doc__ = None
+    module.__file__ = pathname
+    try:
+        exec co in module.__dict__
+    except :
+        sys.modules.pop(name,None)
+        raise
+    return module
+ 
+
+def new_module(name):
+    """Create a new module.  Do not enter it in sys.modules.
+    The module name must include the full package name, if any.
+    """
+    return new.module(name)
+
+
+def init_builtin(name):
+    if name not in sys.builtin_module_names:
+        return None
+    if name in sys.modules:
+        raise ImportError("cannot initialize a built-in module twice "
+                          "in PyPy")
+    return __import__(name)
+
+def init_frozen(name):
+    return None
+
+def is_builtin(name):
+    if name in sys.builtin_module_names:
+        return -1   # cannot be initialized again
+    else:
+        return 0
+
+def is_frozen(name):
+    return False
+
+# ____________________________________________________________
+
+try:
+    # PyPy-specific interface
+    from thread import _importlock_held    as lock_held
+    from thread import _importlock_acquire as acquire_lock
+    from thread import _importlock_release as release_lock
+except ImportError:
+    def lock_held():
+        """On platforms without threads, return False."""
+        return False
+    def acquire_lock():
+        """On platforms without threads, this function does nothing."""
+    def release_lock():
+        """On platforms without threads, this function does nothing."""

Copied: pypy/branch/import-builtin/pypy/module/imp/importing.py (from r70029, pypy/branch/import-builtin/pypy/module/__builtin__/importing.py)
==============================================================================
--- pypy/branch/import-builtin/pypy/module/__builtin__/importing.py	(original)
+++ pypy/branch/import-builtin/pypy/module/imp/importing.py	Thu Dec 10 18:05:42 2009
@@ -14,14 +14,16 @@
 from pypy.rlib.rarithmetic import intmask
 from pypy.rlib.objectmodel import we_are_translated
 
-NOFILE = 0
-PYFILE = 1
-PYCFILE = 2
+SEARCH_ERROR = 0
+PY_SOURCE = 1
+PY_COMPILED = 2
+PKG_DIRECTORY = 3
+C_BUILTIN = 4
 
 def find_modtype(space, filepart):
     """Check which kind of module to import for the given filepart,
-    which is a path without extension.  Returns PYFILE, PYCFILE or
-    NOFILE.
+    which is a path without extension.  Returns PY_SOURCE, PY_COMPILED or
+    SEARCH_ERROR.
     """
     # check the .py file
     pyfile = filepart + ".py"
@@ -33,22 +35,23 @@
         # is False: if a .py file does not exist, we don't even try to
         # look for a lone .pyc file.
         if not space.config.objspace.lonepycfiles:
-            return NOFILE
+            return SEARCH_ERROR, None, None
         pyfile_ts = 0
         pyfile_exists = False
 
     # check the .pyc file
     if space.config.objspace.usepycfiles:
-        pycfile = filepart + ".pyc"    
+        pycfile = filepart + ".pyc"
         if case_ok(pycfile):
             if check_compiled_module(space, pycfile, pyfile_ts):
-                return PYCFILE     # existing and up-to-date .pyc file
+                # existing and up-to-date .pyc file
+                return PY_COMPILED, ".pyc", "rb"
 
     # no .pyc file, use the .py file if it exists
     if pyfile_exists:
-        return PYFILE
+        return PY_SOURCE, ".py", "rU"
     else:
-        return NOFILE
+        return SEARCH_ERROR, None, None
 
 if sys.platform in ['linux2', 'freebsd']:
     def case_ok(filename):
@@ -67,61 +70,6 @@
         except OSError:
             return False
 
-def _prepare_module(space, w_mod, filename, pkgdir):
-    w = space.wrap
-    space.sys.setmodule(w_mod)
-    space.setattr(w_mod, w('__file__'), space.wrap(filename))
-    space.setattr(w_mod, w('__doc__'), space.w_None)
-    if pkgdir is not None:
-        space.setattr(w_mod, w('__path__'), space.newlist([w(pkgdir)]))    
-
-def try_import_mod(space, w_modulename, filepart, w_parent, w_name, pkgdir=None):
-
-    # decide what type we want (pyc/py)
-    modtype = find_modtype(space, filepart)
-
-    if modtype == NOFILE:
-        return None
-
-    w = space.wrap
-    w_mod = w(Module(space, w_modulename))
-
-    try:
-        if modtype == PYFILE:
-            filename = filepart + ".py"
-            stream = streamio.open_file_as_stream(filename, "rU")
-        else:
-            assert modtype == PYCFILE
-            filename = filepart + ".pyc"
-            stream = streamio.open_file_as_stream(filename, "rb")
-
-        try:
-            _prepare_module(space, w_mod, filename, pkgdir)
-            try:
-                if modtype == PYFILE:
-                    load_source_module(space, w_modulename, w_mod, filename,
-                                       stream.readall())
-                else:
-                    magic = _r_long(stream)
-                    timestamp = _r_long(stream)
-                    load_compiled_module(space, w_modulename, w_mod, filename,
-                                         magic, timestamp, stream.readall())
-
-            except OperationError, e:
-                w_mods = space.sys.get('modules')
-                space.call_method(w_mods,'pop', w_modulename, space.w_None)
-                raise
-        finally:
-            stream.close()
-
-    except StreamErrors:
-        return None
-
-    w_mod = check_sys_modules(space, w_modulename)
-    if w_mod is not None and w_parent is not None:
-        space.setattr(w_parent, w_name, w_mod)
-    return w_mod
-
 def try_getattr(space, w_obj, w_name):
     try:
         return space.getattr(w_obj, w_name)
@@ -267,8 +215,140 @@
     else:
         return first
 
+def find_in_meta_path(space, w_modulename, w_path):
+    assert w_modulename is not None
+    for w_hook in space.unpackiterable(space.sys.get("meta_path")):
+        w_loader = space.call_method(w_hook, "find_module",
+                                     w_modulename, w_path)
+        if space.is_true(w_loader):
+            return w_loader
+
+def find_in_path_hooks(space, w_modulename, w_pathitem):
+    w_path_importer_cache = space.sys.get("path_importer_cache")
+    try:
+        w_importer = space.getitem(w_path_importer_cache, w_pathitem)
+    except OperationError, e:
+        if not e.match(space, space.w_KeyError):
+            raise
+        w_importer = space.w_None
+        space.setitem(w_path_importer_cache, w_pathitem, w_importer)
+        for w_hook in space.unpackiterable(space.sys.get("path_hooks")):
+            try:
+                w_importer = space.call_function(w_hook, w_pathitem)
+            except OperationError, e:
+                if not e.match(space, space.w_ImportError):
+                    raise
+            else:
+                break
+        if space.is_true(w_importer):
+            space.setitem(w_path_importer_cache, w_pathitem, w_importer)
+    if space.is_true(w_importer):
+        w_loader = space.call_method(w_importer, "find_module", w_modulename)
+        if space.is_true(w_loader):
+            return w_loader
+
+def ImportInfo(type, name, stream, suffix="", filemode=""):
+    return type, name, stream, suffix, filemode
+
+def find_module(space, modulename, w_modulename, partname, w_path, use_loader=True):
+    """If use_loader is False, returns (import_info, None)
+    if use_loader is True, may return (None, w_loader)"""
+    # Examin importhooks (PEP302) before doing the import
+    if use_loader:
+        w_loader  = find_in_meta_path(space, w_modulename, w_path)
+        if w_loader:
+            return None, w_loader
+
+    # XXX Check for frozen modules?
+    #     when w_path is a string
+
+    # check the builtin modules
+    if modulename in space.builtin_modules:
+        return ImportInfo(C_BUILTIN, modulename, None), None
+
+    # XXX check frozen modules?
+    #     when w_path is null
+
+    if w_path is None:
+        w_path = space.sys.get("path")
+
+    for w_pathitem in space.unpackiterable(w_path):
+        # sys.path_hooks import hook
+        if use_loader:
+            w_loader = find_in_path_hooks(space, w_modulename, w_pathitem)
+            if w_loader:
+                return None, w_loader
+
+        path = space.str_w(w_pathitem)
+        filepart = os.path.join(path, partname)
+        if os.path.isdir(filepart) and case_ok(filepart):
+            initfile = os.path.join(filepart, '__init__')
+            modtype, _, _ = find_modtype(space, initfile)
+            if modtype in (PY_SOURCE, PY_COMPILED):
+                return ImportInfo(PKG_DIRECTORY, filepart, None), None
+            else:
+                msg = "Not importing directory " +\
+                        "'%s' missing __init__.py" % (filepart,)
+                space.warn(msg, space.w_ImportWarning)
+        modtype, suffix, filemode = find_modtype(space, filepart)
+        try:
+            if modtype in (PY_SOURCE, PY_COMPILED):
+                filename = filepart + suffix
+                stream = streamio.open_file_as_stream(filename, filemode)
+                try:
+                    return ImportInfo(modtype, filename, stream, suffix, filemode), None
+                except:
+                    stream.close()
+                    raise
+        except StreamErrors:
+            pass
+    return None, None
+
+def load_module(space, w_modulename, import_info, w_loader, ispkg=False):
+    if w_loader:
+        return space.call_method(w_loader, "load_module", w_modulename)
+    if import_info is None:
+        return
+    modtype, filename, stream, _, _ = import_info
+    if modtype == C_BUILTIN:
+        return space.getbuiltinmodule(filename)
+
+    if modtype in (PY_SOURCE, PY_COMPILED, PKG_DIRECTORY):
+        if ispkg:
+            w_mod = space.getitem(space.sys.get('modules'), w_modulename)
+        else:
+            w_mod = space.wrap(Module(space, w_modulename))
+        space.sys.setmodule(w_mod)
+        space.setattr(w_mod, space.wrap('__file__'), space.wrap(filename))
+        space.setattr(w_mod, space.wrap('__doc__'), space.w_None)
+
+    try:
+        if modtype == PY_SOURCE:
+            load_source_module(space, w_modulename, w_mod, filename,
+                               stream.readall())
+            return w_mod
+        elif modtype == PY_COMPILED:
+            magic = _r_long(stream)
+            timestamp = _r_long(stream)
+            load_compiled_module(space, w_modulename, w_mod, filename,
+                                 magic, timestamp, stream.readall())
+            return w_mod
+        elif modtype == PKG_DIRECTORY:
+            w_path = space.newlist([space.wrap(filename)])
+            space.setattr(w_mod, space.wrap('__path__'), w_path)
+            import_info, _ = find_module(space, "__init__", None, "__init__",
+                                         w_path, use_loader=False)
+            if import_info is None:
+                return w_mod
+            load_module(space, w_modulename, import_info, None, ispkg=True)
+            w_mod = check_sys_modules(space, w_modulename) # in case of "substitution"
+            return w_mod
+    except OperationError:
+        w_mods = space.sys.get('modules')
+        space.call_method(w_mods, 'pop', w_modulename, space.w_None)
+        raise
+
 def load_part(space, w_path, prefix, partname, w_parent, tentative):
-    w_find_module = space.getattr(space.builtin, space.wrap("_find_module"))
     w = space.wrap
     modulename = '.'.join(prefix + [partname])
     w_modulename = w(modulename)
@@ -277,44 +357,20 @@
         if not space.is_w(w_mod, space.w_None):
             return w_mod
     else:
-        # Examin importhooks (PEP302) before doing the import
-        if w_path is not None:
-            w_loader  = space.call_function(w_find_module, w_modulename, w_path)
-        else:
-            w_loader  = space.call_function(w_find_module, w_modulename,
-                                            space.w_None)
-        if not space.is_w(w_loader, space.w_None):
-            w_mod = space.call_method(w_loader, "load_module", w_modulename)
-            #w_mod_ = check_sys_modules(space, w_modulename)
-            if w_mod is not None and w_parent is not None:
-                space.setattr(w_parent, w(partname), w_mod)
-
-            return w_mod
-
-        # check the builtin modules
-        if modulename in space.builtin_modules:
-            return space.getbuiltinmodule(modulename)
+        import_info, w_loader = find_module(
+            space, modulename, w_modulename, partname, w_path)
 
-        if w_path is not None:
-            for path in space.unpackiterable(w_path):
-                path = space.str_w(path)
-                dir = os.path.join(path, partname)
-                if os.path.isdir(dir) and case_ok(dir):
-                    fn = os.path.join(dir, '__init__')
-                    w_mod = try_import_mod(space, w_modulename, fn,
-                                           w_parent, w(partname),
-                                           pkgdir=dir)
-                    if w_mod is not None:
-                        return w_mod
-                    else:
-                        msg = "Not importing directory " +\
-                                "'%s' missing __init__.py" % dir
-                        space.warn(msg, space.w_ImportWarning)
-                fn = dir
-                w_mod = try_import_mod(space, w_modulename, fn, w_parent,
-                                       w(partname))
-                if w_mod is not None:
-                    return w_mod
+        try:
+            if (import_info, w_loader) != (None, None):
+                w_mod = load_module(space, w_modulename, import_info, w_loader)
+                if w_parent is not None:
+                    space.setattr(w_parent, space.wrap(partname), w_mod)
+                return w_mod
+        finally:
+            if import_info:
+                _, _, stream, _, _ = import_info
+                if stream:
+                    stream.close()
 
     if tentative:
         return None
@@ -323,6 +379,45 @@
         msg = "No module named %s" % modulename
         raise OperationError(space.w_ImportError, w(msg))
 
+def reload(space, w_module):
+    """Reload the module.
+    The module must have been successfully imported before."""
+    if not space.is_w(space.type(w_module), space.type(space.sys)):
+        raise OperationError(
+            space.w_TypeError,
+            space.wrap("reload() argument must be module"))
+
+    w_modulename = space.getattr(w_module, space.wrap("__name__"))
+    modulename = space.str_w(w_modulename)
+    if not space.is_w(check_sys_modules(space, w_modulename), w_module):
+        raise OperationError(
+            space.w_ImportError,
+            space.wrap("reload(): module %s not in sys.modules" % (modulename,)))
+
+    namepath = modulename.split('.')
+    subname = namepath[-1]
+    parent_name = '.'.join(namepath[:-1])
+    parent = None
+    w_path = None
+    if parent_name:
+        w_parent = check_sys_modules(space, space.wrap(parent_name))
+        if w_parent is None:
+            raise OperationError(
+                space.w_ImportError,
+                space.wrap("reload(): parent %s not in sys.modules" % (
+                    parent_name,)))
+        w_path = space.getitem(w_parent, space.wrap("__path"))
+
+    import_info, w_loader = find_module(
+        space, modulename, w_modulename, subname, w_path)
+
+    if (import_info, w_loader) == (None, None):
+        # ImportError
+        msg = "No module named %s" % modulename
+        raise OperationError(space.w_ImportError, space.wrap(msg))
+
+    return load_module(space, w_modulename, import_info, w_loader)
+
 # __________________________________________________________________
 #
 # import lock, to prevent two threads from running module-level code in

Copied: pypy/branch/import-builtin/pypy/module/imp/test/test_import.py (from r70029, pypy/branch/import-builtin/pypy/module/__builtin__/test/test_import.py)
==============================================================================
--- pypy/branch/import-builtin/pypy/module/__builtin__/test/test_import.py	(original)
+++ pypy/branch/import-builtin/pypy/module/imp/test/test_import.py	Thu Dec 10 18:05:42 2009
@@ -9,7 +9,7 @@
 import sys, os
 import tempfile, marshal
 
-from pypy.module.__builtin__ import importing
+from pypy.module.imp import importing
 
 from pypy import conftest
 
@@ -64,6 +64,7 @@
              )
     setuppkg("pkg_substituting",
              __init__ = "import sys, pkg_substituted\n"
+                        "print 'TOTO', __name__\n"
                         "sys.modules[__name__] = pkg_substituted")
     setuppkg("pkg_substituted", mod='')
     p = setuppkg("readonly", x='')
@@ -726,12 +727,13 @@
             def __init__(self, *namestoblock):
                 self.namestoblock = dict.fromkeys(namestoblock)
             def find_module(self, fullname, path=None):
+                print "AFA FIND_MODULE", fullname
                 if fullname in self.namestoblock:
                     return self
             def load_module(self, fullname):
                 raise ImportError, "blocked"
 
-        import sys
+        import sys, imp
         modname = "errno" # an arbitrary harmless builtin module
         mod = None
         if modname in sys.modules:
@@ -740,6 +742,10 @@
         sys.meta_path.append(ImportBlocker(modname))
         try:
             raises(ImportError, __import__, modname)
+            # the imp module doesn't use meta_path, and is not blocked
+            # (until imp.get_loader is implemented, see PEP302)
+            file, filename, stuff = imp.find_module(modname)
+            imp.load_module(modname, file, filename, stuff)
         finally:
             sys.meta_path.pop()
             if mod:
@@ -774,6 +780,64 @@
             sys.path.pop(0)
             sys.path_hooks.pop()
 
+    def test_imp_wrapper(self):
+        import sys, os, imp
+        class ImpWrapper:
+
+            def __init__(self, path=None):
+                if path is not None and not os.path.isdir(path):
+                    raise ImportError
+                self.path = path
+
+            def find_module(self, fullname, path=None):
+                subname = fullname.split(".")[-1]
+                if subname != fullname and self.path is None:
+                    return None
+                if self.path is None:
+                    path = None
+                else:
+                    path = [self.path]
+                try:
+                    file, filename, stuff = imp.find_module(subname, path)
+                except ImportError, e:
+                    return None
+                return ImpLoader(file, filename, stuff)
+
+        class ImpLoader:
+
+            def __init__(self, file, filename, stuff):
+                self.file = file
+                self.filename = filename
+                self.stuff = stuff
+
+            def load_module(self, fullname):
+                mod = imp.load_module(fullname, self.file, self.filename, self.stuff)
+                if self.file:
+                    self.file.close()
+                mod.__loader__ = self  # for introspection
+                return mod
+
+        i = ImpWrapper()
+        sys.meta_path.append(i)
+        sys.path_hooks.append(ImpWrapper)
+        sys.path_importer_cache.clear()
+        mnames = ("colorsys", "urlparse", "distutils.core", "compiler.misc")
+        for mname in mnames:
+            parent = mname.split(".")[0]
+            for n in sys.modules.keys():
+                if n.startswith(parent):
+                    del sys.modules[n]
+        for mname in mnames:
+            m = __import__(mname, globals(), locals(), ["__dummy__"])
+            m.__loader__  # to make sure we actually handled the import
+        # Delete urllib from modules because urlparse was imported above.
+        # Without this hack, test_socket_ssl fails if run in this order:
+        # regrtest.py test_codecmaps_tw test_importhooks test_socket_ssl
+        try:
+            del sys.modules['urllib']
+        except KeyError:
+            pass
+
 class AppTestNoPycFile(object):
     usepycfiles = False
     lonepycfiles = False



More information about the Pypy-commit mailing list