DebugClients/Python/coverage/debug.py

Sat, 25 Feb 2017 21:17:56 +0100

author
T.Rzepka <Tobias.Rzepka@gmail.com>
date
Sat, 25 Feb 2017 21:17:56 +0100
branch
debugger fine grinding
changeset 5561
5fffb5cc1a88
parent 5178
878ce843ca9f
child 6219
d6c795b5ce33
permissions
-rw-r--r--

When in unhandled exception, current frame lies in debugger files always. In breakpoints,
you won't see the correct frame in this case.

4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
2 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
3
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
4 """Control of and utilities for debugging."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
5
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
6 import inspect
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
7 import os
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
8 import sys
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
9
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
10 from coverage.misc import isolate_module
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
11
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
12 os = isolate_module(os)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
13
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
14
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
15 # When debugging, it can be helpful to force some options, especially when
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
16 # debugging the configuration mechanisms you usually use to control debugging!
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
17 # This is a list of forced debugging options.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
18 FORCED_DEBUG = []
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
19
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
20 # A hack for debugging testing in sub-processes.
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
21 _TEST_NAME_FILE = "" # "/tmp/covtest.txt"
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
22
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
23
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
24 class DebugControl(object):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
25 """Control and output for debugging."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
26
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
27 def __init__(self, options, output):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
28 """Configure the options and output file for debugging."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
29 self.options = options
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
30 self.output = output
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
31
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
32 def __repr__(self):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
33 return "<DebugControl options=%r output=%r>" % (self.options, self.output)
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
34
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
35 def should(self, option):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
36 """Decide whether to output debug information in category `option`."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
37 return (option in self.options or option in FORCED_DEBUG)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
38
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
39 def write(self, msg):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
40 """Write a line of debug output."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
41 if self.should('pid'):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
42 msg = "pid %5d: %s" % (os.getpid(), msg)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
43 self.output.write(msg+"\n")
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
44 if self.should('callers'):
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
45 dump_stack_frames(out=self.output)
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
46 self.output.flush()
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
47
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
48 def write_formatted_info(self, header, info):
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
49 """Write a sequence of (label,data) pairs nicely."""
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
50 self.write(info_header(header))
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
51 for line in info_formatter(info):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
52 self.write(" %s" % line)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
53
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
54
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
55 def info_header(label):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
56 """Make a nice header string."""
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
57 return "--{0:-<60s}".format(" "+label+" ")
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
58
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
59
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
60 def info_formatter(info):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
61 """Produce a sequence of formatted lines from info.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
62
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
63 `info` is a sequence of pairs (label, data). The produced lines are
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
64 nicely formatted, ready to print.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
65
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
66 """
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
67 info = list(info)
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
68 if not info:
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
69 return
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
70 label_len = max(len(l) for l, _d in info)
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
71 for label, data in info:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
72 if data == []:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
73 data = "-none-"
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
74 if isinstance(data, (list, set, tuple)):
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
75 prefix = "%*s:" % (label_len, label)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
76 for e in data:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
77 yield "%*s %s" % (label_len+1, prefix, e)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
78 prefix = ""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
79 else:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
80 yield "%*s: %s" % (label_len, label, data)
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
81
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
82
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
83 def short_stack(limit=None): # pragma: debugging
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
84 """Return a string summarizing the call stack.
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
85
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
86 The string is multi-line, with one line per stack frame. Each line shows
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
87 the function name, the file name, and the line number:
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
88
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
89 ...
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
90 start_import_stop : /Users/ned/coverage/trunk/tests/coveragetest.py @95
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
91 import_local_file : /Users/ned/coverage/trunk/tests/coveragetest.py @81
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
92 import_local_file : /Users/ned/coverage/trunk/coverage/backward.py @159
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
93 ...
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
94
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
95 `limit` is the number of frames to include, defaulting to all of them.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
96
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
97 """
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
98 stack = inspect.stack()[limit:0:-1]
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
99 return "\n".join("%30s : %s @%d" % (t[3], t[1], t[2]) for t in stack)
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
100
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
101
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
102 def dump_stack_frames(limit=None, out=None): # pragma: debugging
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
103 """Print a summary of the stack to stdout, or some place else."""
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
104 out = out or sys.stdout
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
105 out.write(short_stack(limit=limit))
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
106 out.write("\n")

eric ide

mercurial