docs: def write (stream, items, fieldnames, tabwidth=8):
      """Write a typed tabular text file to the specified stream.
  
      Arguments:
  
      stream
        The destination stream.
      items
        An iterable of items to write. Two passes have to
        be made over the items (to discover the needed column widths),
        so this will be saved into a list.
      fieldnames
        Either a list of field name strings, or a single string.
        If the latter, it will be split into a list with .split().
      tabwidth=8
        The tab width to use. Please don't monkey with it.
  
      Returns nothing.
  
      """
      if isinstance (fieldnames, six.string_types):
          fieldnames = fieldnames.split ()
  
      maxlens = [0] * len (fieldnames)
  
      # We have to make two passes, so listify:
      items = list (items)
  
      # pass 1: get types and maximum lengths for each record. Pad by 1 to
      # ensure there's at least one space between all columns.
  
      coltypes = [None] * len (fieldnames)
  
      for i in items:
          for idx, fn in enumerate (fieldnames):
              val = i.get (fn)
              if val is None:
                  continue
  
              typetag, text, inexact = msmt.fmtinfo (val)
              maxlens[idx] = max (maxlens[idx], len (text) + 1)
  
              if coltypes[idx] is None:
                  coltypes[idx] = typetag
                  continue
  
              if coltypes[idx] == typetag:
                  continue
  
              if coltypes[idx][-1] == 'f' and typetag[-1] == 'u':
                  # Can upcast floats to uvals
                  if coltypes[idx][:-1] == typetag[:-1]:
                      coltypes[idx] = coltypes[idx][:-1] + 'u'
                      continue
  
              if coltypes[idx][-1] == 'u' and typetag[-1] == 'f':
                  if coltypes[idx][:-1] == typetag[:-1]:
                      continue
  
              raise PKError ('irreconcilable column types: %s and %s', coltypes[idx], typetag)
  
      # Compute column headers and their widths
  
      headers = list (fieldnames)
      headers[0] = '@' + headers[0]
  
      for idx, fn in enumerate (fieldnames):
          if coltypes[idx] != '':
              headers[idx] += ':' + coltypes[idx]
  
          maxlens[idx] = max (maxlens[idx], len (headers[idx]))
  
      widths = [tabwidth * ((k + tabwidth - 1) // tabwidth) for k in maxlens]
  
      # pass 2: write out
  
      print (''.join (_tabpad (h, widths[idx], tabwidth)
                      for (idx, h) in enumerate (headers)), file=stream)
  
      def ustr (i, f):
          v = i.get (f)
          if v is None:
              return ''
          return msmt.fmtinfo (v)[1]
  
      for i in items:
          print (''.join (_tabpad (ustr (i, fn), widths[idx], tabwidth)
                          for (idx, fn) in enumerate (fieldnames)), file=stream)