--- a/DebugClients/Python/coverage/plugin_support.py Fri Sep 02 19:08:02 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,250 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt - -"""Support for plugins.""" - -import os -import os.path -import sys - -from coverage.misc import CoverageException, isolate_module -from coverage.plugin import CoveragePlugin, FileTracer, FileReporter - -os = isolate_module(os) - - -class Plugins(object): - """The currently loaded collection of coverage.py plugins.""" - - def __init__(self): - self.order = [] - self.names = {} - self.file_tracers = [] - - self.current_module = None - self.debug = None - - @classmethod - def load_plugins(cls, modules, config, debug=None): - """Load plugins from `modules`. - - Returns a list of loaded and configured plugins. - - """ - plugins = cls() - plugins.debug = debug - - for module in modules: - plugins.current_module = module - __import__(module) - mod = sys.modules[module] - - coverage_init = getattr(mod, "coverage_init", None) - if not coverage_init: - raise CoverageException( - "Plugin module %r didn't define a coverage_init function" % module - ) - - options = config.get_plugin_options(module) - coverage_init(plugins, options) - - plugins.current_module = None - return plugins - - def add_file_tracer(self, plugin): - """Add a file tracer plugin. - - `plugin` is an instance of a third-party plugin class. It must - implement the :meth:`CoveragePlugin.file_tracer` method. - - """ - self._add_plugin(plugin, self.file_tracers) - - def add_noop(self, plugin): - """Add a plugin that does nothing. - - This is only useful for testing the plugin support. - - """ - self._add_plugin(plugin, None) - - def _add_plugin(self, plugin, specialized): - """Add a plugin object. - - `plugin` is a :class:`CoveragePlugin` instance to add. `specialized` - is a list to append the plugin to. - - """ - plugin_name = "%s.%s" % (self.current_module, plugin.__class__.__name__) - if self.debug and self.debug.should('plugin'): - self.debug.write("Loaded plugin %r: %r" % (self.current_module, plugin)) - labelled = LabelledDebug("plugin %r" % (self.current_module,), self.debug) - plugin = DebugPluginWrapper(plugin, labelled) - - # pylint: disable=attribute-defined-outside-init - plugin._coverage_plugin_name = plugin_name - plugin._coverage_enabled = True - self.order.append(plugin) - self.names[plugin_name] = plugin - if specialized is not None: - specialized.append(plugin) - - def __nonzero__(self): - return bool(self.order) - - __bool__ = __nonzero__ - - def __iter__(self): - return iter(self.order) - - def get(self, plugin_name): - """Return a plugin by name.""" - return self.names[plugin_name] - - -class LabelledDebug(object): - """A Debug writer, but with labels for prepending to the messages.""" - - def __init__(self, label, debug, prev_labels=()): - self.labels = list(prev_labels) + [label] - self.debug = debug - - def add_label(self, label): - """Add a label to the writer, and return a new `LabelledDebug`.""" - return LabelledDebug(label, self.debug, self.labels) - - def message_prefix(self): - """The prefix to use on messages, combining the labels.""" - prefixes = self.labels + [''] - return ":\n".join(" "*i+label for i, label in enumerate(prefixes)) - - def write(self, message): - """Write `message`, but with the labels prepended.""" - self.debug.write("%s%s" % (self.message_prefix(), message)) - - -class DebugPluginWrapper(CoveragePlugin): - """Wrap a plugin, and use debug to report on what it's doing.""" - - def __init__(self, plugin, debug): - super(DebugPluginWrapper, self).__init__() - self.plugin = plugin - self.debug = debug - - def file_tracer(self, filename): - tracer = self.plugin.file_tracer(filename) - self.debug.write("file_tracer(%r) --> %r" % (filename, tracer)) - if tracer: - debug = self.debug.add_label("file %r" % (filename,)) - tracer = DebugFileTracerWrapper(tracer, debug) - return tracer - - def file_reporter(self, filename): - reporter = self.plugin.file_reporter(filename) - self.debug.write("file_reporter(%r) --> %r" % (filename, reporter)) - if reporter: - debug = self.debug.add_label("file %r" % (filename,)) - reporter = DebugFileReporterWrapper(filename, reporter, debug) - return reporter - - def sys_info(self): - return self.plugin.sys_info() - - -class DebugFileTracerWrapper(FileTracer): - """A debugging `FileTracer`.""" - - def __init__(self, tracer, debug): - self.tracer = tracer - self.debug = debug - - def _show_frame(self, frame): - """A short string identifying a frame, for debug messages.""" - return "%s@%d" % ( - os.path.basename(frame.f_code.co_filename), - frame.f_lineno, - ) - - def source_filename(self): - sfilename = self.tracer.source_filename() - self.debug.write("source_filename() --> %r" % (sfilename,)) - return sfilename - - def has_dynamic_source_filename(self): - has = self.tracer.has_dynamic_source_filename() - self.debug.write("has_dynamic_source_filename() --> %r" % (has,)) - return has - - def dynamic_source_filename(self, filename, frame): - dyn = self.tracer.dynamic_source_filename(filename, frame) - self.debug.write("dynamic_source_filename(%r, %s) --> %r" % ( - filename, self._show_frame(frame), dyn, - )) - return dyn - - def line_number_range(self, frame): - pair = self.tracer.line_number_range(frame) - self.debug.write("line_number_range(%s) --> %r" % (self._show_frame(frame), pair)) - return pair - - -class DebugFileReporterWrapper(FileReporter): - """A debugging `FileReporter`.""" - - def __init__(self, filename, reporter, debug): - super(DebugFileReporterWrapper, self).__init__(filename) - self.reporter = reporter - self.debug = debug - - def relative_filename(self): - ret = self.reporter.relative_filename() - self.debug.write("relative_filename() --> %r" % (ret,)) - return ret - - def lines(self): - ret = self.reporter.lines() - self.debug.write("lines() --> %r" % (ret,)) - return ret - - def excluded_lines(self): - ret = self.reporter.excluded_lines() - self.debug.write("excluded_lines() --> %r" % (ret,)) - return ret - - def translate_lines(self, lines): - ret = self.reporter.translate_lines(lines) - self.debug.write("translate_lines(%r) --> %r" % (lines, ret)) - return ret - - def translate_arcs(self, arcs): - ret = self.reporter.translate_arcs(arcs) - self.debug.write("translate_arcs(%r) --> %r" % (arcs, ret)) - return ret - - def no_branch_lines(self): - ret = self.reporter.no_branch_lines() - self.debug.write("no_branch_lines() --> %r" % (ret,)) - return ret - - def exit_counts(self): - ret = self.reporter.exit_counts() - self.debug.write("exit_counts() --> %r" % (ret,)) - return ret - - def arcs(self): - ret = self.reporter.arcs() - self.debug.write("arcs() --> %r" % (ret,)) - return ret - - def source(self): - ret = self.reporter.source() - self.debug.write("source() --> %d chars" % (len(ret),)) - return ret - - def source_token_lines(self): - ret = list(self.reporter.source_token_lines()) - self.debug.write("source_token_lines() --> %d tokens" % (len(ret),)) - return ret - -# -# eflag: FileType = Python2