Esempio n. 1
0
    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
Esempio n. 2
0
    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))
Esempio n. 3
0
    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))
Esempio n. 4
0
    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))
Esempio n. 5
0
    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))
Esempio n. 6
0
    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
Esempio n. 7
0
    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
Esempio n. 8
0
    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
Esempio n. 9
0
def f_three(*args, **kwargs):
    """Third of the chain of functions for testing `short_stack`."""
    return short_stack(*args, **kwargs)
Esempio n. 10
0
def f_three(*args, **kwargs):
    """Third of the chain of functions for testing `short_stack`."""
    return short_stack(*args, **kwargs)
Esempio n. 11
0
    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
Esempio n. 12
0
 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)
Esempio n. 13
0
    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()