def testCases(path):
     reader = UFOReader(path)
     expectedFileStructure = fileStructure
     if fileStructure is None:
         expectedFileStructure = UFOFileStructure.PACKAGE
     else:
         expectedFileStructure = UFOFileStructure(fileStructure)
     self.assertEqual(reader.fileStructure, expectedFileStructure)
Exemple #2
0
    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
Exemple #3
0
    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