def __init__(
        self,
        core: Core,
        should_trace: TShouldTraceFn,
        check_include: TCheckIncludeFn,
        should_start_context: TShouldStartContextFn | None,
        file_mapper: Callable[[str], str],
        branch: bool,
        warn: TWarnFn,
        concurrency: list[str],
    ) -> None:
        """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 `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.core = core
        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.pid = os.getpid()

        self.covdata: CoverageData
        self.threading = None
        self.static_context: str | None = None

        self.origin = short_stack()

        self.concur_id_func = None

        # 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

        tried = "nothing"  # to satisfy pylint
        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(core.tracer_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()
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 `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.

        
coverage/collector.py