nodes: 0, module; 1, function_definition; 2, function_name:_cmp_key; 3, parameters; 4, block; 5, identifier:self; 6, default_parameter; 7, expression_statement; 8, if_statement; 9, expression_statement; 10, expression_statement; 11, return_statement; 12, identifier:obj; 13, None; 14, comment:"""Comparison key for sorting results from all linters.
  
          The sort should group files and lines from different linters to make it
          easier for refactoring.
          """; 15, not_operator; 16, block; 17, assignment; 18, assignment; 19, tuple; 20, identifier:obj; 21, expression_statement; 22, identifier:line_nr; 23, conditional_expression:int(obj.line_nr) if obj.line_nr else 0; 24, identifier:col; 25, conditional_expression:int(obj.col) if obj.col else 0; 26, attribute; 27, identifier:line_nr; 28, identifier:col; 29, attribute; 30, assignment; 31, call; 32, attribute; 33, integer:0; 34, call; 35, attribute; 36, integer:0; 37, identifier:obj; 38, identifier:path; 39, identifier:obj; 40, identifier:msg; 41, identifier:obj; 42, identifier:self; 43, identifier:int; 44, argument_list; 45, identifier:obj; 46, identifier:line_nr; 47, identifier:int; 48, argument_list; 49, identifier:obj; 50, identifier:col; 51, attribute; 52, attribute; 53, identifier:obj; 54, identifier:line_nr; 55, identifier:obj; 56, identifier:col
code: def _cmp_key(self, obj=None):
          """Comparison key for sorting results from all linters.
  
          The sort should group files and lines from different linters to make it
          easier for refactoring.
          """
          if not obj:
              obj = self
          line_nr = int(obj.line_nr) if obj.line_nr else 0
          col = int(obj.col) if obj.col else 0
          return (obj.path, line_nr, col, obj.msg)