docstr: Save the DOT source to file. Ensure the file ends with a newline.
  
  Args:
      filename: Filename for saving the source (defaults to ``name`` + ``'.gv'``)
      directory: (Sub)directory for source saving and rendering.
  
  Returns:
      The (possibly relative) path of the saved source file.
docstr_tok: ["Save","the","DOT","source","to","file",".","Ensure","the","file","ends","with","a","newline",".","Args",":","filename",":","Filename","for","saving","the","source","(","defaults","to","``","name","``","+","``","'.gv","'","``",")","directory",":","(","Sub",")","directory","for","source","saving","and","rendering",".","Returns",":","The","(","possibly","relative",")","path","of","the","saved","source","file","."]
code: def save(self, filename=None, directory=None):
      """Save the DOT source to file. Ensure the file ends with a newline.
  
      Args:
          filename: Filename for saving the source (defaults to ``name`` + ``'.gv'``)
          directory: (Sub)directory for source saving and rendering.
  
      Returns:
          The (possibly relative) path of the saved source file.
      """
      if filename is not None:
          self.filename = filename
      if directory is not None:
          self.directory = directory
  
      filepath = self.filepath
      tools.mkdirs(filepath)
  
      log.debug("write %d bytes to %r", len(self.source), filepath)
      with open(filepath, "w", encoding=self.encoding) as fd:
          fd.write(self.source)
          if not self.source.endswith("\n"):
              fd.write("\n")
  
      return filepath
  
imports: import codecs
  import locale
  import logging
  import os
  from .None import backend
  from .None import tools
label_desc: Use image node_id 8 for calling the File obj's underlying member method code with example usage: obj.save(filename, directory) and returns: filepath