Hello,

I'm currently writing an import hook which will cache information on the local disk, instead of retrieving it every time from the slow NFS where I work.
To make sure that I understand how import hooks work, and as a starting point, I wrote a dummy import hook, which is supposed to behave like the python's built-in import mechanism.
I post it here, for two reasons:
1. So that developers who understand the import mechanism better than I do may review it and find things which I didn't do exactly right.
2. Because I think other people might find it helpful when writing new import hooks, as a starting point as well as for better understanding -- there's nothing like a working example to help you settle up on what does which where. (Although perhaps a few more comments, in addition to those which I wrote, might help...)


(Note: I wrote the "DEBUG" parts in order to make sure that my importer works, because if it fails things might be done by the built-in importer and I won't notice. These parts can be removed, of course.)

Do you think that it might be useful? Maybe something like that can go into the "examples" section of the imp module?

Thanks,
Noam Raphael
import imp
import sys

DEBUG = True

if DEBUG:
    myimports = []


class InPackageFinder(object):
    """Find a module/package in a package."""
    
    def find_module(self, fullname, path=None):
        if path is None:
            # Not in a package - don't handle it here.
            return None

        try:
            f, fn, desc = imp.find_module(fullname[fullname.rfind('.')+1:],
                                          path)
        except ImportError:
            # Well, I don't find it, maybe others will.
            return None

        return Loader(f, fn, desc)


class TopLevelFinder(object):
    """Find a top level module/package."""

    def __init__(self, path):
        self._path = path

    def find_module(self, fullname):
        try:
            f, fn, desc = imp.find_module(fullname, [self._path])
        except ImportError:
            # It is not in this path. Maybe in another one.
            return None

        return Loader(f, fn, desc)


class Loader(object):
    """Load a module/package."""

    def __init__(self, f, fn, desc):
        self._f, self._fn, self._desc = f, fn, desc

    def load_module(self, fullname):
        if DEBUG:
            myimports.append(fullname)
            
        try:
            return imp.load_module(fullname, self._f, self._fn, self._desc)
        finally:
            if self._f is not None:
                # For packages we have None instead of a file object.
                self._f.close()


def install():
    sys.meta_path.append(InPackageFinder())
    sys.path_hooks.append(TopLevelFinder)
    sys.path_importer_cache.clear()

    if DEBUG:
        myimports.extend(sys.modules.iterkeys())

if DEBUG:
    def checkok():
        return not [x for x in sys.modules if
                    sys.modules[x] is not None
                    and hasattr(sys.modules[x], "__file__")
                    and x not in myimports]
_______________________________________________
Python-Dev mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to