docs: def rationalize_file(item_f, charset, mode='rb', lock=False):
      '''FSQ attempts to treat all file-like things as line-buffered as an
         optimization to the average case.  rationalize_file will handle file
         objects, buffers, raw file-descriptors, sockets, and string
         file-addresses, and will return a file object that can be safely closed
         in FSQ scope without closing the file in the bounding caller.'''
      # file, TmpFile, socket, etc ...
      if hasattr(item_f, 'fileno'):
          n_fd = os.dup(item_f.fileno())
          try:
              _lock(n_fd, lock)
              # explicitily decrement file ref
              del item_f
              return os.fdopen(n_fd)
          except Exception, e:
              os.close(n_fd)
              raise e
  
      # StringIO, cStringIO, etc ...
      elif hasattr(item_f, 'readline'):
          return item_f
      # raw file descriptor -- e.g. output of pipe
      elif isinstance(item_f, numbers.Integral):
          n_fd = os.dup(item_f)
          try:
              _lock(n_fd, lock)
              return os.fdopen(n_fd)
          except Exception, e:
              os.close(n_fd)
              raise e
  
      # try to open, read+binary, line-buffered
      f = open(coerce_unicode(item_f, charset), mode, 1)
      try:
          _lock(f.fileno(), lock)
          return f
      except Exception, e:
          f.close()
          raise e