strange import phenomenon

  • Thread starter Christoph Zwerschke
  • Start date
C

Christoph Zwerschke

Just hitting a strange problem with Python import behavior. It is the
same on all Python 2.x versions and it is probably correct, but I
currently don't understand why this happens.

I have created a directory "dir" with the following three module,
__init__, hello, and test2; and another module test1 in the parent
directory, like that:


--- test1.py ----------
from dir import test2
------------------------


--- dir/__init__.py ---
print "init"
-----------------------


--- dir/hello.py ------
print "hello world"
-----------------------


--- dir/test2.py ------
import sys
sys.path = []

import hello
-----------------------


The script test2.py removes all entries from the sys.path. So when I run
test2.py directly, I get an ImportError because the hello module cannot
be imported. This is as expected.

However, if I run test1, the hello module *is* imported and I get the
"hello world" message. Why is that??

Probably there is a simple explanation, but currently I simply don't get it.


-- Christoph
 
D

Dieter Maurer

Christoph Zwerschke said:
Just hitting a strange problem with Python import behavior. It is the
same on all Python 2.x versions and it is probably correct, but I
currently don't understand why this happens.
...
--- dir/__init__.py ---
print "init"
-----------------------


--- dir/hello.py ------
print "hello world"
-----------------------


--- dir/test2.py ------
import sys
sys.path = []

import hello
-----------------------


The script test2.py removes all entries from the sys.path. So when I
run test2.py directly, I get an ImportError because the hello module
cannot be imported. This is as expected.


However, if I run test1, the hello module *is* imported and I get the
"hello world" message. Why is that??

Because Python tries to resolve modules inside a package ("dir" in
your example) locally first. This local resolution does not
involve "sys.path" but "package.__path__".
Only when the local lookup fails, a global lookup (using "sys.path")
is tried.

In your case, the local lookup succeeds.


Dieter
 
C

Christoph Zwerschke

Thank you, Dieter! Bingo.

When I think about it now, it is very logical: There must be another
mechanism besides sys.path, otherwise modules inside packages would not
find their siblings or subpackages.

But whereever the search path is explained, only sys.path was mentioned,
so I took that at face value. There is a small note in the tutorial, but
it is not very clear and in section 6.4.3 where you don't expect it. The
section 6.1.1 about the module search path does not mention it.

If I want test2.py to find only the modules in the search path, how
should I proceed? One idea that seems to work is setting

__name__ = '__main__'

in test2.py, but I don't know whether that is proper. Any idea?

Thanks again,
Christoph
 
C

Christoph Zwerschke

One idea that seems to work is setting __name__ = '__main__'

Or, del sys.modules[__name__].
 

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

Similar Threads


Members online

Forum statistics

Threads
474,173
Messages
2,570,938
Members
47,475
Latest member
NovellaSce

Latest Threads

Top