EDIT:
OK, I managed to isolate the bug and the exact, complete code to to reproduce it. But it appears either something that’s by design, or a bug in python.
Create two sibling packages: admin & General, each with it’s own __init__.py, of course.
In the package admin put the file ‘test.py’ with the following code:
from General.test02 import run
import RunStoppedException
try:
run()
except RunStoppedException.RunStoppedException,e:
print 'right'
except Exception,e:
print 'this is what i got: %s'%type(e)
and also in admin put the file ‘RunStoppedException.py’ with the following code:
class RunStoppedException(Exception):
def __init__(self):
Exception.__init__(self)
In the package General put the file test02.py with the code:
import admin.RunStoppedException
def run():
raise admin.RunStoppedException.RunStoppedException()
the printout:
this is what i got: <class 'admin.RunStoppedException.RunStoppedException'>
When it should’ve been right. This only happens when one file sits in the same dir as the exception, so they import it differently.
Is this by design, or a bug of python?
I am using python2.6, running it under eclipse+pydev
This is an ambiguous relative import. Do you mean
RunStoppedExceptionfrom theadmintop-level module? Or frommypackage.adminwhen you’re in a package? If your current working directory (which is added to the module search path) happens to be inside the package, it could be either, depending on whether Python knows it’s inside a package, which depends on how you’re running the script.If you’ve got both
import admin.RunStoppedExceptionandimport RunStoppedExceptionin different modules, that could very well import two copies of the same module: a top-levelRunStoppedExceptionand a submoduleadmin.RunStoppedExceptionof the packageadmin, resulting in two instances of the exception, and the subsequent mismatch inexcept.So don’t use implicit relative imports. They are in any case going away (see PEP328). Always spell out the full module name, eg.
import mypackage.admin.RunStoppedException. However avoid using the same identifier for your module name and your class name as this is terribly confusing. Note that Python will allow you to say:where that identifier is referring to a module and not a subclass of Exception. This is for historical reasons and may also go away, but for the meantime it can hide bugs. A common pattern would be to use
mypackage.exceptionsto hold many exceptions. One-class-per-file is a Java habit that is frowned on in Python.It’s also a good idea generally try to keep the importing of module contents (like classes) down as much as possible. If something changes the copy of
RunStoppedExceptioninside the module, you’ll now have different copies in different scripts. Though classes mostly don’t change, module-level variables may, and monkey-patching and reloading become much harder when you’re taking stuff outside of its owner module.