Move lazy datastructures to misc.lazyTools

This commit is contained in:
Behdad Esfahbod 2023-12-16 20:58:51 -07:00
parent 3806fd2558
commit 3ff2ee61e1
4 changed files with 60 additions and 58 deletions

View File

@ -0,0 +1,42 @@
from collections import UserDict, UserList
__all__ = ["LazyDict", "LazyList"]
class LazyDict(UserDict):
def __init__(self, data):
super().__init__()
self.data = data
def __getitem__(self, k):
v = self.data[k]
if callable(v):
v = v(self, k)
self.data[k] = v
return v
class LazyList(UserList):
def __getitem__(self, k):
if isinstance(k, slice):
indices = range(*k.indices(len(self)))
return [self[i] for i in indices]
v = self.data[k]
if callable(v):
v = v(self, k)
self.data[k] = v
return v
def __add__(self, other):
if isinstance(other, LazyList):
other = list(other)
elif isinstance(other, list):
pass
else:
return NotImplemented
return list(self) + other
def __radd__(self, other):
if not isinstance(other, list):
return NotImplemented
return other + list(self)

View File

@ -1,7 +1,8 @@
from collections import UserDict, deque
from collections import deque
from functools import partial
from fontTools.misc import sstruct
from fontTools.misc.textTools import safeEval
from fontTools.misc.lazyTools import LazyDict
from . import DefaultTable
import array
import itertools
@ -39,19 +40,6 @@ GVAR_HEADER_FORMAT = """
GVAR_HEADER_SIZE = sstruct.calcsize(GVAR_HEADER_FORMAT)
class _LazyDict(UserDict):
def __init__(self, data):
super().__init__()
self.data = data
def __getitem__(self, k):
v = self.data[k]
if callable(v):
v = v(self, k)
self.data[k] = v
return v
def _decompileVarGlyph(self, glyphName):
gid = self.reverseGlyphMap[glyphName]
offsetSize = 2 if self.tableFormat == 0 else 4
@ -143,7 +131,7 @@ class table__g_v_a_r(DefaultTable.DefaultTable):
offsetToData = self.offsetToGlyphVariationData
glyf = ttFont["glyf"]
l = _LazyDict(
l = LazyDict(
{glyphs[gid]: _decompileVarGlyph for gid in range(self.glyphCount)}
)
l.reverseGlyphMap = ttFont.getReverseGlyphMap()

View File

@ -8,6 +8,7 @@ from fontTools.misc.fixedTools import (
)
from fontTools.misc.roundTools import nearestMultipleShortestRepr, otRound
from fontTools.misc.textTools import bytesjoin, tobytes, tostr, pad, safeEval
from fontTools.misc.lazyTools import LazyList
from fontTools.ttLib import getSearchRange
from .otBase import (
CountReference,
@ -108,38 +109,6 @@ def buildConverters(tableSpec, tableNamespace):
return converters, convertersByName
try:
from collections import UserList
except ImportError:
from UserList import UserList
class _LazyList(UserList):
def __getitem__(self, k):
if isinstance(k, slice):
indices = range(*k.indices(len(self)))
return [self[i] for i in indices]
v = self.data[k]
if callable(v):
v = v(self, k)
self.data[k] = v
return v
def __add__(self, other):
if isinstance(other, _LazyList):
other = list(other)
elif isinstance(other, list):
pass
else:
return NotImplemented
return list(self) + other
def __radd__(self, other):
if not isinstance(other, list):
return NotImplemented
return other + list(self)
def _base_converter_read_item(self, i):
self.reader.seek(self.pos + i * self.recordSize)
return self.conv.read(self.reader, self.font, {})
@ -192,7 +161,7 @@ class BaseConverter(object):
l.append(self.read(reader, font, tableDict))
return l
else:
l = _LazyList(_base_converter_read_item for i in range(count))
l = LazyList(_base_converter_read_item for i in range(count))
l.reader = reader.copy()
l.pos = l.reader.pos
l.font = font
@ -1893,7 +1862,7 @@ class CFF2Index(BaseConverter):
lastOffset = offset
return items
else:
l = _LazyList([cff2_index_read_item] * count)
l = LazyList([cff2_index_read_item] * count)
l.reader = reader.copy()
l.offset_pos = l.reader.pos
l.data_pos = l.offset_pos + (count + 1) * offSize

View File

@ -427,9 +427,12 @@ class AATLookupTest(unittest.TestCase):
)
from fontTools.misc.lazyTools import LazyList
class LazyListTest(unittest.TestCase):
def test_slice(self):
ll = otConverters._LazyList([10, 11, 12, 13])
ll = LazyList([10, 11, 12, 13])
sl = ll[:]
self.assertIsNot(sl, ll)
@ -439,8 +442,8 @@ class LazyListTest(unittest.TestCase):
self.assertEqual([11, 12], ll[1:3])
def test_add_both_LazyList(self):
ll1 = otConverters._LazyList([1])
ll2 = otConverters._LazyList([2])
ll1 = LazyList([1])
ll2 = LazyList([2])
l3 = ll1 + ll2
@ -448,7 +451,7 @@ class LazyListTest(unittest.TestCase):
self.assertEqual([1, 2], l3)
def test_add_LazyList_and_list(self):
ll1 = otConverters._LazyList([1])
ll1 = LazyList([1])
l2 = [2]
l3 = ll1 + l2
@ -458,13 +461,13 @@ class LazyListTest(unittest.TestCase):
def test_add_not_implemented(self):
with self.assertRaises(TypeError):
otConverters._LazyList() + 0
LazyList() + 0
with self.assertRaises(TypeError):
otConverters._LazyList() + tuple()
LazyList() + tuple()
def test_radd_list_and_LazyList(self):
l1 = [1]
ll2 = otConverters._LazyList([2])
ll2 = LazyList([2])
l3 = l1 + ll2
@ -473,9 +476,9 @@ class LazyListTest(unittest.TestCase):
def test_radd_not_implemented(self):
with self.assertRaises(TypeError):
0 + otConverters._LazyList()
0 + LazyList()
with self.assertRaises(TypeError):
tuple() + otConverters._LazyList()
tuple() + LazyList()
if __name__ == "__main__":