X-Git-Url: https://wannabe.guru.org/gitweb/?a=blobdiff_plain;f=bootstrap.py;h=50af84407f57e504632e868a1b1e2de32a19a671;hb=e76081ebdfa078aa8508ba1682dacea80341157e;hp=35747865b7aacc38fa61f6005af6c5bd5833ff69;hpb=5c212d7639f62fcb936f9d7a0bbe704a9f7b213d;p=python_utils.git diff --git a/bootstrap.py b/bootstrap.py index 3574786..50af844 100644 --- a/bootstrap.py +++ b/bootstrap.py @@ -1,5 +1,11 @@ #!/usr/bin/env python3 +"""This is a module for wrapping around python programs and doing some +minor setup and tear down work for them. With it, you can break into +pdb on unhandled top level exceptions, profile your code by passing a +commandline argument in, audit module import events, examine where +memory is being used in your program, and so on.""" + import functools import importlib import logging @@ -101,6 +107,15 @@ def handle_uncaught_exception(exc_type, exc_value, exc_tb): class ImportInterceptor(importlib.abc.MetaPathFinder): + """An interceptor that always allows module load events but dumps a + record into the log and onto stdout when modules are loaded and + produces an audit of who imported what at the end of the run. It + can't see any load events that happen before it, though, so move + bootstrap up in your __main__'s import list just temporarily to + get a good view. + + """ + def __init__(self): import collect.trie @@ -111,9 +126,9 @@ class ImportInterceptor(importlib.abc.MetaPathFinder): def repopulate_modules_by_filename(self): self.module_by_filename_cache.clear() - for mod in sys.modules: - if hasattr(sys.modules[mod], '__file__'): - fname = getattr(sys.modules[mod], '__file__') + for _, mod in sys.modules.copy().items(): # copy here because modules is volatile + if hasattr(mod, '__file__'): + fname = getattr(mod, '__file__') else: fname = 'unknown' self.module_by_filename_cache[fname] = mod @@ -243,8 +258,7 @@ def initialize(entry_point): # Maybe log some info about the python interpreter itself. logger.debug( - 'Platform: %s, maxint=0x%x, byteorder=%s', - sys.platform, sys.maxsize, sys.byteorder + 'Platform: %s, maxint=0x%x, byteorder=%s', sys.platform, sys.maxsize, sys.byteorder ) logger.debug('Python interpreter version: %s', sys.version) logger.debug('Python implementation: %s', sys.implementation) @@ -320,7 +334,12 @@ def initialize(entry_point): 'child system: %.4fs\n' 'machine uptime: %.4fs\n' 'walltime: %.4fs', - utime, stime, cutime, cstime, elapsed_time, walltime + utime, + stime, + cutime, + cstime, + elapsed_time, + walltime, ) # If it doesn't return cleanly, call attention to the return value.