[Python-Dev] new import hooks & zip import

Moore, Paul Paul.Moore@atosorigin.com
Thu, 12 Dec 2002 16:32:14 -0000


Guido wrote:

> > Skip Montanaro wrote:
> >=20
> > > Scanning the patch summary I see:
> > >=20
> > >     sys.path_hooks is a list of callable objects that take=20
> > >     a string as their only argument. A hook will be called=20
> > >     with a sys.path or pkg.__path__ item. It should return=20
> > >     an "importer" object (see below), or raise ImportError=20
> > >     or return None if it can't deal with the path item. By=20
> > >     default, sys.path_hooks only contains the zipimporter =20
> > >     type, if the zipimport module is available.           =20
> > >
> > > Why have it raise ImportError or return None if it can't
> > > deal with the path item? Shouldn't there be only one way to
> > > report failure? (Or do I misread your explanation?)
> >
> > No, you read correctly... I'm not sure, I just thought if
> > might be convenient to also be able to return None. I'd
> > be happy to stick with just one way, though (which would
> > be raising ImportError, as that's easiest from __init__
> > methods).
>
> Hm, I'd prefer None. With an exception (especially when you're
> reusing an existing exception) you never know if it was raised
> intentionally or whether it means a real (unexpected) error --
> in the latter case, swallowing the traceback would be a bad
> idea because it makes diagnosing the real problem hard. ("Why
> does my zipimport not work? I don't get any errors, but it
> doesn't work...")

The problem is that in 99% of cases (and specifically for
zipimporter) the "callable object" in question is a class. It's
not possible for a class when called to return a value (the
constructor either does its job or raises an exception). So an
exception signalling "I don't apply to this path item" is the
only way of letting classes be put directly on sys.path_hooks.
You could mandate wrappers, but I imagine that

    def my_importer_wrapper(path):
        try:
            return my_importer(path)
        except ImportError:
            return None

    sys.path_hooks.append(my_importer_wrapper)

is even more offensive...

Actually, I'd say that "I can't handle this" should *always* be
signalled by an exception (Only One Way To Do It), but rather than
reusing ImportError, that should be a new exception type (I don't
know what to call it though - ImportHandlerError?) That way, you
don't risk masking real exceptions.

Paul.