summaryrefslogtreecommitdiff
path: root/bootstrap.py
diff options
context:
space:
mode:
Diffstat (limited to 'bootstrap.py')
-rw-r--r--bootstrap.py64
1 files changed, 64 insertions, 0 deletions
diff --git a/bootstrap.py b/bootstrap.py
new file mode 100644
index 0000000..d1233e9
--- /dev/null
+++ b/bootstrap.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+
+import functools
+import logging
+import os
+import sys
+import time
+import traceback
+
+import argparse_utils
+import config
+import logging_utils
+
+
+logger = logging.getLogger(__name__)
+
+args = config.add_commandline_args(
+ f'Bootstrap ({__file__})',
+ 'Args related to python program bootstrapper and Swiss army knife')
+args.add_argument(
+ '--debug_unhandled_exceptions',
+ action=argparse_utils.ActionNoYes,
+ default=False,
+ help='Break into debugger on top level unhandled exceptions for interactive debugging'
+)
+
+
+def handle_uncaught_exception(
+ exc_type,
+ exc_value,
+ exc_traceback):
+ if issubclass(exc_type, KeyboardInterrupt):
+ sys.__excepthook__(exc_type, exc_value, exc_traceback)
+ return
+ logger.exception(f'Unhandled top level {exc_type}',
+ exc_info=(exc_type, exc_value, exc_traceback))
+ traceback.print_exception(exc_type, exc_value, exc_traceback)
+ if config.config['debug_unhandled_exceptions']:
+ logger.info("Invoking the debugger...")
+ breakpoint()
+
+
+def initialize(funct):
+ """Remember to initialize config and logging before running main."""
+ @functools.wraps(funct)
+ def initialize_wrapper(*args, **kwargs):
+ sys.excepthook = handle_uncaught_exception
+ config.parse()
+ logging_utils.initialize_logging(logging.getLogger())
+ logger.debug(f"About to invoke {funct}...")
+ start = time.perf_counter()
+ ret = funct(*args, **kwargs)
+ end = time.perf_counter()
+ logger.debug(f'{funct} returned {ret}.')
+ (utime, stime, cutime, cstime, elapsed_time) = os.times()
+ logger.debug(f'\nuser: {utime}s\n'
+ f'system: {stime}s\n'
+ f'child user: {cutime}s\n'
+ f'child system: {cstime}s\n'
+ f'elapsed: {elapsed_time}s\n'
+ f'walltime: {end - start}s\n')
+ logger.info(f'Exit {ret}')
+ sys.exit(ret)
+ return initialize_wrapper