Skip to content

Instantly share code, notes, and snippets.

@kinverarity1
Last active June 3, 2020 13:05
Show Gist options
  • Save kinverarity1/6038316 to your computer and use it in GitHub Desktop.
Save kinverarity1/6038316 to your computer and use it in GitHub Desktop.
List loaded Python modules and packages, and show their version numbers and/or Git repository's HEAD commit SHA. Example: http://nbviewer.ipython.org/6038316/zz_example.ipynb
'''List loaded modules and packages, and show their version numbers
and/or Git repository's HEAD commit SHA.
'''
# Standard library modules
import types
# Third-party packages
import git # GitPython
def module_path(mod):
'''Returns path to the file that module *mod* comes from.
If it doesn't come from a file, return None.'''
if hasattr(mod, '__file__'):
return os.path.abspath(os.path.dirname(mod.__file__))
else:
return None
def from_git_repo(mod):
'''Does the module *mod* reside in a Git repository?'''
path = module_path(mod)
if path:
try:
repo = git.Repo(path)
except:
return False
else:
return True
else:
return False
def git_path_sha(mod, slice=slice(0, 8, 1)):
'''Return SHA hash for the HEAD commit for the repository
that the module *mod* resides in.'''
repo = git.Repo(module_path(mod))
return repo.git_dir, repo.head.commit.hexsha[:8]
def module_version(mod):
'''Return version string for module *mod*, or nothing if
it doesn't have a "version" or "__version__" attribute.'''
version = []
if hasattr(mod, '__dict__'):
keys = []
for key in mod.__dict__.keys():
if key.lower() == 'version' or key.lower() == '__version__':
v = mod.__dict__[key]
if isinstance(v, basestring):
version.append(v)
if keys:
print mod, keys
if version:
return ', '.join(version)
else:
return ''
def find_loaded_modules(only_versioned_modules=True):
'''Return list of loaded modules for which there is a version
number or a Git repository commit SHA.
Return a list of *(name, version, path_to_git_repo, git_head_sha)*,
which has an HTML property for pretty display in IPython Notebooks.
'''
def list_of_lists_to_HTML(lists, header_row=None):
'''Convert a list of a list of strings to a HTML table.'''
s = '<table>'
if header_row:
s += '\n\t<tr>\n\t\t'
s += ''.join(['<th>%s</th>' % item for item in header_row])
s += '\n\t</tr>'
for inner_list in lists:
s += '\n\t<tr>\n\t\t'
s += ''.join(['<td>%s</td>' % item for item in inner_list])
s += '\n\t</tr>'
s += '\n</table>'
return s
class LoadedModules(list):
'''Very simple wrapper for a list of lists of strings, with an attribute
for display in IPython Notebooks.'''
def __init__(self, *args, **kwargs):
list.__init__(self, *args, **kwargs)
@property
def HTML(self):
from IPython.display import HTML
return HTML(
list_of_lists_to_HTML(
self, header_row=['Name', 'Version', 'Path', 'SHA']))
objs = LoadedModules()
for i, mod in enumerate(globals().values()):
if isinstance(mod, types.ModuleType):
if hasattr(mod, '__name__'):
name = mod.__name__
else:
name = ''
if from_git_repo(mod):
path, sha = git_path_sha(mod)
else:
path = ''
sha = ''
version = module_version(mod)
if only_versioned_modules:
flag = version or (path and sha)
else:
flag = True
if flag:
objs.append([mod.__name__, version, path, sha])
objs.sort(key=lambda r: r[0])
return objs
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@NicoCoallier
Copy link

Very nice code !

@sri-teja
Copy link

sri-teja commented Oct 17, 2019

Python 3 compatible

'''List loaded modules and packages, and show their version numbers
and/or Git repository's HEAD commit SHA.
'''
# Standard library modules
import types
from six import string_types

# Third-party packages
# If GitPython not installed, then install using the below command
# !pip install GitPython
import git      # GitPython
import os
def module_path(mod):
    '''Returns path to the file that module *mod* comes from.
    If it doesn't come from a file, return None.'''
    if hasattr(mod, '__file__'):
        return os.path.abspath(os.path.dirname(mod.__file__))
    else:
        return None

    
def from_git_repo(mod):
    '''Does the module *mod* reside in a Git repository?'''
    path = module_path(mod)
    if path:
        try:
            repo = git.Repo(path)
        except:
            return False
        else:
            return True
    else:
        return False

    
def git_path_sha(mod, slice=slice(0, 8, 1)):
    '''Return SHA hash for the HEAD commit for the repository
    that the module *mod* resides in.'''
    repo = git.Repo(module_path(mod))
    return repo.git_dir, repo.head.commit.hexsha[:8]


def module_version(mod):
    '''Return version string for module *mod*, or nothing if
    it doesn't have a "version" or "__version__" attribute.'''
    version = []
    if hasattr(mod, '__dict__'):
        keys = []
        for key in mod.__dict__.keys():
            if key.lower() == 'version' or key.lower() == '__version__':
                v = mod.__dict__[key]
                if isinstance(v, string_types):
                    version.append(v)
        if keys:
            print(mod, keys)
    if version:
        return ', '.join(version)
    else:
        return ''

    
def find_loaded_modules(only_versioned_modules=True):
    '''Return list of loaded modules for which there is a version
    number or a Git repository commit SHA.
    
    Return a list of *(name, version, path_to_git_repo, git_head_sha)*,
    which has an HTML property for pretty display in IPython Notebooks.
        
    '''
    def list_of_lists_to_HTML(lists, header_row=None):
        '''Convert a list of a list of strings to a HTML table.'''
        s = '<table>'
        if header_row:
            s += '\n\t<tr>\n\t\t'
            s += ''.join(['<th>%s</th>' % item for item in header_row])
            s += '\n\t</tr>'
        for inner_list in lists:
            s += '\n\t<tr>\n\t\t'
            s += ''.join(['<td>%s</td>' % item for item in inner_list])
            s += '\n\t</tr>'
        s += '\n</table>'
        return s
    
    class LoadedModules(list):
        '''Very simple wrapper for a list of lists of strings, with an attribute
        for display in IPython Notebooks.'''
        def __init__(self, *args, **kwargs):
            list.__init__(self, *args, **kwargs)
            
        @property
        def HTML(self):
            from IPython.display import HTML
            return HTML(
                    list_of_lists_to_HTML(
                            self, header_row=['Name', 'Version', 'Path', 'SHA']))
                    
    objs = LoadedModules()
    for i, mod in enumerate(globals().values()):
        if isinstance(mod, types.ModuleType):
            if hasattr(mod, '__name__'):
                name = mod.__name__
            else:
                name = ''
            
            if from_git_repo(mod):
                path, sha = git_path_sha(mod)
            else:
                path = ''
                sha = ''
            
            version = module_version(mod)
            
            if only_versioned_modules:
                flag = version or (path and sha)
            else:
                flag = True
            
            if flag:
                objs.append([mod.__name__, version, path, sha])
    objs.sort(key=lambda r: r[0])
    return objs
    
    ```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment