code: def file_reporter(self, filename):
      # TODO: let coverage.py handle .py files itself
      # ext = os.path.splitext(filename)[1].lower()
      # if ext == '.py':
      #    from coverage.python import PythonFileReporter
      #    return PythonFileReporter(filename)
  
      filename = canonical_filename(filename)
      if self._c_files_map and filename in self._c_files_map:
          c_file, rel_file_path, code = self._c_files_map[filename]
      else:
          c_file, _ = self._find_source_files(filename)
          if not c_file:
              if standalone():
                  raise AssertionError(filename)
              return None  # unknown file
          rel_file_path, code = self._read_source_lines(
              c_file, filename
          )
          if code is None:
              if standalone():
                  raise AssertionError(filename)
              return None  # no source found
  
      return CythonModuleReporter(c_file, filename, rel_file_path, code)
  
imports: from __future__ import absolute_import
  import re
  import os.path
  import sys
  from collections import defaultdict
  from coverage.plugin import CoveragePlugin, FileTracer, FileReporter
  from coverage.files import canonical_filename
  from .Utils import find_root_package_dir, is_package_dir, open_source_file
  from .None import __version__
label_desc: Use image node_id 3 for calling the Plugin obj's underlying member method code with example usage: obj.file_reporter(filename) and returns: CythonModuleReporter, None, None