Listing Python modules and getting help docs from Excel

Python functions include detailed help documentation but to access this you need the full path to the function, including the names of all code modules and submodules. This post looks at how this information can be found using Excel with pyxll, using the Scipy and Numpy libraries as examples.

As well as pyxll the code requires the inspect, importlib, pkgutil, and numpy libraries:

from inspect import getmembers, isfunction, getdoc, ismodule, signature
import importlib as imp
import pkgutil

import numpy as np

from pyxll import xl_func, xl_arg, xl_return

Example code samples for listing functions from modules include the use of the functions inspect.getmembers and pkgutil.iter_modules. The code below allows either of these functions to be used, and returns either the full output, or just the names of listed functions:

@xl_func
def get_modlist(modname, out=1, out2 = 1):
    mod = imp.import_module(modname)
    if out == 1:
        memb = getmembers(mod, ismodule)
        namelist =  [submod[0] for submod in memb if ismodule(submod[1])] 
    else:
        memb = list(pkgutil.iter_modules(mod.__path__))
        namelist =  [submod[1] for submod in memb if submod[2] == True  ]
    if out2 == 1:
        return memb
    else:
        return namelist

This function was found to give different results with Numpy and Scipy. Using getmembers on the top level Scipy module returned no results, but Numpy returned all available module names:

Using pkgutil.iter_module returns the available modules in Scipy and are indicated with TRUE in the third column, but for Numpy all the modules are indicated as FALSE:

The code below uses pkgutil.iter for the top level Scipy module, and getmembers for all other cases:

@xl_func
def get_modules(modname):
    try:
        mod = imp.import_module(modname)
    except:
        return []
    if modname == 'scipy': 
        memb = list(pkgutil.iter_modules(mod.__path__))
        namelist =  [submod[1] for submod in memb if submod[2] == True  ]
    else:
        memb = getmembers(mod, ismodule)
        namelist =  [submod[0] for submod in memb] 
    return namelist

The screenshot below shows this function displaying scipy modules and 5 levels of submodule:

For any selected submodule all the available functions can be listed with the get_funcs function:

@xl_func
def get_funcs(modname,  searchstring =''):
    lentxt = len(searchstring)
    mod = imp.import_module(modname)
    memb = getmembers(mod)
    namelist =  [func[0] for func in memb if ((isfunction(func[1]) or type(func[1]) == np.ufunc) and func[0][0:lentxt] == searchstring)]
    return namelist

This function will display all functions included in the sub-module, or optionally a search string may be used:

From the list of functions, one can be chosen to display the built-in help with the Get_Docs function:

@xl_func
@xl_arg('afunc', 'str')
@xl_arg('modname', 'str')
@xl_return('numpy_column<str>')
def get_docs(afunc, modname):
    try:
        mod = imp.import_module(modname)
        afun = getattr(mod, afunc)
        doc = getdoc(afun).split('\n')
    except:
        doc = ''
    return np.array([doc])

With recent versions of Excel this function will return a dynamic array, automatically resizing to display the full extent of the text:

The code and spreadsheet may be downloaded from:

PythonDocs.zip

This entry was posted in Excel, Link to Python, Newton, NumPy and SciPy, PyXLL, UDFs and tagged , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.