Commits

Anonymous committed 2c60dc2

Preliminary version of the implementation. Sketchy.

  • Participants
  • Parent commits 52fb003

Comments (0)

Files changed (1)

File Lib/importlib/engine.py

             except ImportError:
                 continue
             if finder:
-                print(type(finder))
+                print(finder)
                 loader = finder.find_module(fullname, engine=engine)
                 if loader:
                     return loader
                 return loader(fullname, full_path)
         return None
 
+    def get_subpath(self, fullname, engine=None):
+        package = fullname.rpartition('.')[0].replace('.', path_sep)
+        tail_module = fullname.rpartition('.')[2]
+        base_path = _path_join(self.path, package)
+        print(base_path)
+
+        # How can find_module() work by looking only by looking at the last module?
+        # How is __path__ different from sys.path?
+        # Not sure if we should find the whole path at once or just the last part?
+
+        # Last part has to be a file
+        # All the other parts have to be directories (do they?)
+        #if _path_isdir(base_path) and _case_ok(self.path, tail_module):
+        for suffix, loader in self.packages:
+            module_filename = tail_module + suffix
+            full_path = _path_join(base_path, module_filename)
+            if _path_isfile(full_path) and _case_ok(base_path, module_filename):
+                print("Returning basepath", base_path)
+                return base_path
+            else:
+                print("Returning None :(")
+                return None
+
+
 class _SourceFinderDetails:
 
     loader = _SourceFileLoader
                 name = "{0}.{1}".format(package[:dot], name)
             else:
                 name = package[:dot]
+        
         with _ImportLockContext():
             try:
                 module = self.modules[name]
                 try:
                     path = parent_module.__path__
                 except AttributeError:
-                    msg = (_ERR_MSG + '; {} is not a package').format(name, parent)
-                    raise ImportError(msg)
+                    virtual_path = self.get_virtual_path(name)
+                    if len(virtual_path):
+                        path = parent_module.__path__ = virtual_path
+                    else:
+                        msg = (_ERR_MSG + '; {} is not a package').format(name, parent)
+                        raise ImportError(msg)
+                    
             meta_path = self.meta_path + _IMPLICIT_META_PATH
             for finder in meta_path:
                 print(finder)
                 loader = finder.find_module(name, path, self)
                 if loader is not None:
+                    print("Loader: ", loader)
                     loader.load_module(name, self)
                     break
             else:
                     pass
             return module
 
+    def get_virtual_path(self, modulename, parent_path=None):
+        if parent_path is None:
+            parent_path = self.path
+
+        path = []
+
+        for entry in parent_path:
+            # Obtain a PEP 302 importer object - see pkgutil module
+            print("Path entry: ", entry)
+            importer = self.get_importer(entry)
+            print(importer)
+            if hasattr(importer, 'get_subpath'):
+                subpath = importer.get_subpath(modulename)
+                if subpath is not None:
+                    path.append(subpath)
+
+        return path
+
     def import_module(self, name, package=None):
         level = 0
         if name.startswith('.'):
 
         return engine
 
+    def get_importer(self, path_item):
+        """Retrieve a PEP 302 importer for the given path item
+
+        The returned importer is cached in self.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 = self.path_importer_cache[path_item]
+        except KeyError:
+            for path_hook in self.path_hooks:
+                try:
+                    importer = path_hook(path_item)
+                    break
+                except ImportError:
+                    pass
+            else:
+                importer = None
+            sys.path_importer_cache.setdefault(path_item, importer)
+
+        if importer is None:
+            try:
+                importer = _file_path_hook(path_item)
+            except ImportError:
+                importer = None
+        return importer
+
+
 class GlobalImportEngine(ImportEngine):
     """
     Subclass of ImportEngine which uses and writes to the global import-related