DNS DNS - 7 months ago 22
Python Question

Is there a standard way to list names of Python modules in a package?

Is there a straightforward way to list the names of all modules in a package, without using

__all__
?

For example, given this package:

/testpkg
/testpkg/__init__.py
/testpkg/modulea.py
/testpkg/moduleb.py


I'm wondering if there is a standard or built-in way to do something like this:

>>> package_contents("testpkg")
['modulea', 'moduleb']


The manual approach would be to iterate through the module search paths in order to find the package's directory. One could then list all the files in that directory, filter out the uniquely-named py/pyc/pyo files, strip the extensions, and return that list. But this seems like a fair amount of work for something the module import mechanism is already doing internally. Is that functionality exposed anywhere?

Answer

Maybe this will do what you're looking for?

import imp
import os
MODULE_EXTENSIONS = ('.py', '.pyc', '.pyo')

def package_contents(package_name):
    file, pathname, description = imp.find_module(package_name)
    if file:
        raise ImportError('Not a package: %r', package_name)
    # Use a set because some may be both source and compiled.
    return set([os.path.splitext(module)[0]
        for module in os.listdir(pathname)
        if module.endswith(MODULE_EXTENSIONS)])