def do_debug(self, args): """Implementation of 'coverage debug'.""" if not args: show_help( "What information would you like: config, data, sys, premain, pybehave?" ) return ERR if args[1:]: show_help("Only one topic at a time, please") return ERR if args[0] == "sys": write_formatted_info(print, "sys", self.coverage.sys_info()) elif args[0] == "data": print(info_header("data")) data_file = self.coverage.config.data_file debug_data_file(data_file) for filename in combinable_files(data_file): print("-----") debug_data_file(filename) elif args[0] == "config": write_formatted_info(print, "config", self.coverage.config.debug_info()) elif args[0] == "premain": print(info_header("premain")) print(short_stack()) elif args[0] == "pybehave": write_formatted_info(print, "pybehave", env.debug_info()) else: show_help(f"Don't know what you mean by {args[0]!r}") return ERR return OK
def add_arc(self, start, end, smsg=None, emsg=None): if self.debug: print("\nAdding arc: ({}, {}): {!r}, {!r}".format(start, end, smsg, emsg)) print(short_stack(limit=6)) self.arcs.add((start, end)) if smsg is not None or emsg is not None: self.missing_arc_fragments[(start, end)].append((smsg, emsg))
def add_arc(self, start, end, smsg=None, emsg=None): """Add an arc, including message fragments to use if it is missing.""" if self.debug: print("\nAdding arc: ({}, {}): {!r}, {!r}".format(start, end, smsg, emsg)) print(short_stack(limit=6)) self.arcs.add((start, end)) if smsg is not None or emsg is not None: self.missing_arc_fragments[(start, end)].append((smsg, emsg))
def add_arc(self, start, end, smsg=None, emsg=None): """Add an arc, including message fragments to use if it is missing.""" if self.debug: # pragma: debugging print("\nAdding arc: ({}, {}): {!r}, {!r}".format(start, end, smsg, emsg)) print(short_stack(limit=6)) self.arcs.add((start, end)) if smsg is not None or emsg is not None: self.missing_arc_fragments[(start, end)].append((smsg, emsg))
def _post_init(self): """Stuff to do after everything is initialized.""" if self._should_write_debug: self._should_write_debug = False self._write_startup_debug() # '[run] _crash' will raise an exception if the value is close by in # the call stack, for testing error handling. if self.config._crash and self.config._crash in short_stack(limit=4): raise Exception("Crashing because called by {}".format(self.config._crash))
def do_debug(self, args): """Implementation of 'coverage debug'.""" if not args: show_help( "What information would you like: config, data, sys, premain?") return ERR for info in args: if info == 'sys': sys_info = self.coverage.sys_info() print(info_header("sys")) for line in info_formatter(sys_info): print(" %s" % line) elif info == 'data': self.coverage.load() data = self.coverage.get_data() print(info_header("data")) print("path: %s" % self.coverage.get_data().data_filename()) if data: print("has_arcs: %r" % data.has_arcs()) summary = line_counts(data, fullpath=True) filenames = sorted(summary.keys()) print("\n%d files:" % len(filenames)) for f in filenames: line = "%s: %d lines" % (f, summary[f]) plugin = data.file_tracer(f) if plugin: line += " [%s]" % plugin print(line) else: print("No data collected") elif info == 'config': print(info_header("config")) config_info = self.coverage.config.__dict__.items() for line in info_formatter(config_info): print(" %s" % line) elif info == "premain": print(info_header("premain")) from coverage.debug import short_stack print(short_stack()) else: show_help("Don't know what you mean by %r" % info) return ERR return OK
def do_debug(self, args): """Implementation of 'coverage debug'.""" if not args: show_help( "What information would you like: config, data, sys, premain?") return ERR for info in args: if info == 'sys': sys_info = self.coverage.sys_info() print(info_header("sys")) for line in info_formatter(sys_info): print(f" {line}") elif info == 'data': self.coverage.load() data = self.coverage.get_data() print(info_header("data")) print(f"path: {data.data_filename()}") if data: print(f"has_arcs: {data.has_arcs()!r}") summary = line_counts(data, fullpath=True) filenames = human_sorted(summary.keys()) print(f"\n{len(filenames)} files:") for f in filenames: line = f"{f}: {summary[f]} lines" plugin = data.file_tracer(f) if plugin: line += f" [{plugin}]" print(line) else: print("No data collected") elif info == 'config': print(info_header("config")) config_info = self.coverage.config.__dict__.items() for line in info_formatter(config_info): print(f" {line}") elif info == "premain": print(info_header("premain")) print(short_stack()) else: show_help(f"Don't know what you mean by {info!r}") return ERR return OK
def __init__(self, should_trace, check_include, timid, branch, warn, concurrency): """Create a collector. `should_trace` is a function, taking a file name and a frame, and returning a `coverage.FileDisposition object`. `check_include` is a function taking a file name and a frame. It returns a boolean: True if the file should be traced, False if not. If `timid` is true, then a slower simpler trace function will be used. This is important for some environments where manipulation of tracing functions make the faster more sophisticated trace function not operate properly. If `branch` is true, then branches will be measured. This involves collecting data on which statements followed each other (arcs). Use `get_arc_data` to get the arc data. `warn` is a warning function, taking a single string message argument and an optional slug argument which will be a string or None, to be used if a warning needs to be issued. `concurrency` is a list of strings indicating the concurrency libraries in use. Valid values are "greenlet", "eventlet", "gevent", or "thread" (the default). Of these four values, only one can be supplied. Other values are ignored. """ self.should_trace = should_trace self.check_include = check_include self.warn = warn self.branch = branch self.threading = None self.origin = short_stack() self.concur_id_func = None # We can handle a few concurrency options here, but only one at a time. these_concurrencies = self.SUPPORTED_CONCURRENCIES.intersection( concurrency) if len(these_concurrencies) > 1: raise CoverageException("Conflicting concurrency settings: %s" % concurrency) self.concurrency = these_concurrencies.pop( ) if these_concurrencies else '' try: if self.concurrency == "greenlet": import greenlet self.concur_id_func = greenlet.getcurrent elif self.concurrency == "eventlet": import eventlet.greenthread # pylint: disable=import-error,useless-suppression self.concur_id_func = eventlet.greenthread.getcurrent elif self.concurrency == "gevent": import gevent # pylint: disable=import-error,useless-suppression self.concur_id_func = gevent.getcurrent elif self.concurrency == "thread" or not self.concurrency: # It's important to import threading only if we need it. If # it's imported early, and the program being measured uses # gevent, then gevent's monkey-patching won't work properly. import threading self.threading = threading else: raise CoverageException("Don't understand concurrency=%s" % concurrency) except ImportError: raise CoverageException( "Couldn't trace with concurrency=%s, the module isn't installed." % (self.concurrency, )) # Who-Tests-What is just a hack at the moment, so turn it on with an # environment variable. self.wtw = int(os.getenv('COVERAGE_WTW', 0)) self.reset() if timid: # Being timid: use the simple Python trace function. self._trace_class = PyTracer else: # Being fast: use the C Tracer if it is available, else the Python # trace function. self._trace_class = CTracer or PyTracer if self._trace_class is CTracer: self.file_disposition_class = CFileDisposition self.supports_plugins = True else: self.file_disposition_class = FileDisposition self.supports_plugins = False
def f_three(*args, **kwargs): """Third of the chain of functions for testing `short_stack`.""" return short_stack(*args, **kwargs)
def __init__(self, should_trace, check_include, timid, branch, warn, concurrency): """Create a collector. `should_trace` is a function, taking a file name and a frame, and returning a `coverage.FileDisposition object`. `check_include` is a function taking a file name and a frame. It returns a boolean: True if the file should be traced, False if not. If `timid` is true, then a slower simpler trace function will be used. This is important for some environments where manipulation of tracing functions make the faster more sophisticated trace function not operate properly. If `branch` is true, then branches will be measured. This involves collecting data on which statements followed each other (arcs). Use `get_arc_data` to get the arc data. `warn` is a warning function, taking a single string message argument and an optional slug argument which will be a string or None, to be used if a warning needs to be issued. `concurrency` is a list of strings indicating the concurrency libraries in use. Valid values are "greenlet", "eventlet", "gevent", or "thread" (the default). Of these four values, only one can be supplied. Other values are ignored. """ self.should_trace = should_trace self.check_include = check_include self.warn = warn self.branch = branch self.threading = None self.origin = short_stack() self.concur_id_func = None # We can handle a few concurrency options here, but only one at a time. these_concurrencies = self.SUPPORTED_CONCURRENCIES.intersection(concurrency) if len(these_concurrencies) > 1: raise CoverageException("Conflicting concurrency settings: %s" % concurrency) self.concurrency = these_concurrencies.pop() if these_concurrencies else '' try: if self.concurrency == "greenlet": import greenlet self.concur_id_func = greenlet.getcurrent elif self.concurrency == "eventlet": import eventlet.greenthread # pylint: disable=import-error,useless-suppression self.concur_id_func = eventlet.greenthread.getcurrent elif self.concurrency == "gevent": import gevent # pylint: disable=import-error,useless-suppression self.concur_id_func = gevent.getcurrent elif self.concurrency == "thread" or not self.concurrency: # It's important to import threading only if we need it. If # it's imported early, and the program being measured uses # gevent, then gevent's monkey-patching won't work properly. import threading self.threading = threading else: raise CoverageException("Don't understand concurrency=%s" % concurrency) except ImportError: raise CoverageException( "Couldn't trace with concurrency=%s, the module isn't installed." % ( self.concurrency, ) ) # Who-Tests-What is just a hack at the moment, so turn it on with an # environment variable. self.wtw = int(os.getenv('COVERAGE_WTW', 0)) self.reset() if timid: # Being timid: use the simple Python trace function. self._trace_class = PyTracer else: # Being fast: use the C Tracer if it is available, else the Python # trace function. self._trace_class = CTracer or PyTracer if self._trace_class is CTracer: self.file_disposition_class = CFileDisposition self.supports_plugins = True else: self.file_disposition_class = FileDisposition self.supports_plugins = False
def add(self, arc): """set.add, but with a stack trace.""" from coverage.debug import short_stack print("\nAdding arc: {}".format(arc)) print(short_stack(limit=6)) self.the_set.add(arc)
def __init__( self, should_trace, check_include, should_start_context, file_mapper, timid, branch, warn, concurrency, ): """Create a collector. `should_trace` is a function, taking a file name and a frame, and returning a `coverage.FileDisposition object`. `check_include` is a function taking a file name and a frame. It returns a boolean: True if the file should be traced, False if not. `should_start_context` is a function taking a frame, and returning a string. If the frame should be the start of a new context, the string is the new context. If the frame should not be the start of a new context, return None. `file_mapper` is a function taking a filename, and returning a Unicode filename. The result is the name that will be recorded in the data file. If `timid` is true, then a slower simpler trace function will be used. This is important for some environments where manipulation of tracing functions make the faster more sophisticated trace function not operate properly. If `branch` is true, then branches will be measured. This involves collecting data on which statements followed each other (arcs). Use `get_arc_data` to get the arc data. `warn` is a warning function, taking a single string message argument and an optional slug argument which will be a string or None, to be used if a warning needs to be issued. `concurrency` is a list of strings indicating the concurrency libraries in use. Valid values are "greenlet", "eventlet", "gevent", or "thread" (the default). "thread" can be combined with one of the other three. Other values are ignored. """ self.should_trace = should_trace self.check_include = check_include self.should_start_context = should_start_context self.file_mapper = file_mapper self.branch = branch self.warn = warn self.concurrency = concurrency assert isinstance(self.concurrency, list), f"Expected a list: {self.concurrency!r}" self.threading = None self.covdata = None self.static_context = None self.origin = short_stack() self.concur_id_func = None self.mapped_file_cache = {} if timid: # Being timid: use the simple Python trace function. self._trace_class = PyTracer else: # Being fast: use the C Tracer if it is available, else the Python # trace function. self._trace_class = CTracer or PyTracer if self._trace_class is CTracer: self.file_disposition_class = CFileDisposition self.supports_plugins = True self.packed_arcs = True else: self.file_disposition_class = FileDisposition self.supports_plugins = False self.packed_arcs = False # We can handle a few concurrency options here, but only one at a time. concurrencies = set(self.concurrency) unknown = concurrencies - CoverageConfig.CONCURRENCY_CHOICES if unknown: show = ", ".join(sorted(unknown)) raise ConfigError(f"Unknown concurrency choices: {show}") light_threads = concurrencies & self.LIGHT_THREADS if len(light_threads) > 1: show = ", ".join(sorted(light_threads)) raise ConfigError(f"Conflicting concurrency settings: {show}") do_threading = False try: if "greenlet" in concurrencies: tried = "greenlet" import greenlet self.concur_id_func = greenlet.getcurrent elif "eventlet" in concurrencies: tried = "eventlet" import eventlet.greenthread # pylint: disable=import-error,useless-suppression self.concur_id_func = eventlet.greenthread.getcurrent elif "gevent" in concurrencies: tried = "gevent" import gevent # pylint: disable=import-error,useless-suppression self.concur_id_func = gevent.getcurrent if "thread" in concurrencies: do_threading = True except ImportError as ex: msg = f"Couldn't trace with concurrency={tried}, the module isn't installed." raise ConfigError(msg) from ex if self.concur_id_func and not hasattr(self._trace_class, "concur_id_func"): raise ConfigError( "Can't support concurrency={} with {}, only threads are supported." .format( tried, self.tracer_name(), )) if do_threading or not concurrencies: # It's important to import threading only if we need it. If # it's imported early, and the program being measured uses # gevent, then gevent's monkey-patching won't work properly. import threading self.threading = threading self.reset()