Source code for mango.debug

from time import time
from sys import argv
from functools import wraps
from types import FunctionType


[docs]def set_debug(): """ Allow for setting debugging from the command line. eg. ``--debug [ io core ]`` """ try: debug = argv.index("--debug") string = set([]) try: start = argv.index("[") end = argv.index("]") string = {argv[i] for i in range(start + 1, end)} del argv[end] for i, j in enumerate(string): del argv[argv.index(j)] del argv[start] del argv[debug] except ValueError: del argv[debug] WHAT_TO_DEBUG = string DBG = True except ValueError: if argv[0] == "Regtests.py": debug_v = input("Enter debugging variables:\n") WHAT_TO_DEBUG = set(debug_v.split()) DBG = True else: WHAT_TO_DEBUG = set([]) DBG = False return WHAT_TO_DEBUG, DBG
[docs]class v_print(): """Debug printing.""" def __init__(self, verbose): """Print switch.""" if verbose: self.print = self._print else: self.print = self._dont_print @staticmethod def _print(*a, **k): return print(*a, **k) @staticmethod def _dont_print(*a, **k): pass
WHAT_TO_DEBUG, DBG = set_debug() verb = v_print(DBG)
[docs]class debug: """ Debugging helper. Aspects are provided as list of arguments which are decorators of the function to debug. eg. ``set(['io','core'])`` the flag TT will print out the run time for each function only Inspiration from https://wiki.python.org/moin/PythonDecoratorLibrary#Controllable_DIY_debug """ def __init__(self, aspects=None): """Set __call__ to debug version if needed.""" if DBG: self.aspects = set(aspects) self.f_dict = {} setattr(debug, '__call__', self.dcall) self.call = self.dcall self.no_parallel = "--no-parallel" in argv @staticmethod def __call__(f): """Do nothing if not in debugging mode.""" return f
[docs] def dcall(self, f): """ Wrap function to print debugging info. Generically gives all wrapped class methods the DBG variable Can be used to carry out debugging methods (eg. if hasattr(self, "DBG"): ...) If specifically selected with aspects, prints timing and/or arguments """ @wraps(f) def f_DBG(*args, **kwds): if f.__name__ == "__init__" and (hasattr(args[0], "__dict__") or hasattr(args[0], "__slots__")): args[0].DBG = True elif isinstance(f, FunctionType) and ((len(args) > 0 and not hasattr(args[0], "DBG")) or len(args) == 0): f_DBG.DBG = True return f(*args, **kwds) if ((self.aspects & WHAT_TO_DEBUG) or ('all' in WHAT_TO_DEBUG)) and 'STEP_THROUGH' not in WHAT_TO_DEBUG: @wraps(f_DBG) def newf(*args, **kwds): # checks for self could be better? if "TT" not in WHAT_TO_DEBUG: print(f.__name__, args, kwds, [a.__dict__ for a in args if hasattr(a, '__dict__')]) self.start_timer(f.__name__) f_result = f_DBG(*args, **kwds) timing(f.__name__, self.f_dict[f.__name__], f_result) return f_result return newf if ("STEP_THROUGH" in WHAT_TO_DEBUG) and (self.aspects & WHAT_TO_DEBUG): from numpy import ndarray @wraps(f_DBG) def stepthrough(*args, **kwds): print(f_DBG.__name__) print(*args[1:], **kwds) out = f_DBG(*args, **kwds) for i, j in out.items(): print(i) if isinstance(j, ndarray): for v in j: for vv in v: print(vv) else: print(j) if self.no_parallel: input() return out return stepthrough return f_DBG
[docs] def start_timer(self, fname): """Start timer.""" if fname not in self.f_dict: self.f_dict[fname] = {"startf": time(), 'tt': 0} else: self.f_dict[fname]['startf'] = time()
[docs]def timing(name, f_dict, f_result=None): """ Time functions. Get total run time of functions """ f_dict["endf"] = time() f_dict["step"] = f_dict["endf"] - f_dict["startf"] f_dict["tt"] += f_dict["step"] if f_result is None: print(name, "took {:13.5e}s total {:13.5e}s".format(f_dict[ "step"], f_dict["tt"])) else: print(name, "took {:13.5e}s total {:13.5e}s".format(f_dict[ "step"], f_dict["tt"]), "returned", f_result)
[docs]def profile(*args, file=None): """Profile code.""" from cProfile import Profile import pstats prof = Profile() out = prof.runcall(*args) # main, argparse, opts) calc.run, stat) pstats.Stats(prof).strip_dirs().dump_stats(file) return out
if __name__ == '__main__': pass