[Distutils] imp.find_modules and namespaces

PJ Eby pje at telecommunity.com
Mon Feb 11 22:11:38 CET 2013


On Mon, Feb 11, 2013 at 11:40 AM, Alessandro Dentella <sandro at e-den.it> wrote:
>
> I believe that this issue belongs to this list, please let me know if I'm
> wrong.
>
> Suppose I have 2 packages:
>
>   jmb.foo
>   jmb.bar
>
> distributed separately. Each has in jmb's __init__ a standard:
>
>
>   __import__('pkg_resources').declare_namespace(__name__)
>
> or
>
>   from pkgutil import extend_path
>   __path__ = extend_path(__path__, __name__)
>
>
> I just realized that imp.find_module() will return "fake" values
>
>   imp.find_module('jmb', None)
>
> may return (a tuple with) the path from the first package or from the
> second. Many framework will fail to discover commands in the inner module:
> one is detailed here [1] another is Django way of getting application's
> commands.
>
> I find it misleading to return a value that is not thorohly correct.
>
> Is there a workaround? Is the current behaviour considered correct for
> reasons I don't yet understand?

Since Python 2.5, the right way to do this is with
pkgutil.iter_modules() (for a flat list) or pkgutil.walk_packages()
(for a subpackage tree).

For your example, if I wanted to find just the subpackages of 'jmb', I would do:

    import jmb, pkgutil
    for (module_loader, name, ispkg) in
pkgutil.iter_modules(jmb.__path__, 'jmb.'):
        # 'name' will be 'jmb.foo', 'jmb.bar', etc.
        # 'ispkg' will be true if 'jmb.foo' is a package, false if it's a module


More information about the Distutils-SIG mailing list