|
1 """Control of and utilities for debugging.""" |
|
2 |
|
3 import os |
|
4 |
|
5 |
|
6 # When debugging, it can be helpful to force some options, especially when |
|
7 # debugging the configuration mechanisms you usually use to control debugging! |
|
8 # This is a list of forced debugging options. |
|
9 FORCED_DEBUG = [] |
|
10 |
|
11 |
|
12 class DebugControl(object): |
|
13 """Control and output for debugging.""" |
|
14 |
|
15 def __init__(self, options, output): |
|
16 """Configure the options and output file for debugging.""" |
|
17 self.options = options |
|
18 self.output = output |
|
19 |
|
20 def should(self, option): |
|
21 """Decide whether to output debug information in category `option`.""" |
|
22 return (option in self.options or option in FORCED_DEBUG) |
|
23 |
|
24 def write(self, msg): |
|
25 """Write a line of debug output.""" |
|
26 if self.should('pid'): |
|
27 msg = "pid %5d: %s" % (os.getpid(), msg) |
|
28 self.output.write(msg+"\n") |
|
29 self.output.flush() |
|
30 |
|
31 def write_formatted_info(self, info): |
|
32 """Write a sequence of (label,data) pairs nicely.""" |
|
33 for line in info_formatter(info): |
|
34 self.write(" %s" % line) |
|
35 |
|
36 |
|
37 def info_formatter(info): |
|
38 """Produce a sequence of formatted lines from info. |
|
39 |
|
40 `info` is a sequence of pairs (label, data). The produced lines are |
|
41 nicely formatted, ready to print. |
|
42 |
|
43 """ |
|
44 label_len = max([len(l) for l, _d in info]) |
|
45 for label, data in info: |
|
46 if data == []: |
|
47 data = "-none-" |
|
48 if isinstance(data, (list, tuple)): |
|
49 prefix = "%*s:" % (label_len, label) |
|
50 for e in data: |
|
51 yield "%*s %s" % (label_len+1, prefix, e) |
|
52 prefix = "" |
|
53 else: |
|
54 yield "%*s: %s" % (label_len, label, data) |