Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I list all packages/modules available to Python from within a Python script?

Tags:

python

package

I have looked around and do not see a solution for this. What I would like to do is get a list of all packages available in Python at run-time.

I looked at these:

  • List all the modules that are part of a python package?
  • Python package structure
  • How to: get list of modules in a package

But they are not what I am looking for.

I attempted to do this:

import pkgutil
for pkg in pkgutil.walk_packages():
    print(pkg)  # or do something with them...

However, when I do this:

import sys
sys.modules.keys()​​​

It appears that I have loaded all the packages which is not what I want to do, what I want is a list of strings of all packages+modules available to the current Python installation without loading them all when I do it.

like image 421
Tom Myddeltyn Avatar asked Jun 10 '16 15:06

Tom Myddeltyn


2 Answers

Alright, I was curious, and I digged a bit into pkgutil, and I came up with this, which is much simpler than I expected:

list(pkgutil.iter_modules())

It lists all top-level packages/modules available either as regular files or zip packages, without loading them. It will not see other types of packages though, unless they properly register with the pkgutil internals.

Each returned entry is a 3-tuple with the items:

  1. module_finder: The file finder instance that found the module
  2. name: The name of the module
  3. ispkg: A boolean specifying whether it is a regular module or a package.

Example 3-tuple:

(FileFinder('/usr/lib/python3/dist-packages'), 'PIL', True)

And I can confirm that this did not load the PIL package:

In [11]: sys.modules['PIL']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-11-b0fc0af6cc34> in <module>()
----> 1 sys.modules['PIL']

KeyError: 'PIL'
like image 196
spectras Avatar answered Oct 07 '22 21:10

spectras


I put together a very rough way of getting this list (see below), which appears to be more accurate than pkgutil. See details below.

In addition, I found loaded_modules and list-imports, but I tested none of them.


I have compared the results of my method with the answer by spectras:

  1. All items in the output by spectras (say, modlist2) are in the output here (say, modlist1).
  2. There are quite a few items in modlist1 that are not in modlist2. To my surprise, this difference included modules like sys, math, zlib, etc. In my case, the respective lengths were 390 vs. 327, so the method with pkgutil gives quite incomplete results.

The method to pull the list of available modules consists of:

  1. Capturing output of help into a string
  2. Removing spare text from the captured string
  3. Splitting multicolumn output

Code is here:

def modules_list() :
    """Return a list of available modules"""
    import sys
    # Capture output of help into a string
    import io
    stdout_sys = sys.stdout
    stdout_capture = io.StringIO()
    sys.stdout = stdout_capture
    help('modules')
    sys.stdout = stdout_sys
    help_out = stdout_capture.getvalue()
    # Remove extra text from string
    help_out = help_out.replace('.', '')
    help_out = help_out.replace('available modules', '%').replace('Enter any module', '%').split('%')[-2]
    # Split multicolumn output
    help_out = help_out.replace('\n', '%').replace(' ', '%').split('%')
    help_out = list(filter(None, help_out))
    help_out.sort()
    return help_out
like image 34
sancho.s ReinstateMonicaCellio Avatar answered Oct 07 '22 23:10

sancho.s ReinstateMonicaCellio