nodes: 0, module; 1, function_definition; 2, function_name:sort_by; 3, parameters; 4, block; 5, identifier:items; 6, identifier:attr; 7, expression_statement; 8, function_definition; 9, return_statement; 10, comment:"""
      General sort filter - sorts by either attribute or key.
      """; 11, function_name:key_func; 12, parameters; 13, block; 14, call; 15, identifier:item; 16, try_statement; 17, identifier:sorted; 18, argument_list; 19, block; 20, except_clause; 21, identifier:items; 22, keyword_argument; 23, return_statement; 24, identifier:AttributeError; 25, block; 26, identifier:key; 27, identifier:key_func; 28, call; 29, try_statement; 30, identifier:getattr; 31, argument_list; 32, block; 33, except_clause; 34, identifier:item; 35, identifier:attr; 36, return_statement; 37, identifier:TypeError; 38, block; 39, subscript; 40, expression_statement; 41, comment:# Reraise AttributeError; 42, identifier:item; 43, identifier:attr; 44, call; 45, identifier:getattr; 46, argument_list; 47, identifier:item; 48, identifier:attr
code: def sort_by(items, attr):
      """
      General sort filter - sorts by either attribute or key.
      """
      def key_func(item):
          try:
              return getattr(item, attr)
          except AttributeError:
              try:
                  return item[attr]
              except TypeError:
                  getattr(item, attr)  # Reraise AttributeError
      return sorted(items, key=key_func)