imp.find_module() does not find modules from zipped eggs.
How can find modules which can come from both places: directories or zipped eggs? It is im
Assuming Python 2, the information I think you need is in PEP 302 - New Import Hooks (the PEP is outdated for Python 3, which is completely different in this regard).
Finding and importing modules from ZIP archives is implemented in zipimport, which is "hooked" into the import machinery as described by the PEP. When PEP 302 and importing from ZIPs were added to Python, the imp
modules was not adapted, i.e. imp
is totally unaware of PEP 302 hooks.
A "generic" find_module
function that finds modules like imp
does and respects PEP 302 hooks, would roughly look like this:
import imp
import sys
def find_module(fullname, path=None):
try:
# 1. Try imp.find_module(), which searches sys.path, but does
# not respect PEP 302 import hooks.
result = imp.find_module(fullname, path)
if result:
return result
except ImportError:
pass
if path is None:
path = sys.path
for item in path:
# 2. Scan path for import hooks. sys.path_importer_cache maps
# path items to optional "importer" objects, that implement
# find_module() etc. Note that path must be a subset of
# sys.path for this to work.
importer = sys.path_importer_cache.get(item)
if importer:
try:
result = importer.find_module(fullname, [item])
if result:
return result
except ImportError:
pass
raise ImportError("%s not found" % fullname)
if __name__ == "__main__":
# Provide a simple CLI for `find_module` above.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--path", action="append")
parser.add_argument("modname", nargs='+')
args = parser.parse_args()
for name in args.modname:
print find_module(name, args.path)
Note, though, that the result from finding a module in a ZIP archive looks quite different to what imp.find_module
returns: you'll get a zipimport.zipimporter
object for the particular ZIP. The litte program above prints the following when asked to find a regular module, a built-in module and a module from a zipped egg:
$ python find_module.py grin os sys
<zipimporter object "<my venv>/lib/python2.7/site-packages/grin-1.2.1-py2.7.egg">
(<open file '<my venv>/lib/python2.7/os.py', mode 'U' at 0x10a0bbf60>, '<my venv>/lib/python2.7/os.py', ('.py', 'U', 1))
(None, 'sys', ('', '', 6))