2.3a1: importhooks oddity

Just just at xs4all.nl
Thu Jan 2 15:17:55 EST 2003


In article <3E1497C4.1070605 at earthlink.net>,
 Hans Nowak <wurmy at earthlink.net> wrote:

> OK, updated code:
> 
> import sys
> 
> print '' in sys.path
> print '' in sys.path_importer_cache.keys()
> 
> def f(path):
>      print "Wahey!", `path`
>      raise ImportError
> 
> sys.path_hooks.append(f)
> 
> import nothing
> 
> On Windows:
> 
> (P:\test\2.3) $ python test-importhooks-2.py
> True
> True
> Traceback (most recent call last):
>    File "test-importhooks-2.py", line 14, in ?
>      import nothing  # needless to say, doesn't exist
> ImportError: No module named nothing
> 
> On Cygwin:
> 
> (P:\test\2.3) $ c:\cygwin\usr\local\bin\python2.3.exe test-importhooks-2.py
> True
> False
> Wahey! ''
> Traceback (most recent call last):
>    File "test-importhooks-2.py", line 14, in ?
>      import nothing  # needless to say, doesn't exist
> ImportError: No module named nothing
> 
> The empty string '' isn't a key in sys.path_importer_cache, apparently. 
> (Interesting, when I run Cygwin-Python's interactive interpreter, and inspect 
> sys.path_importer_cache, the empty string *is* there...)

sys.path_importer_cache only contains values for path items that have 
been touched. This means that if all imports succeed before the end of 
sys.path is reached, the last item(s) won't have values in the cache. 
Perhaps cygwin doesn't do any failing imports at startup? I think os.py 
catches some ImportErrors, but maybe there are other places as well. Can 
I see the contents of both systems' sys.paths, both with and without -S?

> When run with -S, both scripts produce a whole list of Wahey's, and the two 
> conditions at the beginning are True and False, respectively.

That was expected, as Python doesn't do any file system imports by 
itself, so site.py actually fills the cache.

> >>If I understand correctly, then registering any function or class in
> >>path_hooks is useless on Windows for path "", since it will be bypassed.
> > 
> > Not sure what you mean. I'd think you could still register a hook for "" 
> > and make it do "something".
> 
> Hmm, well, I mean, that if a Windows user innocently runs code like
> 
> def f(path):
>      # do something...
> 
> sys.path_hooks.append(f)
> 
> then this has no effect at all, because the function is just skipped.  Sure, 
> I 
> now know that I have to clear the cache (or maybe manipulate it in other 
> ways), 
> but this behavior still seems confusing. (And on a superficial level, 
> *appear* 
> to be non-portable... a script would work on one platform but not on the 
> other.) 

Hm, what's in the cache is highly platform dependent, as is (eg.) what's 
in sys.modules.

There are two idioms for adding path hooks:
1)
    sys.path_hooks.append(myhook)
    sys.path.append(item_that_myhook_likes)
2)
    sys.path_hooks.append(myhook)
    sys.path_importer_cache.clear()  # take over existing path items

> Now I realize that installing import hooks is not something you'd do 
> every day, and probably not for the faint of heart, but still... maybe this 
> caveat should be documented somewhere?

Documentation still needs to be done, and I'll try my best to document 
all subtleties in there. (Not that the __import__ subtleties are all 
that well documented...)

Just




More information about the Python-list mailing list