Import Problems

B

Bill Jackson

Once again, I am having issues with imports...

Until now, I thought the general guidelines were to rarely use 'from x
import y' syntax, except when you really want to copy names over.
However, I have run into issues by following this guideline. So...

1) What is going wrong in the example below?
2) What is a good way to handle imports for packages w/subdirectories?

Here is a sample directory structure:

importtest/
__init__.py
test2/
__init__.py
someclass.py
mytest.py


Here are the definitions of the files:

# importtest/__init__.py
from test2 import *

# importtest/test2/__init__.py
from someclass import *
from test2 import *

# importtest/test2/someclass.py
class SomeClass:
pass

# importtest/test2/mytest.py
import importtest
print importtest.SomeClass


Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/home/user/lib/python/importtest/__init__.py", line 1, in ?
from test2 import *
File "/home/user/lib/python/importtest/test2/__init__.py", line 2, in ?
from mytest import *
File "/home/user/lib/python/importtest/test2/mytest.py", line 3, in ?
print importtest.SomeClass
AttributeError: 'module' object has no attribute 'SomeClass'

The problem seems to be an 'order' issue. importtest/test2/__init__.py
has loaded someclass.py, but it doesn't seem to have copied its contents
into importtest/__init__.py....perhaps it is because it hasn't finished
all of its imports. Is this correct?

So what is a good way to deal with this? In files which contain
implementations, I thought it was best not to use 'from x import y', but
this seems to be the only way to get this to work:

# importtest/test2/mytest.py
from someclass import SomeClass
print SomeClass

Is this the guideline?
Use 'from x import y' for modules within your package.
Use 'import y' for modules outside your package.

Help.
 
B

Bill Jackson

Bill Jackson wrote the following on 04/27/2007 12:49 PM:
# importtest/test2/__init__.py
from someclass import *
from test2 import *

Sorry typo here:

# importtest/test2/__init__.py
from someclass import *
from mytest import *
 
R

Robert Kern

Bill said:
Once again, I am having issues with imports...

Until now, I thought the general guidelines were to rarely use 'from x
import y' syntax, except when you really want to copy names over.

No, the guideline is to not use "from x import *" except at the interactive
prompt and occasionally in __init__.py's to "copy names over" as you put it.
However, I have run into issues by following this guideline. So...

1) What is going wrong in the example below?
2) What is a good way to handle imports for packages w/subdirectories?

Here is a sample directory structure:

importtest/
__init__.py
test2/
__init__.py
someclass.py
mytest.py


Here are the definitions of the files:

# importtest/__init__.py
from test2 import *

# importtest/test2/__init__.py
from someclass import *
from test2 import *

# importtest/test2/someclass.py
class SomeClass:
pass

# importtest/test2/mytest.py
import importtest
print importtest.SomeClass



Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/home/user/lib/python/importtest/__init__.py", line 1, in ?
from test2 import *
File "/home/user/lib/python/importtest/test2/__init__.py", line 2, in ?
from mytest import *
File "/home/user/lib/python/importtest/test2/mytest.py", line 3, in ?
print importtest.SomeClass
AttributeError: 'module' object has no attribute 'SomeClass'


The problem seems to be an 'order' issue. importtest/test2/__init__.py
has loaded someclass.py, but it doesn't seem to have copied its contents
into importtest/__init__.py....perhaps it is because it hasn't finished
all of its imports. Is this correct?

You are right that it is an order issue. The line "from test2 import *" hasn't
finished executing by the time "print importtest.SomeClass" is executed because
the former is trying to execute the latter.
So what is a good way to deal with this? In files which contain
implementations, I thought it was best not to use 'from x import y', but
this seems to be the only way to get this to work:

My recommendation is that inside packages, be as specific as is feasible with
your imports, even if you expose the symbols at a higher level for external
callers. If you have a module whose contents are being exposed in your
__init__.py, never rely on the contents of that __init__.py in that code.
Instead, go straight to the real modules that implement the symbols that you
need. So mytest.py should read:

from importtest.test2.someclass import SomeClass
print SomeClass

or

from importtest.test2 import someclass
print someclass.SomeClass

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top