<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def report(self, morfs=None):
 """ Generate a part of json report for coveralls `morfs` is a list of modules or filenames. `outfile` is a file object to write the json to. """

        units = None
        if hasattr(self, 'find_code_units'):
            self.find_code_units(morfs)
        else:
            units = self.find_file_reporters(morfs)

        if units is None:
            if hasattr(self, 'code_units'):
                units = self.code_units
            else:
                units = self.file_reporters

        for cu in units:
            try:
                analyzed = self.coverage._analyze(cu)  # pylint: disable=W0212
                self.parse_file(cu, analyzed)
            except NoSource:
                if not self.config.ignore_errors:
                    log.warning('No source for %s', cu.filename)
            except NotPython:
                # Only report errors for .py files, and only if we didn't
                # explicitly suppress those errors.
                if cu.should_be_python() and not self.config.ignore_errors:
                    log.warning('Source file is not python %s', cu.filename)
            except KeyError:
                cov3x = __version__[0] < 4
                cov40 = __version__[0] == 4 and __version__[1] < 1
                if cov3x or cov40:
                    raise CoverallsException(
                        'Old (<4.1) versions of coverage.py do not work '
                        'consistently on new versions of Python. Please '
                        'upgrade your coverage.py.'
                    )

                raise

        return self.source_files