nodes: 0, module; 1, function_definition; 2, function_name:dsort; 3, parameters; 4, block; 5, identifier:self; 6, identifier:order; 7, expression_statement; 8, comment:# Make order conforming to a list of dictionaries; 9, expression_statement; 10, expression_statement; 11, comment:# Verify that all columns exist in file; 12, expression_statement; 13, comment:# Get column indexes; 14, expression_statement; 15, for_statement; 16, comment:# From the Python documentation:; 17, comment:# "Starting with Python 2.3, the sort() method is guaranteed to be; 18, comment:# stable. A sort is stable if it guarantees not to change the; 19, comment:# relative order of elements that compare equal - this is helpful; 20, comment:# for sorting in multiple passes (for example, sort by department,; 21, comment:# then by salary grade)."; 22, comment:# This means that the sorts have to be done from "minor" column to; 23, comment:# "major" column; 24, for_statement; 25, comment:r"""
          Sort rows.
  
          :param order: Sort order
          :type  order: :ref:`CsvColFilter`
  
          .. [[[cog cog.out(exobj.get_sphinx_autodoc()) ]]]
          .. Auto-generated exceptions documentation for
          .. pcsv.csv_file.CsvFile.dsort
  
          :raises:
           * RuntimeError (Argument \`order\` is not valid)
  
           * RuntimeError (Invalid column specification)
  
           * ValueError (Column *[column_identifier]* not found)
  
          .. [[[end]]]
          """; 26, assignment; 27, assignment; 28, call; 29, assignment; 30, identifier:nitem; 31, identifier:norder; 32, block; 33, tuple_pattern; 34, call; 35, block; 36, identifier:order; 37, conditional_expression:order if isinstance(order, list) else [order]; 38, identifier:norder; 39, list_comprehension; 40, attribute; 41, argument_list; 42, identifier:clist; 43, list; 44, for_statement; 45, identifier:cindex; 46, identifier:rvalue; 47, identifier:reversed; 48, argument_list; 49, expression_statement; 50, expression_statement; 51, identifier:order; 52, call; 53, list; 54, conditional_expression:{item: "A"} if not isinstance(item, dict) else item; 55, for_in_clause; 56, identifier:self; 57, identifier:_in_header; 58, list_comprehension; 59, pattern_list; 60, call; 61, block; 62, identifier:clist; 63, assignment; 64, call; 65, identifier:isinstance; 66, argument_list; 67, identifier:order; 68, dictionary; 69, not_operator; 70, identifier:item; 71, identifier:item; 72, identifier:order; 73, subscript; 74, for_in_clause; 75, identifier:key; 76, identifier:value; 77, attribute; 78, argument_list; 79, expression_statement; 80, identifier:fpointer; 81, call; 82, attribute; 83, argument_list; 84, identifier:order; 85, identifier:list; 86, pair; 87, call; 88, call; 89, integer:0; 90, identifier:item; 91, identifier:norder; 92, identifier:nitem; 93, identifier:items; 94, call; 95, attribute; 96, argument_list; 97, attribute; 98, identifier:sort; 99, keyword_argument; 100, keyword_argument; 101, identifier:item; 102, string:"A"; 103, identifier:isinstance; 104, argument_list; 105, identifier:list; 106, argument_list; 107, attribute; 108, argument_list; 109, identifier:operator; 110, identifier:itemgetter; 111, identifier:cindex; 112, identifier:self; 113, identifier:_data; 114, identifier:key; 115, identifier:fpointer; 116, identifier:reverse; 117, identifier:rvalue; 118, identifier:item; 119, identifier:dict; 120, call; 121, identifier:clist; 122, identifier:append; 123, tuple; 124, attribute; 125, argument_list; 126, conditional_expression:key
                          if isinstance(key, int)
                          else self._header_upper.index(key.upper()); 127, comparison_operator:value.upper() == "D"; 128, identifier:item; 129, identifier:keys; 130, identifier:key; 131, call; 132, call; 133, call; 134, string:"D"; 135, identifier:isinstance; 136, argument_list; 137, attribute; 138, argument_list; 139, attribute; 140, argument_list; 141, identifier:key; 142, identifier:int; 143, attribute; 144, identifier:index; 145, call; 146, identifier:value; 147, identifier:upper; 148, identifier:self; 149, identifier:_header_upper; 150, attribute; 151, argument_list; 152, identifier:key; 153, identifier:upper
code: def dsort(self, order):
          r"""
          Sort rows.
  
          :param order: Sort order
          :type  order: :ref:`CsvColFilter`
  
          .. [[[cog cog.out(exobj.get_sphinx_autodoc()) ]]]
          .. Auto-generated exceptions documentation for
          .. pcsv.csv_file.CsvFile.dsort
  
          :raises:
           * RuntimeError (Argument \`order\` is not valid)
  
           * RuntimeError (Invalid column specification)
  
           * ValueError (Column *[column_identifier]* not found)
  
          .. [[[end]]]
          """
          # Make order conforming to a list of dictionaries
          order = order if isinstance(order, list) else [order]
          norder = [{item: "A"} if not isinstance(item, dict) else item for item in order]
          # Verify that all columns exist in file
          self._in_header([list(item.keys())[0] for item in norder])
          # Get column indexes
          clist = []
          for nitem in norder:
              for key, value in nitem.items():
                  clist.append(
                      (
                          key
                          if isinstance(key, int)
                          else self._header_upper.index(key.upper()),
                          value.upper() == "D",
                      )
                  )
          # From the Python documentation:
          # "Starting with Python 2.3, the sort() method is guaranteed to be
          # stable. A sort is stable if it guarantees not to change the
          # relative order of elements that compare equal - this is helpful
          # for sorting in multiple passes (for example, sort by department,
          # then by salary grade)."
          # This means that the sorts have to be done from "minor" column to
          # "major" column
          for (cindex, rvalue) in reversed(clist):
              fpointer = operator.itemgetter(cindex)
              self._data.sort(key=fpointer, reverse=rvalue)