Coverage for gws-app/gws/core/debug.py: 15%

112 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-17 01:37 +0200

1"""Debuggging tools""" 

2 

3import re 

4import socket 

5import sys 

6import time 

7import traceback 

8 

9from . import log 

10 

11 

12def inspect(arg, max_depth=1, all_props=False): 

13 """Inspect the argument upto the given depth""" 

14 

15 yield from _dump(arg, None, 0, max_depth or 1, all_props, []) 

16 

17 

18def p(*args, lines=False, stack=False, d=3, all=False): 

19 """Log an inspection of the arguments""" 

20 

21 sep = '-' * 60 

22 

23 if lines: 

24 for arg in args: 

25 for s in enumerate(str(arg).split('\n'), 1): 

26 log.debug('%06d:%s' % s, stacklevel=2) 

27 log.debug(sep, stacklevel=2) 

28 return 

29 

30 if stack: 

31 for s in traceback.format_stack()[:-1]: 

32 log.debug(s.replace('\n', ' '), stacklevel=2) 

33 return 

34 

35 for arg in args: 

36 for s in inspect(arg, max_depth=d, all_props=all): 

37 log.debug(s, stacklevel=2) 

38 log.debug(sep, stacklevel=2) 

39 

40 

41_TIME_STACK = [] 

42 

43 

44def time_start(label=None): 

45 _TIME_STACK.append((time.time(), label or 'default')) 

46 

47 

48def time_end(): 

49 if _TIME_STACK: 

50 t2 = time.time() 

51 t1, label = _TIME_STACK.pop() 

52 log.debug(f'@PROFILE {label} :: {t2 - t1:.2f}', stacklevel=2) 

53 

54 

55def pycharm_debugger_check(path_to_pycharm_debug_egg, host, port, suspend=False): 

56 """Check for pycharm debugger listeniing. 

57 

58 Attempt to open the debugger socket first and return that socket when pydevd asks for it. 

59 If there is no socket, then IDEA is not listening, return quickly. 

60 """ 

61 

62 sock = None 

63 try: 

64 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

65 sock.connect((host, port)) 

66 except: 

67 sock = None 

68 

69 if not sock: 

70 return False 

71 

72 if not path_to_pycharm_debug_egg.endswith('.egg'): 

73 if sys.version_info >= (3, 0): 

74 path_to_pycharm_debug_egg += '/pycharm-debug-py3k.egg' 

75 else: 

76 path_to_pycharm_debug_egg += '/pycharm-debug.egg' 

77 

78 sys.path.append(path_to_pycharm_debug_egg) 

79 pydevd = __import__('pydevd') 

80 

81 pydevd.StartClient = lambda h, p: sock 

82 pydevd.start_client = lambda h, p: sock 

83 pydevd.settrace(host, port=port, stdoutToServer=True, stderrToServer=True, suspend=suspend) 

84 

85 return True 

86 

87 

88## 

89 

90 

91_noexpand = { 

92 "<class 'datetime.datetime'>", 

93 "<class 'datetime.date'>", 

94 "<class 'memoryview'>", 

95} 

96 

97 

98def _should_list(k, v): 

99 if k.startswith('__'): 

100 return False 

101 if isinstance(v, type): 

102 return True 

103 if callable(v): 

104 return False 

105 return True 

106 

107 

108_MAX_REPR_LEN = 255 

109 

110 

111def _repr(x): 

112 s = repr(x) 

113 if len(s) > _MAX_REPR_LEN: 

114 s = s[:_MAX_REPR_LEN] + '...' 

115 return s 

116 

117 

118def _dump(x, name, depth, max_depth, all_props, seen): 

119 pfx = ' ' * depth 

120 

121 if name: 

122 pfx += str(name) + ': ' 

123 

124 t = str(type(x)) 

125 m = re.match(r"^<(type|class) '(.+?)'>", t) 

126 pfx += m.group(2) if m else t 

127 

128 try: 

129 pfx += '(%d)' % len(x) 

130 except (TypeError, AttributeError): 

131 pass 

132 

133 head = pfx + ' = ' + _repr(x) 

134 

135 if not x or isinstance(x, (bool, int, float, str, bytes)): 

136 yield head 

137 return 

138 

139 if not all_props and str(type(x)) in _noexpand: 

140 yield head 

141 return 

142 

143 try: 

144 if x in seen: 

145 yield head 

146 return 

147 seen.append(x) 

148 except: 

149 pass 

150 

151 if depth >= max_depth: 

152 yield pfx + '...' 

153 return 

154 

155 if isinstance(x, dict): 

156 yield pfx + ' = ' 

157 for k in x: 

158 yield from _dump(x[k], repr(k), depth + 1, max_depth, all_props, seen) 

159 return 

160 

161 if isinstance(x, (set, list, tuple)): 

162 yield pfx + ' = ' 

163 for k, v in enumerate(x): 

164 yield from _dump(v, str(k), depth + 1, max_depth, all_props, seen) 

165 return 

166 

167 yield head 

168 

169 for k in dir(x): 

170 try: 

171 v = getattr(x, k) 

172 except Exception as e: 

173 v = '?' + repr(e) 

174 if all_props or _should_list(k, v): 

175 yield from _dump(v, k, depth + 1, max_depth, all_props, seen)