DebugClients/Python/coverage/misc.py

changeset 6219
d6c795b5ce33
parent 5178
878ce843ca9f
equal deleted inserted replaced
6218:bedab77d0fa3 6219:d6c795b5ce33
10 import os 10 import os
11 import sys 11 import sys
12 import types 12 import types
13 13
14 from coverage import env 14 from coverage import env
15 from coverage.backward import string_class, to_bytes, unicode_class 15 from coverage.backward import to_bytes, unicode_class
16 16
17 ISOLATED_MODULES = {} 17 ISOLATED_MODULES = {}
18 18
19 19
20 def isolate_module(mod): 20 def isolate_module(mod):
36 return ISOLATED_MODULES[mod] 36 return ISOLATED_MODULES[mod]
37 37
38 os = isolate_module(os) 38 os = isolate_module(os)
39 39
40 40
41 def dummy_decorator_with_args(*args_unused, **kwargs_unused):
42 """Dummy no-op implementation of a decorator with arguments."""
43 def _decorator(func):
44 return func
45 return _decorator
46
47
41 # Use PyContracts for assertion testing on parameters and returns, but only if 48 # Use PyContracts for assertion testing on parameters and returns, but only if
42 # we are running our own test suite. 49 # we are running our own test suite.
43 if env.TESTING: 50 if env.TESTING:
44 from contracts import contract # pylint: disable=unused-import 51 from contracts import contract # pylint: disable=unused-import
45 from contracts import new_contract as raw_new_contract 52 from contracts import new_contract as raw_new_contract
55 62
56 # Define contract words that PyContract doesn't have. 63 # Define contract words that PyContract doesn't have.
57 new_contract('bytes', lambda v: isinstance(v, bytes)) 64 new_contract('bytes', lambda v: isinstance(v, bytes))
58 if env.PY3: 65 if env.PY3:
59 new_contract('unicode', lambda v: isinstance(v, unicode_class)) 66 new_contract('unicode', lambda v: isinstance(v, unicode_class))
60 else: # pragma: not covered 67
61 # We aren't using real PyContracts, so just define a no-op decorator as a 68 def one_of(argnames):
62 # stunt double. 69 """Ensure that only one of the argnames is non-None."""
63 def contract(**unused): 70 def _decorator(func):
64 """Dummy no-op implementation of `contract`.""" 71 argnameset = set(name.strip() for name in argnames.split(","))
65 return lambda func: func 72 def _wrapped(*args, **kwargs):
73 vals = [kwargs.get(name) for name in argnameset]
74 assert sum(val is not None for val in vals) == 1
75 return func(*args, **kwargs)
76 return _wrapped
77 return _decorator
78 else: # pragma: not testing
79 # We aren't using real PyContracts, so just define our decorators as
80 # stunt-double no-ops.
81 contract = dummy_decorator_with_args
82 one_of = dummy_decorator_with_args
66 83
67 def new_contract(*args_unused, **kwargs_unused): 84 def new_contract(*args_unused, **kwargs_unused):
68 """Dummy no-op implementation of `new_contract`.""" 85 """Dummy no-op implementation of `new_contract`."""
69 pass 86 pass
70 87
91 even if there are gaps between statements. 108 even if there are gaps between statements.
92 109
93 For example, if `statements` is [1,2,3,4,5,10,11,12,13,14] and 110 For example, if `statements` is [1,2,3,4,5,10,11,12,13,14] and
94 `lines` is [1,2,5,10,11,13,14] then the result will be "1-2, 5-11, 13-14". 111 `lines` is [1,2,5,10,11,13,14] then the result will be "1-2, 5-11, 13-14".
95 112
96 """ 113 Both `lines` and `statements` can be any iterable. All of the elements of
97 pairs = [] 114 `lines` must be in `statements`, and all of the values must be positive
98 i = 0 115 integers.
99 j = 0 116
100 start = None 117 """
101 statements = sorted(statements) 118 statements = sorted(statements)
102 lines = sorted(lines) 119 lines = sorted(lines)
103 while i < len(statements) and j < len(lines): 120
104 if statements[i] == lines[j]: 121 pairs = []
105 if start is None: 122 start = None
106 start = lines[j] 123 lidx = 0
107 end = lines[j] 124 for stmt in statements:
108 j += 1 125 if lidx >= len(lines):
126 break
127 if stmt == lines[lidx]:
128 lidx += 1
129 if not start:
130 start = stmt
131 end = stmt
109 elif start: 132 elif start:
110 pairs.append((start, end)) 133 pairs.append((start, end))
111 start = None 134 start = None
112 i += 1
113 if start: 135 if start:
114 pairs.append((start, end)) 136 pairs.append((start, end))
115 ret = ', '.join(map(nice_pair, pairs)) 137 ret = ', '.join(map(nice_pair, pairs))
116 return ret 138 return ret
117 139
127 attr = "_once_" + fn.__name__ 149 attr = "_once_" + fn.__name__
128 150
129 def _wrapped(self): 151 def _wrapped(self):
130 """Inner function that checks the cache.""" 152 """Inner function that checks the cache."""
131 if hasattr(self, attr): 153 if hasattr(self, attr):
132 raise Exception("Shouldn't have called %s more than once" % fn.__name__) 154 raise AssertionError("Shouldn't have called %s more than once" % fn.__name__)
133 setattr(self, attr, True) 155 setattr(self, attr, True)
134 return fn(self) 156 return fn(self)
135 return _wrapped 157 return _wrapped
136 else: 158 else:
137 return fn 159 return fn # pragma: not testing
138 160
139 161
140 def bool_or_none(b): 162 def bool_or_none(b):
141 """Return bool(b), but preserve None.""" 163 """Return bool(b), but preserve None."""
142 if b is None: 164 if b is None:
177 self.md5 = hashlib.md5() 199 self.md5 = hashlib.md5()
178 200
179 def update(self, v): 201 def update(self, v):
180 """Add `v` to the hash, recursively if needed.""" 202 """Add `v` to the hash, recursively if needed."""
181 self.md5.update(to_bytes(str(type(v)))) 203 self.md5.update(to_bytes(str(type(v))))
182 if isinstance(v, string_class): 204 if isinstance(v, unicode_class):
183 self.md5.update(to_bytes(v)) 205 self.md5.update(v.encode('utf8'))
184 elif isinstance(v, bytes): 206 elif isinstance(v, bytes):
185 self.md5.update(v) 207 self.md5.update(v)
186 elif v is None: 208 elif v is None:
187 pass 209 pass
188 elif isinstance(v, (int, float)): 210 elif isinstance(v, (int, float)):
225 thing=thing, name=name, func_name=func_name 247 thing=thing, name=name, func_name=func_name
226 ) 248 )
227 ) 249 )
228 250
229 251
230 class CoverageException(Exception): 252 class SimpleRepr(object):
231 """An exception specific to coverage.py.""" 253 """A mixin implementing a simple __repr__."""
254 def __repr__(self):
255 return "<{klass} @{id:x} {attrs}>".format(
256 klass=self.__class__.__name__,
257 id=id(self) & 0xFFFFFF,
258 attrs=" ".join("{}={!r}".format(k, v) for k, v in self.__dict__.items()),
259 )
260
261
262 class BaseCoverageException(Exception):
263 """The base of all Coverage exceptions."""
264 pass
265
266
267 class CoverageException(BaseCoverageException):
268 """A run-of-the-mill exception specific to coverage.py."""
232 pass 269 pass
233 270
234 271
235 class NoSource(CoverageException): 272 class NoSource(CoverageException):
236 """We couldn't find the source for a module.""" 273 """We couldn't find the source for a module."""
252 289
253 Construct it with three arguments, the values from `sys.exc_info`. 290 Construct it with three arguments, the values from `sys.exc_info`.
254 291
255 """ 292 """
256 pass 293 pass
294
295
296 class StopEverything(BaseCoverageException):
297 """An exception that means everything should stop.
298
299 The CoverageTest class converts these to SkipTest, so that when running
300 tests, raising this exception will automatically skip the test.
301
302 """
303 pass

eric ide

mercurial