Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from time import time 

2from sys import argv 

3from functools import wraps 

4from types import FunctionType 

5 

6 

7def set_debug(): 

8 """ 

9 Allow for setting debugging from the command line. 

10 

11 eg. ``--debug [ io core ]`` 

12 """ 

13 try: 

14 debug = argv.index("--debug") 

15 string = set([]) 

16 

17 try: 

18 start = argv.index("[") 

19 end = argv.index("]") 

20 string = {argv[i] for i in range(start + 1, end)} 

21 del argv[end] 

22 for i, j in enumerate(string): 

23 del argv[argv.index(j)] 

24 del argv[start] 

25 del argv[debug] 

26 except ValueError: 

27 del argv[debug] 

28 

29 WHAT_TO_DEBUG = string 

30 DBG = True 

31 except ValueError: 

32 if argv[0] == "Regtests.py": 

33 debug_v = input("Enter debugging variables:\n") 

34 WHAT_TO_DEBUG = set(debug_v.split()) 

35 DBG = True 

36 else: 

37 WHAT_TO_DEBUG = set([]) 

38 DBG = False 

39 

40 return WHAT_TO_DEBUG, DBG 

41 

42 

43class v_print(): 

44 """Debug printing.""" 

45 

46 def __init__(self, verbose): 

47 """Print switch.""" 

48 if verbose: 48 ↛ 49line 48 didn't jump to line 49, because the condition on line 48 was never true

49 self.print = self._print 

50 else: 

51 self.print = self._dont_print 

52 

53 @staticmethod 

54 def _print(*a, **k): 

55 return print(*a, **k) 

56 

57 @staticmethod 

58 def _dont_print(*a, **k): 

59 pass 

60 

61 

62WHAT_TO_DEBUG, DBG = set_debug() 

63 

64verb = v_print(DBG) 

65 

66 

67class debug: 

68 """ 

69 Debugging helper. 

70 

71 Aspects are provided as list of arguments which are decorators of the function to debug. 

72 

73 eg. ``set(['io','core'])`` 

74 

75 the flag TT will print out the run time for each function only 

76 

77 Inspiration from https://wiki.python.org/moin/PythonDecoratorLibrary#Controllable_DIY_debug 

78 

79 """ 

80 

81 def __init__(self, aspects=None): 

82 """Set __call__ to debug version if needed.""" 

83 if DBG: 

84 self.aspects = set(aspects) 

85 self.f_dict = {} 

86 setattr(debug, '__call__', self.dcall) 

87 self.call = self.dcall 

88 self.no_parallel = "--no-parallel" in argv 

89 

90 @staticmethod 

91 def __call__(f): 

92 """Do nothing if not in debugging mode.""" 

93 return f 

94 

95 def dcall(self, f): 

96 """ 

97 Wrap function to print debugging info. 

98 

99 Generically gives all wrapped class methods the DBG variable 

100 Can be used to carry out debugging methods (eg. if hasattr(self, "DBG"): ...) 

101 

102 If specifically selected with aspects, prints timing and/or arguments 

103 """ 

104 @wraps(f) 

105 def f_DBG(*args, **kwds): 

106 if f.__name__ == "__init__" and (hasattr(args[0], "__dict__") or hasattr(args[0], "__slots__")): 

107 args[0].DBG = True 

108 elif isinstance(f, FunctionType) and ((len(args) > 0 and not hasattr(args[0], "DBG")) or len(args) == 0): 

109 f_DBG.DBG = True 

110 return f(*args, **kwds) 

111 

112 if ((self.aspects & WHAT_TO_DEBUG) or ('all' in WHAT_TO_DEBUG)) and 'STEP_THROUGH' not in WHAT_TO_DEBUG: 

113 @wraps(f_DBG) 

114 def newf(*args, **kwds): 

115 # checks for self could be better? 

116 if "TT" not in WHAT_TO_DEBUG: 

117 print(f.__name__, args, kwds, [a.__dict__ for a in args if hasattr(a, '__dict__')]) 

118 

119 self.start_timer(f.__name__) 

120 

121 f_result = f_DBG(*args, **kwds) 

122 

123 timing(f.__name__, self.f_dict[f.__name__], f_result) 

124 

125 return f_result 

126 return newf 

127 

128 if ("STEP_THROUGH" in WHAT_TO_DEBUG) and (self.aspects & WHAT_TO_DEBUG): 128 ↛ 129line 128 didn't jump to line 129, because the condition on line 128 was never true

129 from numpy import ndarray 

130 @wraps(f_DBG) 

131 def stepthrough(*args, **kwds): 

132 print(f_DBG.__name__) 

133 print(*args[1:], **kwds) 

134 out = f_DBG(*args, **kwds) 

135 for i, j in out.items(): 

136 print(i) 

137 if isinstance(j, ndarray): 

138 for v in j: 

139 for vv in v: 

140 print(vv) 

141 else: 

142 print(j) 

143 if self.no_parallel: 

144 input() 

145 return out 

146 return stepthrough 

147 

148 return f_DBG 

149 

150 def start_timer(self, fname): 

151 """Start timer.""" 

152 if fname not in self.f_dict: 

153 self.f_dict[fname] = {"startf": time(), 'tt': 0} 

154 else: 

155 self.f_dict[fname]['startf'] = time() 

156 

157 

158def timing(name, f_dict, f_result=None): 

159 """ 

160 Time functions. 

161 

162 Get total run time of functions 

163 """ 

164 f_dict["endf"] = time() 

165 f_dict["step"] = f_dict["endf"] - f_dict["startf"] 

166 

167 f_dict["tt"] += f_dict["step"] 

168 

169 if f_result is None: 

170 print(name, "took {:13.5e}s total {:13.5e}s".format(f_dict[ 

171 "step"], f_dict["tt"])) 

172 else: 

173 print(name, "took {:13.5e}s total {:13.5e}s".format(f_dict[ 

174 "step"], f_dict["tt"]), "returned", f_result) 

175 

176 

177def profile(*args, file=None): 

178 """Profile code.""" 

179 from cProfile import Profile 

180 import pstats 

181 prof = Profile() 

182 out = prof.runcall(*args) # main, argparse, opts) calc.run, stat) 

183 pstats.Stats(prof).strip_dirs().dump_stats(file) 

184 return out 

185 

186 

187if __name__ == '__main__': 

188 pass