def testCases(path): reader = UFOReader(path) expectedFileStructure = fileStructure if fileStructure is None: expectedFileStructure = UFOFileStructure.PACKAGE else: expectedFileStructure = UFOFileStructure(fileStructure) self.assertEqual(reader.fileStructure, expectedFileStructure)
def save( self, path=None, formatVersion=3, structure=None, overwrite=False, validate=True ): if formatVersion != 3: raise NotImplementedError("unsupported format version: %s" % formatVersion) # validate 'structure' argument if structure is not None: structure = UFOFileStructure(structure) elif self._fileStructure is not None: # if structure is None, fall back to the same as when first loaded structure = self._fileStructure if hasattr(path, "__fspath__"): path = path.__fspath__() if isinstance(path, str): path = os.path.normpath(path) # else we assume it's an fs.BaseFS and we pass it on to UFOWriter overwritePath = tmp = None saveAs = path is not None if saveAs: if isinstance(path, str) and os.path.exists(path): if overwrite: overwritePath = path tmp = fs.tempfs.TempFS() path = tmp.getsyspath(os.path.basename(path)) else: import errno raise OSError(errno.EEXIST, "path %r already exists" % path) elif self.path is None: raise TypeError("'path' is required when saving a new Font") else: path = self.path try: with UFOWriter(path, structure=structure, validate=validate) as writer: self.write(writer, saveAs=saveAs) writer.setModificationTime() except Exception: raise else: if overwritePath is not None: # remove existing then move file to destination if os.path.isdir(overwritePath): shutil.rmtree(overwritePath) elif os.path.isfile(overwritePath): os.remove(overwritePath) shutil.move(path, overwritePath) path = overwritePath finally: # clean up the temporary directory if tmp is not None: tmp.close() self._path = path
def save( self, path: Optional[Union[PathLike, fs.base.FS]] = None, formatVersion: int = 3, structure: Optional[UFOFileStructure] = None, overwrite: bool = False, validate: bool = True, ) -> None: """Saves the font to ``path``. Args: path: The target path. If it is None, the path from the last save (except when that was a ``fs.base.FS``) or when the font was first opened will be used. formatVersion: The version to save the UFO as. Only version 3 is supported currently. structure (fontTools.ufoLib.UFOFileStructure): How to store the UFO. Can be either None, "zip" or "package". If None, it tries to use the same structure as the original UFO at the output path. If "zip", the UFO will be saved as compressed archive. If "package", it is saved as a regular folder or "package". overwrite: If False, raises OSError when the target path exists. If True, overwrites the target path. validate: If True, will validate the data in Font before writing it out. If False, will write out whatever is serializable. """ if formatVersion != 3: raise NotImplementedError(f"unsupported format version: {formatVersion}") # validate 'structure' argument if structure is not None: structure = UFOFileStructure(structure) elif self._fileStructure is not None: # if structure is None, fall back to the same as when first loaded structure = self._fileStructure # Normalize path unless we're given a fs.base.FS, which we pass to UFOWriter. if path is not None and not isinstance(path, fs.base.FS): path = os.path.normpath(os.fspath(path)) overwritePath = tmp = None saveAs = path is not None if saveAs: if isinstance(path, str) and os.path.exists(path): if overwrite: overwritePath = path tmp = fs.tempfs.TempFS() path = tmp.getsyspath(os.path.basename(path)) else: import errno raise OSError(errno.EEXIST, "path %r already exists" % path) elif self.path is None: raise TypeError("'path' is required when saving a new Font") else: path = self.path try: with UFOWriter(path, structure=structure, validate=validate) as writer: self.write(writer, saveAs=saveAs) writer.setModificationTime() except Exception: raise else: if overwritePath is not None: assert isinstance(path, str) # remove existing then move file to destination if os.path.isdir(overwritePath): shutil.rmtree(overwritePath) elif os.path.isfile(overwritePath): os.remove(overwritePath) shutil.move(path, overwritePath) path = overwritePath finally: # clean up the temporary directory if tmp is not None: tmp.close() # Only remember path if it isn't a fs.base.FS because not all FS objects are # OsFS with a corresponding filesystem path. E.g. think about MemoryFS. # If you want, you can call getsyspath("") method of OsFS object and set that to # self._path. But you then have to catch the fs.errors.NoSysPath and skip if # the FS object does not implement a filesystem path. if not isinstance(path, fs.base.FS): self._path = path