I was debugging an issue with our Django app at work today; an
admin.py file wasn't being picked up, and nothing was appearing in the admin pages. It turned that an
ImportError was being thrown in the
admin.py and Django was interpreting this as the file not existing.
I'm assuming that the reason for this is that Django uses
__import__ to import the module, and catches
ImportError's if the
admin.py doesn't exist. The trouble with this is that if
admin.py does exist, and throws an
ImportError of its own, Django will also interpret that as a missing
admin.py – which can be misleading.
The only solution I can think of to more accurately handle this would be to programmaticaly examine the traceback to determine where the ImportError is thrown. If the traceback is one level deep, we know that the
ImportError was thrown because the module doesn't exists. If it is greater than one level then we know the module was found, but has thrown an
ImportError of its own.
Here's a simple proof of concept:
#check_import.py import traceback import sys def check_import(name): try: __import__(name) except ImportError: exceptionType, exceptionValue, exceptionTraceback = sys.exc_info() return len(traceback.extract_tb(exceptionTraceback)) > 1 return True print check_import("os") print check_import("noimport") print check_import("anotherlevel")
#anotherlevel.py import thismoduledoesnotexist
This produces the following when run:
It would be nice if Django did something similar for its implicit imports. I think the best behaviour would be re-raise the ImportError if it the module does actually exist. That way, it is clear what the problem is. I may attempt to write a patch at some point, unless someone knows of a better solution.