# Buggy code
def check_parallel(linter, jobs, files, arguments=None):
    """Use the given linter to lint the files with given amount of workers (jobs)"""
    # The reporter does not need to be passed to worker processess, i.e. the reporter does
    # not need to be pickleable
    original_reporter = linter.reporter
    linter.reporter = None

    # The linter is inherited by all the pool's workers, i.e. the linter
    # is identical to the linter object here. This is requred so that
    # a custom PyLinter object can be used.
    initializer = functools.partial(_worker_initialize, arguments=arguments)
    with multiprocessing.Pool(jobs, initializer=initializer, initargs=[linter]) as pool:
        # ..and now when the workers have inherited the linter, the actual reporter
        # can be set back here on the parent process so that results get stored into
        # correct reporter
        linter.set_reporter(original_reporter)
        linter.open()

        all_stats = []

        for module, base_name, messages, stats, msg_status in pool.imap_unordered(
            _worker_check_single_file, files
        ):
            linter.file_state.base_name = base_name
            linter.set_current_module(module)
            for msg in messages:
                msg = Message(*msg)
                linter.reporter.handle_message(msg)

            all_stats.append(stats)
            linter.msg_status |= msg_status

    linter.stats = _merge_stats(all_stats)

    # Insert stats data to local checkers.
    for checker in linter.get_checkers():
        if checker is not linter:
            checker.stats = linter.stats


# Traceback (AttributeError)
Traceback (most recent call last):
File "/opt/gitlab-runner/NCiG8AGt/0/<path>/.tox/pylint/bin/pylint", line 8, in <module>
sys.exit(run_pylint())
File "/opt/gitlab-runner/NCiG8AGt/0/<path>/.tox/pylint/lib/python3.6/site-packages/pylint/__init__.py", line 22, in run_pylint
PylintRun(sys.argv[1:])
File "/opt/gitlab-runner/NCiG8AGt/0/<path>/.tox/pylint/lib/python3.6/site-packages/pylint/lint/run.py", line 338, in __init__
linter.check(args)
File "/opt/gitlab-runner/NCiG8AGt/0/<path>/.tox/pylint/lib/python3.6/site-packages/pylint/lint/pylinter.py", line 878, in check
files_or_modules,
File "/opt/gitlab-runner/NCiG8AGt/0/<path>/.tox/pylint/lib/python3.6/site-packages/pylint/lint/check_parallel.py", line 106, in check_parallel
linter.reporter.handle_message(msg)
File "/opt/gitlab-runner/NCiG8AGt/0/<path>/.tox/pylint/lib/python3.6/site-packages/pylint/reporters/text.py", line 151, in handle_message
self.write_message(msg)
File "/opt/gitlab-runner/NCiG8AGt/0/<path>/.tox/pylint/lib/python3.6/site-packages/pylint/reporters/text.py", line 141, in write_message
self.writeln(msg.format(self._template))
File "/opt/gitlab-runner/NCiG8AGt/0/<path>/.tox/pylint/lib/python3.6/site-packages/pylint/message/message.py", line 51, in format
return template.format(**dict(zip(self._fields, self)))
AttributeError: 'NoneType' object has no attribute 'format'
ERROR: InvocationError for command /opt/gitlab-runner/NCiG8AGt/0/<path>/.tox/pylint/bin/pylint src/ (exited with code 1)

# Fixed code
def check_parallel(linter, jobs, files, arguments=None):
    """Use the given linter to lint the files with given amount of workers (jobs)"""
    # The reporter does not need to be passed to worker processess, i.e. the reporter does
    # not need to be pickleable
    original_reporter = linter.reporter
    linter.reporter = None

    # The linter is inherited by all the pool's workers, i.e. the linter
    # is identical to the linter object here. This is requred so that
    # a custom PyLinter object can be used.
    initializer = functools.partial(_worker_initialize, arguments=arguments)
    with multiprocessing.Pool(jobs, initializer=initializer, initargs=[linter]) as pool:
        # ..and now when the workers have inherited the linter, the actual reporter
        # can be set back here on the parent process so that results get stored into
        # correct reporter
        linter.set_reporter(original_reporter)
        linter.open()

        all_stats = []

        for (
            module,
            file_path,
            base_name,
            messages,
            stats,
            msg_status,
        ) in pool.imap_unordered(_worker_check_single_file, files):
            linter.file_state.base_name = base_name
            linter.set_current_module(module, file_path)
            for msg in messages:
                msg = Message(*msg)
                linter.reporter.handle_message(msg)

            all_stats.append(stats)
            linter.msg_status |= msg_status

    linter.stats = _merge_stats(all_stats)

    # Insert stats data to local checkers.
    for checker in linter.get_checkers():
        if checker is not linter:
            checker.stats = linter.stats