Move lazy datastructures to misc.lazyTools
This commit is contained in:
parent
3806fd2558
commit
3ff2ee61e1
42
Lib/fontTools/misc/lazyTools.py
Normal file
42
Lib/fontTools/misc/lazyTools.py
Normal 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)
|
@ -1,7 +1,8 @@
|
|||||||
from collections import UserDict, deque
|
from collections import deque
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from fontTools.misc import sstruct
|
from fontTools.misc import sstruct
|
||||||
from fontTools.misc.textTools import safeEval
|
from fontTools.misc.textTools import safeEval
|
||||||
|
from fontTools.misc.lazyTools import LazyDict
|
||||||
from . import DefaultTable
|
from . import DefaultTable
|
||||||
import array
|
import array
|
||||||
import itertools
|
import itertools
|
||||||
@ -39,19 +40,6 @@ GVAR_HEADER_FORMAT = """
|
|||||||
GVAR_HEADER_SIZE = sstruct.calcsize(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):
|
def _decompileVarGlyph(self, glyphName):
|
||||||
gid = self.reverseGlyphMap[glyphName]
|
gid = self.reverseGlyphMap[glyphName]
|
||||||
offsetSize = 2 if self.tableFormat == 0 else 4
|
offsetSize = 2 if self.tableFormat == 0 else 4
|
||||||
@ -143,7 +131,7 @@ class table__g_v_a_r(DefaultTable.DefaultTable):
|
|||||||
offsetToData = self.offsetToGlyphVariationData
|
offsetToData = self.offsetToGlyphVariationData
|
||||||
glyf = ttFont["glyf"]
|
glyf = ttFont["glyf"]
|
||||||
|
|
||||||
l = _LazyDict(
|
l = LazyDict(
|
||||||
{glyphs[gid]: _decompileVarGlyph for gid in range(self.glyphCount)}
|
{glyphs[gid]: _decompileVarGlyph for gid in range(self.glyphCount)}
|
||||||
)
|
)
|
||||||
l.reverseGlyphMap = ttFont.getReverseGlyphMap()
|
l.reverseGlyphMap = ttFont.getReverseGlyphMap()
|
||||||
|
@ -8,6 +8,7 @@ from fontTools.misc.fixedTools import (
|
|||||||
)
|
)
|
||||||
from fontTools.misc.roundTools import nearestMultipleShortestRepr, otRound
|
from fontTools.misc.roundTools import nearestMultipleShortestRepr, otRound
|
||||||
from fontTools.misc.textTools import bytesjoin, tobytes, tostr, pad, safeEval
|
from fontTools.misc.textTools import bytesjoin, tobytes, tostr, pad, safeEval
|
||||||
|
from fontTools.misc.lazyTools import LazyList
|
||||||
from fontTools.ttLib import getSearchRange
|
from fontTools.ttLib import getSearchRange
|
||||||
from .otBase import (
|
from .otBase import (
|
||||||
CountReference,
|
CountReference,
|
||||||
@ -108,38 +109,6 @@ def buildConverters(tableSpec, tableNamespace):
|
|||||||
return converters, convertersByName
|
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):
|
def _base_converter_read_item(self, i):
|
||||||
self.reader.seek(self.pos + i * self.recordSize)
|
self.reader.seek(self.pos + i * self.recordSize)
|
||||||
return self.conv.read(self.reader, self.font, {})
|
return self.conv.read(self.reader, self.font, {})
|
||||||
@ -192,7 +161,7 @@ class BaseConverter(object):
|
|||||||
l.append(self.read(reader, font, tableDict))
|
l.append(self.read(reader, font, tableDict))
|
||||||
return l
|
return l
|
||||||
else:
|
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.reader = reader.copy()
|
||||||
l.pos = l.reader.pos
|
l.pos = l.reader.pos
|
||||||
l.font = font
|
l.font = font
|
||||||
@ -1893,7 +1862,7 @@ class CFF2Index(BaseConverter):
|
|||||||
lastOffset = offset
|
lastOffset = offset
|
||||||
return items
|
return items
|
||||||
else:
|
else:
|
||||||
l = _LazyList([cff2_index_read_item] * count)
|
l = LazyList([cff2_index_read_item] * count)
|
||||||
l.reader = reader.copy()
|
l.reader = reader.copy()
|
||||||
l.offset_pos = l.reader.pos
|
l.offset_pos = l.reader.pos
|
||||||
l.data_pos = l.offset_pos + (count + 1) * offSize
|
l.data_pos = l.offset_pos + (count + 1) * offSize
|
||||||
|
@ -427,9 +427,12 @@ class AATLookupTest(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
from fontTools.misc.lazyTools import LazyList
|
||||||
|
|
||||||
|
|
||||||
class LazyListTest(unittest.TestCase):
|
class LazyListTest(unittest.TestCase):
|
||||||
def test_slice(self):
|
def test_slice(self):
|
||||||
ll = otConverters._LazyList([10, 11, 12, 13])
|
ll = LazyList([10, 11, 12, 13])
|
||||||
sl = ll[:]
|
sl = ll[:]
|
||||||
|
|
||||||
self.assertIsNot(sl, ll)
|
self.assertIsNot(sl, ll)
|
||||||
@ -439,8 +442,8 @@ class LazyListTest(unittest.TestCase):
|
|||||||
self.assertEqual([11, 12], ll[1:3])
|
self.assertEqual([11, 12], ll[1:3])
|
||||||
|
|
||||||
def test_add_both_LazyList(self):
|
def test_add_both_LazyList(self):
|
||||||
ll1 = otConverters._LazyList([1])
|
ll1 = LazyList([1])
|
||||||
ll2 = otConverters._LazyList([2])
|
ll2 = LazyList([2])
|
||||||
|
|
||||||
l3 = ll1 + ll2
|
l3 = ll1 + ll2
|
||||||
|
|
||||||
@ -448,7 +451,7 @@ class LazyListTest(unittest.TestCase):
|
|||||||
self.assertEqual([1, 2], l3)
|
self.assertEqual([1, 2], l3)
|
||||||
|
|
||||||
def test_add_LazyList_and_list(self):
|
def test_add_LazyList_and_list(self):
|
||||||
ll1 = otConverters._LazyList([1])
|
ll1 = LazyList([1])
|
||||||
l2 = [2]
|
l2 = [2]
|
||||||
|
|
||||||
l3 = ll1 + l2
|
l3 = ll1 + l2
|
||||||
@ -458,13 +461,13 @@ class LazyListTest(unittest.TestCase):
|
|||||||
|
|
||||||
def test_add_not_implemented(self):
|
def test_add_not_implemented(self):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
otConverters._LazyList() + 0
|
LazyList() + 0
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
otConverters._LazyList() + tuple()
|
LazyList() + tuple()
|
||||||
|
|
||||||
def test_radd_list_and_LazyList(self):
|
def test_radd_list_and_LazyList(self):
|
||||||
l1 = [1]
|
l1 = [1]
|
||||||
ll2 = otConverters._LazyList([2])
|
ll2 = LazyList([2])
|
||||||
|
|
||||||
l3 = l1 + ll2
|
l3 = l1 + ll2
|
||||||
|
|
||||||
@ -473,9 +476,9 @@ class LazyListTest(unittest.TestCase):
|
|||||||
|
|
||||||
def test_radd_not_implemented(self):
|
def test_radd_not_implemented(self):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
0 + otConverters._LazyList()
|
0 + LazyList()
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
tuple() + otConverters._LazyList()
|
tuple() + LazyList()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user