25
25
# debugging the configuration mechanisms you usually use to control debugging!
26
26
# This is a list of forced debugging options.
27
27
FORCED_DEBUG = []
28
+ FORCED_DEBUG_FILE = None
28
29
29
30
30
31
class DebugControl (object ):
@@ -189,11 +190,14 @@ def add_pid_and_tid(text):
189
190
190
191
class SimpleReprMixin (object ):
191
192
"""A mixin implementing a simple __repr__."""
193
+ simple_repr_ignore = ['simple_repr_ignore' , '$coverage.object_id' ]
194
+
192
195
def __repr__ (self ):
193
196
show_attrs = (
194
197
(k , v ) for k , v in self .__dict__ .items ()
195
198
if getattr (v , "show_repr_attr" , True )
196
199
and not callable (v )
200
+ and k not in self .simple_repr_ignore
197
201
)
198
202
return "<{klass} @0x{id:x} {attrs}>" .format (
199
203
klass = self .__class__ .__name__ ,
@@ -301,7 +305,7 @@ def get_one(cls, fileobj=None, show_process=True, filters=(), interim=False):
301
305
the_one , is_interim = sys .modules .get (cls .SYS_MOD_NAME , (None , True ))
302
306
if the_one is None or is_interim :
303
307
if fileobj is None :
304
- debug_file_name = os .environ .get ("COVERAGE_DEBUG_FILE" )
308
+ debug_file_name = os .environ .get ("COVERAGE_DEBUG_FILE" , FORCED_DEBUG_FILE )
305
309
if debug_file_name :
306
310
fileobj = open (debug_file_name , "a" )
307
311
else :
@@ -328,14 +332,18 @@ def log(msg, stack=False): # pragma: debugging
328
332
dump_stack_frames (out = out , skip = 1 )
329
333
330
334
331
- def decorate_methods (decorator , butnot = ()): # pragma: debugging
332
- """A class decorator to apply a decorator to public methods."""
335
+ def decorate_methods (decorator , butnot = (), private = False ): # pragma: debugging
336
+ """A class decorator to apply a decorator to methods."""
333
337
def _decorator (cls ):
334
338
for name , meth in inspect .getmembers (cls , inspect .isroutine ):
335
- public = name == '__init__' or not name .startswith ("_" )
336
- decorate_it = public and name not in butnot
337
- if decorate_it :
338
- setattr (cls , name , decorator (meth ))
339
+ if name not in cls .__dict__ :
340
+ continue
341
+ if name != "__init__" :
342
+ if not private and name .startswith ("_" ):
343
+ continue
344
+ if name in butnot :
345
+ continue
346
+ setattr (cls , name , decorator (meth ))
339
347
return cls
340
348
return _decorator
341
349
@@ -355,7 +363,7 @@ def _wrapper(*args, **kwargs):
355
363
CALLS = itertools .count ()
356
364
OBJ_ID_ATTR = "$coverage.object_id"
357
365
358
- def show_calls (show_args = True , show_stack = False ): # pragma: debugging
366
+ def show_calls (show_args = True , show_stack = False , show_return = False ): # pragma: debugging
359
367
"""A method decorator to debug-log each call to the function."""
360
368
def _decorator (func ):
361
369
@functools .wraps (func )
@@ -377,9 +385,14 @@ def _wrapper(self, *args, **kwargs):
377
385
if show_stack :
378
386
extra += " @ "
379
387
extra += "; " .join (_clean_stack_line (l ) for l in short_stack ().splitlines ())
380
- msg = "{} {:04d} {}{}\n " .format (oid , next (CALLS ), func .__name__ , extra )
388
+ callid = next (CALLS )
389
+ msg = "{} {:04d} {}{}\n " .format (oid , callid , func .__name__ , extra )
381
390
DebugOutputFile .get_one (interim = True ).write (msg )
382
- return func (self , * args , ** kwargs )
391
+ ret = func (self , * args , ** kwargs )
392
+ if show_return :
393
+ msg = "{} {:04d} {} return {!r}\n " .format (oid , callid , func .__name__ , ret )
394
+ DebugOutputFile .get_one (interim = True ).write (msg )
395
+ return ret
383
396
return _wrapper
384
397
return _decorator
385
398
0 commit comments