docs: def save(filename, obj, overwrite=False, create_directories=False):
      '''
      pimms.save(filename, obj) attempts to pickle the given object obj in the filename (or stream,
        if given). An error is raised when this cannot be accomplished; the first argument is always
        returned; though if the argument is a filename, it may be a differet string that refers to
        the same file.
  
      The save/load protocol uses pickle for all saving/loading except when the object is a numpy
      object, in which case it is written using obj.tofile(). The save function writes meta-data
      into the file so cannot simply be unpickled, but must be loaded using the pimms.load()
      function. Fundamentally, however, if an object can be picled, it can be saved/loaded.
  
      Options:
        * overwrite (False) The optional parameter overwrite indicates whether an error should be
          raised before opening the file if the file already exists.
        * create_directories (False) The optional parameter create_directories indicates whether the
          function should attempt to create the directories in which the filename exists if they do
          not already exist.
      '''
      if isinstance(filename, six.string_types):
          filename = os.path.expanduser(filename)
          if not overwrite and os.path.exists(filename):
              raise ValueError('save would overwrite file %s' % filename)
          if create_directories:
              dname = os.path.dirname(os.path.realpath(filename))
              if not os.path.isdir(dname): os.makedirs(dname)
          with open(filename, 'wb') as f:
              _save_stream(f, obj)
      else:
          _save_stream(filename, obj)
      return filename