Last active
June 3, 2020 13:05
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'''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 | |
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
Very nice code !