9

Given a package, how can I automatically find all its sub-packages?

0

2 Answers 2

10

You can't rely on introspection of loaded modules, because sub-packages may not have been loaded. You'll have to look at the filesystem, assuming the top level package in question is not an egg, zip file, extension module, or loaded from memory.

def get_subpackages(module):
    dir = os.path.dirname(module.__file__)
    def is_package(d):
        d = os.path.join(dir, d)
        return os.path.isdir(d) and glob.glob(os.path.join(d, '__init__.py*'))

    return filter(is_package, os.listdir(dir))
Sign up to request clarification or add additional context in comments.

4 Comments

Not working. That glob.glob thing returns a list: Is that a mistake?
I had forgotten that os.listdir does not return the full path. Fixed the bug. (An empty list in a boolean context evaluates to false.)
SilentGhost tells me that my implementation is terrible, though it works for me. I'm assuming yours is okay, so I guess I'll select that as the answer. However, you think it's okay to put the question mark after the py? Wouldn't it not work when there isn't a pyc or pyo file?
You're correct, it should be an asterisk so that it matches .py, .pyc, and .pyo files. As it stands, there are still a lot of gotchas with this sort of thing. I hope you aren't using it for anything important, like missile control. =)
0

Inspired by James Emerton's answer:

def find_subpackages(module):
    result=[]
    for thing in os.listdir(os.path.dirname(module.__file__)):
        full=os.path.join(os.path.dirname(module.__file__),thing)
        if os.path.isdir(full):
            if glob.glob(os.path.join(full, '__init__.py*'))!=[]:
                result.append(thing)
    return result

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.