DebugClients/Python/coverage/misc.py

Sat, 31 Dec 2016 13:34:21 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 31 Dec 2016 13:34:21 +0100
changeset 5389
9b1c800daff3
parent 5178
878ce843ca9f
child 6219
d6c795b5ce33
permissions
-rw-r--r--

Updated copyright for 2017.

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
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
4 """Miscellaneous stuff for coverage.py."""
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
5
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
6 import errno
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
7 import hashlib
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
8 import inspect
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
9 import locale
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
10 import os
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
11 import sys
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
12 import types
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
13
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
14 from coverage import env
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
15 from coverage.backward import string_class, to_bytes, unicode_class
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
16
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
17 ISOLATED_MODULES = {}
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
18
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
19
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
20 def isolate_module(mod):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
21 """Copy a module so that we are isolated from aggressive mocking.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
22
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
23 If a test suite mocks os.path.exists (for example), and then we need to use
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
24 it during the test, everything will get tangled up if we use their mock.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
25 Making a copy of the module when we import it will isolate coverage.py from
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
26 those complications.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
27 """
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
28 if mod not in ISOLATED_MODULES:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
29 new_mod = types.ModuleType(mod.__name__)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
30 ISOLATED_MODULES[mod] = new_mod
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
31 for name in dir(mod):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
32 value = getattr(mod, name)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
33 if isinstance(value, types.ModuleType):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
34 value = isolate_module(value)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
35 setattr(new_mod, name, value)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
36 return ISOLATED_MODULES[mod]
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
37
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
38 os = isolate_module(os)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
39
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
40
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
41 # Use PyContracts for assertion testing on parameters and returns, but only if
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
42 # we are running our own test suite.
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
43 if env.TESTING:
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
44 from contracts import contract # pylint: disable=unused-import
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
45 from contracts import new_contract as raw_new_contract
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
46
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
47 def new_contract(*args, **kwargs):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
48 """A proxy for contracts.new_contract that doesn't mind happening twice."""
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
49 try:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
50 return raw_new_contract(*args, **kwargs)
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
51 except ValueError:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
52 # During meta-coverage, this module is imported twice, and
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
53 # PyContracts doesn't like redefining contracts. It's OK.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
54 pass
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
55
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
56 # Define contract words that PyContract doesn't have.
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
57 new_contract('bytes', lambda v: isinstance(v, bytes))
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
58 if env.PY3:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
59 new_contract('unicode', lambda v: isinstance(v, unicode_class))
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
60 else: # pragma: not covered
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
61 # We aren't using real PyContracts, so just define a no-op decorator as a
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
62 # stunt double.
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
63 def contract(**unused):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
64 """Dummy no-op implementation of `contract`."""
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
65 return lambda func: func
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
66
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
67 def new_contract(*args_unused, **kwargs_unused):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
68 """Dummy no-op implementation of `new_contract`."""
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
69 pass
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
70
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
71
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
72 def nice_pair(pair):
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
73 """Make a nice string representation of a pair of numbers.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
74
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
75 If the numbers are equal, just return the number, otherwise return the pair
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
76 with a dash between them, indicating the range.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
77
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
78 """
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
79 start, end = pair
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
80 if start == end:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
81 return "%d" % start
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
82 else:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
83 return "%d-%d" % (start, end)
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
84
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
85
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
86 def format_lines(statements, lines):
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
87 """Nicely format a list of line numbers.
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
88
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
89 Format a list of line numbers for printing by coalescing groups of lines as
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
90 long as the lines represent consecutive statements. This will coalesce
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
91 even if there are gaps between statements.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
92
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
93 For example, if `statements` is [1,2,3,4,5,10,11,12,13,14] and
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
94 `lines` is [1,2,5,10,11,13,14] then the result will be "1-2, 5-11, 13-14".
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
95
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
96 """
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
97 pairs = []
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
98 i = 0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
99 j = 0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
100 start = None
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
101 statements = sorted(statements)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
102 lines = sorted(lines)
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
103 while i < len(statements) and j < len(lines):
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
104 if statements[i] == lines[j]:
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
105 if start is None:
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
106 start = lines[j]
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
107 end = lines[j]
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
108 j += 1
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
109 elif start:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
110 pairs.append((start, end))
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
111 start = None
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
112 i += 1
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
113 if start:
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
114 pairs.append((start, end))
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
115 ret = ', '.join(map(nice_pair, pairs))
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
116 return ret
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
117
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
118
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
119 def expensive(fn):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
120 """A decorator to indicate that a method shouldn't be called more than once.
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
121
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
122 Normally, this does nothing. During testing, this raises an exception if
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
123 called more than once.
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
124
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
125 """
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
126 if env.TESTING:
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
127 attr = "_once_" + fn.__name__
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
128
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
129 def _wrapped(self):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
130 """Inner function that checks the cache."""
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
131 if hasattr(self, attr):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
132 raise Exception("Shouldn't have called %s more than once" % fn.__name__)
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
133 setattr(self, attr, True)
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
134 return fn(self)
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
135 return _wrapped
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
136 else:
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
137 return fn
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
138
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
139
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
140 def bool_or_none(b):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
141 """Return bool(b), but preserve None."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
142 if b is None:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
143 return None
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
144 else:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
145 return bool(b)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
146
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
147
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
148 def join_regex(regexes):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
149 """Combine a list of regexes into one that matches any of them."""
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
150 return "|".join("(?:%s)" % r for r in regexes)
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
151
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
152
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
153 def file_be_gone(path):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
154 """Remove a file, and don't get annoyed if it doesn't exist."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
155 try:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
156 os.remove(path)
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
157 except OSError as e:
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
158 if e.errno != errno.ENOENT:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
159 raise
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
160
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
161
5051
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
162 def output_encoding(outfile=None):
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
163 """Determine the encoding to use for output written to `outfile` or stdout."""
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
164 if outfile is None:
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
165 outfile = sys.stdout
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
166 encoding = (
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
167 getattr(outfile, "encoding", None) or
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
168 getattr(sys.__stdout__, "encoding", None) or
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
169 locale.getpreferredencoding()
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
170 )
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
171 return encoding
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
172
3586ebd9fac8 Updated coverage.py to version 4.1.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 4489
diff changeset
173
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
174 class Hasher(object):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
175 """Hashes Python data into md5."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
176 def __init__(self):
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
177 self.md5 = hashlib.md5()
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
178
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
179 def update(self, v):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
180 """Add `v` to the hash, recursively if needed."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
181 self.md5.update(to_bytes(str(type(v))))
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
182 if isinstance(v, string_class):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
183 self.md5.update(to_bytes(v))
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
184 elif isinstance(v, bytes):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
185 self.md5.update(v)
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
186 elif v is None:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
187 pass
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
188 elif isinstance(v, (int, float)):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
189 self.md5.update(to_bytes(str(v)))
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
190 elif isinstance(v, (tuple, list)):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
191 for e in v:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
192 self.update(e)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
193 elif isinstance(v, dict):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
194 keys = v.keys()
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
195 for k in sorted(keys):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
196 self.update(k)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
197 self.update(v[k])
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
198 else:
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
199 for k in dir(v):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
200 if k.startswith('__'):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
201 continue
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
202 a = getattr(v, k)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
203 if inspect.isroutine(a):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
204 continue
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
205 self.update(k)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
206 self.update(a)
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
207
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
208 def hexdigest(self):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
209 """Retrieve the hex digest of the hash."""
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
210 return self.md5.hexdigest()
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
211
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
212
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
213 def _needs_to_implement(that, func_name):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
214 """Helper to raise NotImplementedError in interface stubs."""
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
215 if hasattr(that, "_coverage_plugin_name"):
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
216 thing = "Plugin"
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
217 name = that._coverage_plugin_name
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
218 else:
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
219 thing = "Class"
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
220 klass = that.__class__
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
221 name = "{klass.__module__}.{klass.__name__}".format(klass=klass)
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
222
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
223 raise NotImplementedError(
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
224 "{thing} {name!r} needs to implement {func_name}()".format(
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
225 thing=thing, name=name, func_name=func_name
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
226 )
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
227 )
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
228
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
229
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
230 class CoverageException(Exception):
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
231 """An exception specific to coverage.py."""
0
de9c2efb9d02 Started porting eric4 to Python3
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff changeset
232 pass
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
233
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
234
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
235 class NoSource(CoverageException):
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
236 """We couldn't find the source for a module."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
237 pass
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
238
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
239
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
240 class NoCode(NoSource):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
241 """We couldn't find any code at all."""
29
391dc0bc4ae5 Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents: 0
diff changeset
242 pass
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
243
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
244
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
245 class NotPython(CoverageException):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
246 """A source file turned out not to be parsable Python."""
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
247 pass
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
248
4489
d0d6e4ad31bd Updated coverage to 4.0 (breaks with Python 3.2 support).
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 3495
diff changeset
249
3495
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
250 class ExceptionDuringRun(CoverageException):
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
251 """An exception happened while running customer code.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
252
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
253 Construct it with three arguments, the values from `sys.exc_info`.
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
254
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
255 """
fac17a82b431 updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents: 29
diff changeset
256 pass

eric ide

mercurial