Use a set for file names for clash checking

This commit is contained in:
Nikolaus Waxweiler 2021-10-07 12:03:47 +01:00
parent df2916af61
commit a7e4d86540
3 changed files with 15 additions and 10 deletions

View File

@ -15,7 +15,7 @@ class NameTranslationError(Exception):
pass pass
def userNameToFileName(userName: str, existing=[], prefix="", suffix=""): def userNameToFileName(userName: str, existing=set(), prefix="", suffix=""):
""" """
existing should be a case-insensitive list existing should be a case-insensitive list
of all existing file names. of all existing file names.

View File

@ -10,6 +10,8 @@ in a folder. It offers two ways to read glyph data, and one way to write
glyph data. See the class doc string for details. glyph data. See the class doc string for details.
""" """
from __future__ import annotations
import logging import logging
import enum import enum
from warnings import warn from warnings import warn
@ -205,7 +207,7 @@ class GlyphSet(_UFOBaseIO):
self.glyphNameToFileName = glyphNameToFileNameFunc self.glyphNameToFileName = glyphNameToFileNameFunc
self._validateRead = validateRead self._validateRead = validateRead
self._validateWrite = validateWrite self._validateWrite = validateWrite
self._existingFileNames = None self._existingFileNames: set[str] | None = None
self._reverseContents = None self._reverseContents = None
self.rebuildContents() self.rebuildContents()
@ -455,12 +457,10 @@ class GlyphSet(_UFOBaseIO):
fileName = self.contents.get(glyphName) fileName = self.contents.get(glyphName)
if fileName is None: if fileName is None:
if self._existingFileNames is None: if self._existingFileNames is None:
self._existingFileNames = {} self._existingFileNames = set(fileName.lower() for fileName in self.contents.values())
for fileName in self.contents.values(): fileName = self.glyphNameToFileName(glyphName, self._existingFileNames)
self._existingFileNames[fileName] = fileName.lower()
fileName = self.glyphNameToFileName(glyphName, self._existingFileNames.values())
self.contents[glyphName] = fileName self.contents[glyphName] = fileName
self._existingFileNames[fileName] = fileName.lower() self._existingFileNames.add(fileName.lower())
if self._reverseContents is not None: if self._reverseContents is not None:
self._reverseContents[fileName.lower()] = glyphName self._reverseContents[fileName.lower()] = glyphName
data = _writeGlyphToBytes( data = _writeGlyphToBytes(
@ -485,9 +485,9 @@ class GlyphSet(_UFOBaseIO):
fileName = self.contents[glyphName] fileName = self.contents[glyphName]
self.fs.remove(fileName) self.fs.remove(fileName)
if self._existingFileNames is not None: if self._existingFileNames is not None:
del self._existingFileNames[fileName] self._existingFileNames.remove(fileName.lower())
if self._reverseContents is not None: if self._reverseContents is not None:
del self._reverseContents[self.contents[glyphName].lower()] del self._reverseContents[fileName.lower()]
del self.contents[glyphName] del self.contents[glyphName]
# dict-like support # dict-like support
@ -573,9 +573,12 @@ class GlyphSet(_UFOBaseIO):
def glyphNameToFileName(glyphName, existingFileNames): def glyphNameToFileName(glyphName, existingFileNames):
""" """
Wrapper around the userNameToFileName function in filenames.py Wrapper around the userNameToFileName function in filenames.py
Note that existingFileNames should be a set for large glyphsets
or performance will suffer.
""" """
if existingFileNames is None: if existingFileNames is None:
existingFileNames = [] existingFileNames = set()
return userNameToFileName(glyphName, existing=existingFileNames, suffix=".glif") return userNameToFileName(glyphName, existing=existingFileNames, suffix=".glif")
# ----------------------- # -----------------------

View File

@ -159,6 +159,8 @@ class FileNameTest:
dst.writeGlyph("a", glyph) dst.writeGlyph("a", glyph)
dst.writeGlyph("A", glyph) dst.writeGlyph("A", glyph)
dst.writeGlyph("a_", glyph) dst.writeGlyph("a_", glyph)
dst.deleteGlyph("a_")
dst.writeGlyph("a_", glyph)
dst.writeGlyph("A_", glyph) dst.writeGlyph("A_", glyph)
dst.writeGlyph("i_j", glyph) dst.writeGlyph("i_j", glyph)