def test_io(tmpdir, parametrized_pl): pl, use_builtin_types = parametrized_pl testpath = tmpdir / "test.plist" with testpath.open("wb") as fp: plistlib.dump(pl, fp, use_builtin_types=use_builtin_types) with testpath.open("rb") as fp: pl2 = plistlib.load(fp, use_builtin_types=use_builtin_types) assert pl == pl2 with pytest.raises(AttributeError): plistlib.dump(pl, "filename") with pytest.raises(AttributeError): plistlib.load("filename")
def cleanupContentsList(glyphDirPath, doWarning=True): contentsFilePath = os.path.join(glyphDirPath, kContentsName) # maps glyph names to files. with open(contentsFilePath, 'r', encoding='utf-8') as fp: contentsDict = plistlib.load(fp) fileDict = {} fileList = os.listdir(glyphDirPath) for fileName in fileList: fileDict[fileName] = 1 changed = 0 # now update and write the processed processedGlyphDirPath # contents.plist file. itemList = list(contentsDict.items()) for glyphName, fileName in itemList: if fileName not in fileDict: del contentsDict[glyphName] changed = 1 if doWarning: print("Removing contents.plist entry where glif was missing: " "%s, %s, %s" % (glyphName, fileName, glyphDirPath)) if changed: with open(contentsFilePath, 'wb') as fp: plistlib.dump(contentsDict, fp)
def test_writePlist_to_file(tmpdir, pl_no_builtin_types): testpath = tmpdir / "test.plist" with testpath.open("wb") as fp: writePlist(pl_no_builtin_types, fp) with testpath.open("rb") as fp: pl2 = plistlib.load(fp, use_builtin_types=False) assert pl2 == pl_no_builtin_types
def test_bytesio(parametrized_pl): pl, use_builtin_types = parametrized_pl b = BytesIO() plistlib.dump(pl, b, use_builtin_types=use_builtin_types) pl2 = plistlib.load(BytesIO(b.getvalue()), use_builtin_types=use_builtin_types) assert pl == pl2
def test_bytesio(parametrized_pl): pl, use_builtin_types = parametrized_pl b = BytesIO() plistlib.dump(pl, b, use_builtin_types=use_builtin_types) pl2 = plistlib.load( BytesIO(b.getvalue()), use_builtin_types=use_builtin_types ) assert pl == pl2
def readPlist(path_or_file): did_open = False if isinstance(path_or_file, str): path_or_file = open(path_or_file, "rb") did_open = True try: return load(path_or_file, use_builtin_types=False) finally: if did_open: path_or_file.close()
def getUFOVersion(ufoPath): # Peek into a ufo to read its format version. # <?xml version="1.0" encoding="UTF-8"?> # <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> # <plist version="1.0"> # <dict> # <key>creator</key> # <string>org.robofab.ufoLib</string> # <key>formatVersion</key> # <integer>2</integer> # </dict> # </plist> metaInfoPath = os.path.join(ufoPath, "metainfo.plist") with open(metaInfoPath, 'rb') as f: p = plistlib.load(f) return p.get('formatVersion')
def test_keysort_bytesio(sort_keys): pl = collections.OrderedDict() pl["b"] = 1 pl["a"] = 2 pl["c"] = 3 b = BytesIO() plistlib.dump(pl, b, sort_keys=sort_keys) pl2 = plistlib.load(BytesIO(b.getvalue()), dict_type=collections.OrderedDict) assert dict(pl) == dict(pl2) if sort_keys: assert list(pl2.keys()) == ["a", "b", "c"] else: assert list(pl2.keys()) == ["b", "a", "c"]
def test_keysort_bytesio(sort_keys): pl = collections.OrderedDict() pl["b"] = 1 pl["a"] = 2 pl["c"] = 3 b = BytesIO() plistlib.dump(pl, b, sort_keys=sort_keys) pl2 = plistlib.load( BytesIO(b.getvalue()), dict_type=collections.OrderedDict ) assert dict(pl) == dict(pl2) if sort_keys: assert list(pl2.keys()) == ["a", "b", "c"] else: assert list(pl2.keys()) == ["b", "a", "c"]
def parsePList(filePath, dictKey=None): # If dictKey is defined, parse and return only the data for that key. # # Updates July 2019: # - use fontTools.misc.plistlib instead of ET to parse # - use built-in OrderedDict as the dict_type to preserve ordering # - use simpler filtering for non-None dictKey plistDict = {} plistKeys = [] with open(filePath, 'r', encoding='utf-8') as fp: plistDict = plistlib.load(fp, dict_type=OrderedDict) if dictKey is not None: if dictKey in plistDict: plistDict = {dictKey: plistDict[dictKey]} else: plistDict = None if plistDict is not None: plistKeys = list(plistDict.keys()) return plistDict, plistKeys
def cleanUpGLIFFiles(defaultContentsFilePath, glyphDirPath, doWarning=True): changed = 0 contentsFilePath = os.path.join(glyphDirPath, kContentsName) # maps glyph names to files. with open(contentsFilePath, 'r', encoding='utf-8') as fp: contentsDict = plistlib.load(fp) # First, delete glyph files that are not in the contents.plist file in # the glyphDirPath. In some UFOfont files, we end up with case errors, # so we need to check for a lower-case version of the file name. fileDict = {} for glyphName, fileName in contentsDict.items(): fileDict[fileName] = glyphName lcFileName = fileName.lower() if lcFileName != fileName: fileDict[lcFileName + kAdobeLCALtSuffix] = glyphName fileList = os.listdir(glyphDirPath) for fileName in fileList: if not fileName.endswith(".glif"): continue if fileName in fileDict: continue lcFileName = fileName.lower() if (lcFileName + kAdobeLCALtSuffix) in fileDict: # glif file exists which has a case-insensitive match to file name # entry in the contents.plist file; assume latter is intended, and # change the file name to match. glyphFilePathOld = os.path.join(glyphDirPath, fileName) glyphFilePathNew = os.path.join(glyphDirPath, lcFileName) os.rename(glyphFilePathOld, glyphFilePathNew) continue glyphFilePath = os.path.join(glyphDirPath, fileName) os.remove(glyphFilePath) if doWarning: print("Removing glif file %s that was not in the contents.plist " "file: %s" % (glyphDirPath, contentsFilePath)) changed = 1 if defaultContentsFilePath == contentsFilePath: return changed # Now remove glyphs that are not referenced in the defaultContentsFilePath. # Since the processed glyph layer is written with the defcon module, # and the default layer may be written by anything, the actual glyph file # names may be different for the same UFO glyph. We need to compare by UFO # glyph name, not file name. with open(defaultContentsFilePath, 'r', encoding='utf-8') as fp: defaultContentsDict = plistlib.load(fp) fileList = os.listdir(glyphDirPath) for fileName in fileList: if not fileName.endswith(".glif"): continue try: glyphName = fileDict[fileName] if glyphName not in defaultContentsDict: glyphFilePath = os.path.join(glyphDirPath, fileName) os.remove(glyphFilePath) if doWarning: print("Removing glif %s that was not in the " "contents.plist file: %s" % (glyphName, defaultContentsFilePath)) changed = 1 except KeyError: print("Shouldn't happen %s %s" % (glyphName, defaultContentsFilePath)) return changed