module import search path strangeness

tow toby.o.h.white at googlemail.com
Tue Aug 12 17:50:00 CEST 2008


On Aug 12, 9:56 am, Peter Otten <__pete... at web.de> wrote:
> tow wrote:

> > Basically, I had thought that import and imp.find_module used exactly
> > the same
> > search path, but the above example shows that at least in this
> > circumstance they
> > don't; import is picking up additional search paths from somewhere -
> > what am I missing?
>
> Grepping through the django source finds
>
> ./trunk/django/core/management/__init__.py:  
> sys.path.append(os.path.join(project_directory, os.pardir))

Hmm. It turns out that that is indeed the issue, but in a way that
wasn't immediately obvious to me. Looking at it in more context:

    sys.path.append(os.path.join(project_directory, os.pardir))
    project_module = __import__(project_name, {}, {}, [''])
    sys.path.pop()

sys.path is extended, the project module is imported, then the
additional path is dropped from sys.path.
And if I comment out those sys.path manipulations, I get the result I
expect later on.

What I think is happening is that in that stanza, project_module
(which is my_module in my case) is
imported from the altered sys.path. sys.path is then put back, but
python now knows about my_module.

As a result when my_module is imported again elsewhere, python already
knows about it, so no searching
of sys.path is done (which is good, because it wouldn't be found on
the current sys.path), and the
import apparently succeeds, though in fact it's effectively
(actually?) a no-op.

However, imp.find_module("my_module") forces a search of the sys.path,
and thus fails.

Or at least, that is what I surmise, given that I see

import my_module # succeeds
imp.find_module("my_module") # fails, raising ImportError

So, to answer my original question, the difference in search behaviour
between "import" and "imp.find_module" is that the former might not
look at sys.path at all if the module has already been loaded, while
the latter will only search on the current sys.path.

Am I right?

Toby



More information about the Python-list mailing list