zipimporter can't find/load sub-modules
Question: I'm trying to load a sub-module from a ZIP package but it won't work. How to
do it right?

**foo.zip**

    
    
    foo/
        __init__.py
       bar.py
    

**test.py**

    
    
    import os
    import zipimport
    
    dirname = os.path.dirname(__file__)
    importer = zipimport.zipimporter(os.path.join(dirname, 'foo.zip'))
    print importer.is_package('foo')
    print importer.load_module('foo')
    print importer.load_module('foo.bar')
    

**Output**

    
    
    $ python test.py
    True
    <module 'foo' from 'foo.zip/foo/__init__.py'>
    Traceback (most recent call last):
      File "test.py", line 8, in <module>
        print importer.load_module('foo.bar')
    zipimport.ZipImportError: can't find module 'foo.bar'
    

* * *

**Update** 2015/04/11 06:30 AM PT

The following would work, but is this the real solution to the problem? The
`zipimport.zipimporter` documentation explicitly states _"fullname must be the
fully qualified (dotted) module name."_ and has an `is_package()` method that
seems to function properly.

    
    
    import os
    import zipimport
    
    dirname = os.path.dirname(__file__)
    importer = zipimport.zipimporter(os.path.join(dirname, 'foo.zip'))
    
    def load_module(name):
        parts = name.split('.')
        module = importer.load_module(parts[0])
        full_name = parts[0]
        for part in parts[1:]:
            full_name += '.' + part
            if not hasattr(module, '__path__'):
                raise ImportError('%s' % full_name)
            path = module.__path__[0]
            module = zipimport.zipimporter(path).load_module(part)
    
        return module
    
    print load_module('foo.bar')
    


Answer: It will load if you change `importer.load_module('foo.bar')` to
`importer.load_module('foo/bar')`. I am not sure why, because the
documentation reads

> load_module(fullname)
>
> Load the module specified by fullname. fullname must be the fully qualified
> (dotted) module name. It returns the imported module, or raises
> ZipImportError if it wasn’t found.

