Different kinds of Import Errors

Graham Dumpleton Graham.Dumpleton at gmail.com
Sat Dec 1 00:41:34 EST 2007


On Dec 1, 12:24 am, Thomas Guettler <h... at tbz-pariv.de> wrote:
> Sorry, but this does not work. If there is an ImportError
> during importing the existing module, it won't get inserted
> into sys.modules. I just tried it with a small example.
>
> An other solution would be to inspect the traceback. If the
> app_name+'.management' is in it, it exists.
>
> Graham Dumpleton schrieb:
>
> > On Nov 28, 12:35 am, Thomas Guettler <h... at tbz-pariv.de> wrote:
> >> If you look at this code, you see there are two kind of ImportErrors:
>
> >> 1. app_name has no attribute or file managment.py: That's OK.
> >> 2. managment.py exists, but raises an ImportError: That's not OK: reraise
>
> >>         # Import the 'management' module within each installed app, to register
> >>         # dispatcher events.
> >>         for app_name in settings.INSTALLED_APPS:
> >>             try:
> >>                 __import__(app_name + '.management', {}, {}, [''])
> >>             except ImportError, exc:
> >>                 if exc.args[0]!='No module named management':
> >>                     raise
>
> >> I am searching a better solution, since in a future version of python
> >> the string 'No module namend management' might be changed.
>
> >> Any better solution?
>
> > Perhaps check for the presence of the module in sys.modules.
>
> >   if (app_name + '.management') in sys.modules:
> >     raise
>
> > If not there, module couldn't be found. If module there but exception
> > occurred then some other import related error occurred.

What example did you use to test it? What version of Python are you
using?

Curious, as at least for Python 2.3 it behaves as I described with the
simple examples I tested. I do vaguely remember behaviour related to
this changing though, so possible that newer version works
differently.

First try case of importing module that doesn't exist:

>>> import sys
>>> import z
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ImportError: No module named z
>>> sys.modules['z']
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
KeyError: 'z'

Thus ImportError occurred, and not in sys.modules. Therefore module
must not have been able to be found.

Now lets try existing module, but non ImportError case first:

$ cat a.py
print 'a1'
xxx
print 'a2'

>>> import sys
>>> sys.modules['a']
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
KeyError: 'a'
>>> import a
a1
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "a.py", line 2, in ?
    xxx
NameError: name 'xxx' is not defined
>>> sys.modules['a']
<module 'a' from 'a.py'>

Thus, although an exception occurred in importing file, the module is
still in sys.modules.

Now lets try for an ImportError for where target module exists:

$ cat a.py
print 'a1'
import z
print 'a2'

>>> import sys
>>> import a
a1
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "a.py", line 2, in ?
    import z
ImportError: No module named z
>>> sys.modules['a']
<module 'a' from 'a.py'>

In this case ImportError occurred but is in sys.modules, thus
ImportError can only have been related to a sub module import as top
level module did actually exist.

I'll have to try this at work next week on newer version of Python
than my Mac has.

Graham



More information about the Python-list mailing list