def lint(filename, lines, config):
_, ext = os.path.splitext(filename)<EOL>if ext in config:<EOL><INDENT>output = collections.defaultdict(list)<EOL>for linter in config[ext]:<EOL><INDENT>linter_output = linter(filename, lines)<EOL>for category, values in linter_output[filename].items():<EOL><INDENT>output[category].extend(values)<EOL><DEDENT><DEDENT>if '<STR_LIT>' in output:<EOL><INDENT>output['<STR_LIT>'] = sorted(<EOL>output['<STR_LIT>'],<EOL>key=lambda x: (x.get('<STR_LIT>', -<NUM_LIT:1>), x.get('<STR_LIT>', -<NUM_LIT:1>)))<EOL><DEDENT>return {filename: dict(output)}<EOL><DEDENT>else:<EOL><INDENT>return {<EOL>filename: {<EOL>'<STR_LIT>': [<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % ext<EOL>]<EOL>}<EOL>}<EOL><DEDENT>
Lints a file.

    Args:
        filename: string: filename to lint.
        lines: list[int]|None: list of lines that we want to capture. If None,
          then all lines will be captured.
        config: dict[string: linter]: mapping from extension to a linter
          function.

    Returns: dict: if there were errors running the command then the field
      'error' will have the reasons in a list. if the lint process was skipped,
      then a field 'skipped' will be set with the reasons. Otherwise, the field
      'comments' will have the messages.