On Wed, 7 Jun 2000, Gordon McMillan wrote:
I disagree with the moral.
If test.py uses "import A.parent" and changes references accordingly, it works.
Correct. Well, maybe there are two things going on here. I agree that import * isn't usually a very good idea. However, notice that the problem occurs even if the first line of test.py is "import parent" (no star). When you talk about changing references accordingly, the real issue is referencing "A.parent" rather than "parent". In fact, if you change the first line to "from A.parent import *" (not that i am advocating this!) -- it works. In short: from parent import * ... Parent doesn't work import parent ... parent.Parent doesn't work from A.parent import * ... Parent works import A.parent ... A.parent.Parent works The first two cases -- attempting to import "parent" -- are only made possible by the fact that we're executing test.py from within the A/ directory, and hence the confusion. This problem is an "advanced" version of a simpler issue which a friend of mine discovered and complained about recently to me: the __main__ vs. module-name conflict. Allow me to paraphrase his example. Exhibit A: ---- spam.py ---- import eggs def go(): print "was", eggs.a eggs.a = 3 print "now", eggs.a ---- eggs.py ---- import spam a = 1 def go(): spam.go() print "finally", a if __name__ == "__main__": go() --- watch what happens ---- % python eggs.py was 1 now 3 finally 1 % python >>> import eggs >>> eggs.go() was 1 now 3 finally 3 Exhibit B: ---- one.py ---- import two def go(): pass ---- two.py ---- import one one.go() ---- watch what happens ---- % python one.py % python two.py Traceback (innermost last): File "two.py", line 1, in ? import one File "./one.py", line 1, in ? import two File "./two.py", line 2, in ? one.go() AttributeError: go Exit 1 % python >>> import one Traceback (innermost last): File "<stdin>", line 1, in ? File "./one.py", line 1, in ? import two File "./two.py", line 2, in ? one.go() AttributeError: go >>> import two >>> The facts that eggs.a appears to behave differently in Exhibit A, and that one.py can be run but two.py cannot, yet "two" can be imported and "one" cannot, in Exhibit B, both result from the duplication namespaces in __main__ and in a module. Normally, this only affects the main file that you are running, the one with the __main__ namespace. However, attempting to run scripts in package directories allows this problem to propagate further into the duplication of other modules: __main__ imports parent which imports child A.test imports A.parent which imports A.child ...and that can cause duplicate classes all over the place, which is what happened to Andy. My friend was quite irked by the existence of __main__, citing it as the culprit for this duplication. But naturally Python can't always know the name of the script being run -- in the case of a file ending in .py, perhaps, it's easy, but the script might come from a pipe, for example. So eliminating __main__ doesn't seem like a feasible response. Depending how "real" you consider this problem, leaving things as they are and instructing people in the discipline of keeping modules and scripts separated may be the best response. I bet this crops up all the time in those "testing" sections of modules that use the 'if __name__ == "__main__"' convention, though... -- ?!ng "Computers are useless. They can only give you answers." -- Pablo Picasso