[Python-Dev] Fix import errors to have data

Guido van Rossum guido at python.org
Tue Jul 27 16:45:14 CEST 2004


> A common idiom to optionally support some module if it is
> present is to use ImportError handlers:
> 
>    try:
>        import foo
>    except ImportError:
>        # Configure for absense of foo
>        ...
>    else:
>        # Configure for presense of foo
>        ...
> 
> Unfortunately, this is a bug trap.  The module foo
> might be present and yet it's import could fail with an import error.
> This can happen if one of *its* imports fails.  Code like that
> above will hide such bugs.

Why is it important to catch the bug at this point?  If the module
imported by foo has a bug, importing it directly will reveal it.  The
code importing foo will work without foo.  In some very real sense,
foo is unusable, and its importer is making the right choice.

> Unfortunately, it's hard to do this correctly, because ImportErrors
> don't have the module name as data.  When the import error is raised,
> it is raised with an error message rather than data.  This is because
> most standard exception classes share a common __str__ that
> simply prints their initialization arguments.
> 
> At present, to conditionally support a module, you have to
> use code like:
> 
>    try:
>        import foo
>    except ImportError, v:
>        if not str(v).endsswith(' foo'):
>            raise
>        # Configure for absense of foo
>        ...
>    else:
>        # Configure for presense of foo
>        ...
> 
> which is ugly and brittle.
> 
> I'd like to get this fixed.
> 
> I propose to:
> 
>    - Provide ImportError with an __init__ that takes a module name
>      and sets a module_name attribute
> 
>    - Provide ImportError with an __str__ that produces the message
>      we have now
> 
>    - Change standard code that raises import errors to provide just the
>      module name.
> 
> With this change, one could write careful conditional
> import code like this:
> 
>    try:
>        import foo
>    except ImportError, v:
>        if v.module_name != 'foo':
>            raise
>        # Configure for absense of foo
>        ...
>    else:
>        # Configure for presense of foo
>        ...
> 
> which is much cleaner IMO.

If you provide a working patch, I have no objection against its
introduction.  I'm just not going out of my way for it.

--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list