Default to "\n" for newlinestr instead of None

If newlinestr is None, os.linesep is used, bu it is the third millennium
and we don’t need or want different line endings per-platform.
This commit is contained in:
Khaled Hosny 2021-07-30 03:58:20 +02:00
parent c552a77fea
commit 000bf81700
16 changed files with 36 additions and 45 deletions

View File

@ -11,7 +11,7 @@ INDENT = " "
class XMLWriter(object): class XMLWriter(object):
def __init__(self, fileOrPath, indentwhite=INDENT, idlefunc=None, encoding="utf_8", def __init__(self, fileOrPath, indentwhite=INDENT, idlefunc=None, encoding="utf_8",
newlinestr=None): newlinestr="\n"):
if encoding.lower().replace('-','').replace('_','') != 'utf8': if encoding.lower().replace('-','').replace('_','') != 'utf8':
raise Exception('Only UTF-8 encoding is supported.') raise Exception('Only UTF-8 encoding is supported.')
if fileOrPath == '-': if fileOrPath == '-':

View File

@ -76,7 +76,7 @@ class TTCollection(object):
final.write(file.getvalue()) final.write(file.getvalue())
file.close() file.close()
def saveXML(self, fileOrPath, newlinestr=None, writeVersion=True, **kwargs): def saveXML(self, fileOrPath, newlinestr="\n", writeVersion=True, **kwargs):
from fontTools.misc import xmlWriter from fontTools.misc import xmlWriter
writer = xmlWriter.XMLWriter(fileOrPath, newlinestr=newlinestr) writer = xmlWriter.XMLWriter(fileOrPath, newlinestr=newlinestr)

View File

@ -215,7 +215,7 @@ class TTFont(object):
return writer.reordersTables() return writer.reordersTables()
def saveXML(self, fileOrPath, newlinestr=None, **kwargs): def saveXML(self, fileOrPath, newlinestr="\n", **kwargs):
"""Export the font as TTX (an XML-based text file), or as a series of text """Export the font as TTX (an XML-based text file), or as a series of text
files when splitTables is true. In the latter case, the 'fileOrPath' files when splitTables is true. In the latter case, the 'fileOrPath'
argument should be a path to a directory. argument should be a path to a directory.

View File

@ -122,7 +122,7 @@ class Options(object):
ignoreDecompileErrors = True ignoreDecompileErrors = True
bitmapGlyphDataFormat = 'raw' bitmapGlyphDataFormat = 'raw'
unicodedata = None unicodedata = None
newlinestr = None newlinestr = "\n"
recalcTimestamp = None recalcTimestamp = None
flavor = None flavor = None
useZopfli = False useZopfli = False

View File

@ -29,9 +29,7 @@ def write_checksum(filepaths, stdout_write=False, use_ttx=False, include_tables=
temp_ttx_path = path + ".ttx" temp_ttx_path = path + ".ttx"
tt = TTFont(path) tt = TTFont(path)
# important to keep the newlinestr value defined here as hash values will change across platforms tt.saveXML(temp_ttx_path, skipTables=exclude_tables, tables=include_tables)
# if platform specific newline values are assumed
tt.saveXML(temp_ttx_path, newlinestr="\n", skipTables=exclude_tables, tables=include_tables)
checksum_path = temp_ttx_path checksum_path = temp_ttx_path
else: else:
if include_tables is not None: if include_tables is not None:

View File

@ -108,12 +108,11 @@ class BuilderTest(unittest.TestCase):
lines = [] lines = []
with open(path, "r", encoding="utf-8") as ttx: with open(path, "r", encoding="utf-8") as ttx:
for line in ttx.readlines(): for line in ttx.readlines():
# Elide ttFont attributes because ttLibVersion may change, # Elide ttFont attributes because ttLibVersion may change.
# and use os-native line separators so we can run difflib.
if line.startswith("<ttFont "): if line.startswith("<ttFont "):
lines.append("<ttFont>" + os.linesep) lines.append("<ttFont>\n")
else: else:
lines.append(line.rstrip() + os.linesep) lines.append(line.rstrip() + "\n")
return lines return lines
def expect_ttx(self, font, expected_ttx, replace=None): def expect_ttx(self, font, expected_ttx, replace=None):

View File

@ -4,8 +4,7 @@ import os
import unittest import unittest
from fontTools.misc.xmlWriter import XMLWriter from fontTools.misc.xmlWriter import XMLWriter
linesep = tobytes(os.linesep) HEADER = b'<?xml version="1.0" encoding="UTF-8"?>\n'
HEADER = b'<?xml version="1.0" encoding="UTF-8"?>' + linesep
class TestXMLWriter(unittest.TestCase): class TestXMLWriter(unittest.TestCase):
@ -17,30 +16,30 @@ class TestXMLWriter(unittest.TestCase):
def test_comment_multiline(self): def test_comment_multiline(self):
writer = XMLWriter(BytesIO()) writer = XMLWriter(BytesIO())
writer.comment("Hello world\nHow are you?") writer.comment("Hello world\nHow are you?")
self.assertEqual(HEADER + b"<!-- Hello world" + linesep + b" How are you? -->", self.assertEqual(HEADER + b"<!-- Hello world\n How are you? -->",
writer.file.getvalue()) writer.file.getvalue())
def test_encoding_default(self): def test_encoding_default(self):
writer = XMLWriter(BytesIO()) writer = XMLWriter(BytesIO())
self.assertEqual(b'<?xml version="1.0" encoding="UTF-8"?>' + linesep, self.assertEqual(b'<?xml version="1.0" encoding="UTF-8"?>\n',
writer.file.getvalue()) writer.file.getvalue())
def test_encoding_utf8(self): def test_encoding_utf8(self):
# https://github.com/fonttools/fonttools/issues/246 # https://github.com/fonttools/fonttools/issues/246
writer = XMLWriter(BytesIO(), encoding="utf8") writer = XMLWriter(BytesIO(), encoding="utf8")
self.assertEqual(b'<?xml version="1.0" encoding="UTF-8"?>' + linesep, self.assertEqual(b'<?xml version="1.0" encoding="UTF-8"?>\n',
writer.file.getvalue()) writer.file.getvalue())
def test_encoding_UTF_8(self): def test_encoding_UTF_8(self):
# https://github.com/fonttools/fonttools/issues/246 # https://github.com/fonttools/fonttools/issues/246
writer = XMLWriter(BytesIO(), encoding="UTF-8") writer = XMLWriter(BytesIO(), encoding="UTF-8")
self.assertEqual(b'<?xml version="1.0" encoding="UTF-8"?>' + linesep, self.assertEqual(b'<?xml version="1.0" encoding="UTF-8"?>\n',
writer.file.getvalue()) writer.file.getvalue())
def test_encoding_UTF8(self): def test_encoding_UTF8(self):
# https://github.com/fonttools/fonttools/issues/246 # https://github.com/fonttools/fonttools/issues/246
writer = XMLWriter(BytesIO(), encoding="UTF8") writer = XMLWriter(BytesIO(), encoding="UTF8")
self.assertEqual(b'<?xml version="1.0" encoding="UTF-8"?>' + linesep, self.assertEqual(b'<?xml version="1.0" encoding="UTF-8"?>\n',
writer.file.getvalue()) writer.file.getvalue())
def test_encoding_other(self): def test_encoding_other(self):
@ -61,7 +60,7 @@ class TestXMLWriter(unittest.TestCase):
writer.newline() writer.newline()
writer.dedent() writer.dedent()
writer.write("baz") writer.write("baz")
self.assertEqual(HEADER + bytesjoin(["foo", " bar", "baz"], linesep), self.assertEqual(HEADER + bytesjoin(["foo", " bar", "baz"], "\n"),
writer.file.getvalue()) writer.file.getvalue())
def test_writecdata(self): def test_writecdata(self):
@ -89,7 +88,7 @@ class TestXMLWriter(unittest.TestCase):
"66756c20 67726f75 70206f66 206c6574", "66756c20 67726f75 70206f66 206c6574",
"74657273 2c206e6f 74206120 67726f75", "74657273 2c206e6f 74206120 67726f75",
"70206f66 20626561 75746966 756c206c", "70206f66 20626561 75746966 756c206c",
"65747465 72732e ", ""], joiner=linesep), writer.file.getvalue()) "65747465 72732e ", ""], joiner="\n"), writer.file.getvalue())
def test_stringifyattrs(self): def test_stringifyattrs(self):
writer = XMLWriter(BytesIO()) writer = XMLWriter(BytesIO())

View File

@ -182,14 +182,14 @@ class MtiTest(unittest.TestCase):
decompiled.decompile(blob, font) decompiled.decompile(blob, font)
# XML from built object. # XML from built object.
writer = XMLWriter(StringIO(), newlinestr='\n') writer = XMLWriter(StringIO())
writer.begintag(tableTag); writer.newline() writer.begintag(tableTag); writer.newline()
table.toXML(writer, font) table.toXML(writer, font)
writer.endtag(tableTag); writer.newline() writer.endtag(tableTag); writer.newline()
xml_built = writer.file.getvalue() xml_built = writer.file.getvalue()
# XML from decompiled object. # XML from decompiled object.
writer = XMLWriter(StringIO(), newlinestr='\n') writer = XMLWriter(StringIO())
writer.begintag(tableTag); writer.newline() writer.begintag(tableTag); writer.newline()
decompiled.toXML(writer, font) decompiled.toXML(writer, font)
writer.endtag(tableTag); writer.newline() writer.endtag(tableTag); writer.newline()
@ -208,7 +208,7 @@ class MtiTest(unittest.TestCase):
reader.read(rootless=True) reader.read(rootless=True)
# XML from object read from XML. # XML from object read from XML.
writer = XMLWriter(StringIO(), newlinestr='\n') writer = XMLWriter(StringIO())
writer.begintag(tableTag); writer.newline() writer.begintag(tableTag); writer.newline()
font2[tableTag].toXML(writer, font) font2[tableTag].toXML(writer, font)
writer.endtag(tableTag); writer.newline() writer.endtag(tableTag); writer.newline()

View File

@ -50,12 +50,11 @@ class SubsetTest(unittest.TestCase):
lines = [] lines = []
with open(path, "r", encoding="utf-8") as ttx: with open(path, "r", encoding="utf-8") as ttx:
for line in ttx.readlines(): for line in ttx.readlines():
# Elide ttFont attributes because ttLibVersion may change, # Elide ttFont attributes because ttLibVersion may change.
# and use os-native line separators so we can run difflib.
if line.startswith("<ttFont "): if line.startswith("<ttFont "):
lines.append("<ttFont>" + os.linesep) lines.append("<ttFont>\n")
else: else:
lines.append(line.rstrip() + os.linesep) lines.append(line.rstrip() + "\n")
return lines return lines
def expect_ttx(self, font, expected_ttx, tables=None): def expect_ttx(self, font, expected_ttx, tables=None):

View File

@ -1,7 +1,6 @@
from fontTools.misc.testTools import parseXML from fontTools.misc.testTools import parseXML
from fontTools.misc.xmlWriter import XMLWriter from fontTools.misc.xmlWriter import XMLWriter
from io import BytesIO from io import BytesIO
import os
import struct import struct
import unittest import unittest
from fontTools.ttLib import newTable from fontTools.ttLib import newTable
@ -46,14 +45,14 @@ class Test_l_t_a_g(unittest.TestCase):
table = newTable("ltag") table = newTable("ltag")
table.decompile(self.DATA_, ttFont=None) table.decompile(self.DATA_, ttFont=None)
table.toXML(writer, ttFont=None) table.toXML(writer, ttFont=None)
expected = os.linesep.join([ expected = "\n".join([
'<?xml version="1.0" encoding="UTF-8"?>', '<?xml version="1.0" encoding="UTF-8"?>',
'<version value="1"/>', '<version value="1"/>',
'<flags value="0"/>', '<flags value="0"/>',
'<LanguageTag tag="en"/>', '<LanguageTag tag="en"/>',
'<LanguageTag tag="zh-Hant"/>', '<LanguageTag tag="zh-Hant"/>',
'<LanguageTag tag="zh"/>' '<LanguageTag tag="zh"/>'
]) + os.linesep ]) + "\n"
self.assertEqual(expected.encode("utf_8"), writer.file.getvalue()) self.assertEqual(expected.encode("utf_8"), writer.file.getvalue())

View File

@ -254,7 +254,7 @@ def read_expected_ttx(testfile, tableTag):
def dump_ttx(font, tableTag): def dump_ttx(font, tableTag):
f = StringIO() f = StringIO()
font.saveXML(f, newlinestr='\n', tables=[tableTag]) font.saveXML(f, tables=[tableTag])
return ttLibVersion_RE.sub('', f.getvalue()) return ttLibVersion_RE.sub('', f.getvalue())

View File

@ -104,7 +104,7 @@ class ProgramTest(unittest.TestCase):
p.fromBytecode(BYTECODE) p.fromBytecode(BYTECODE)
ttfont = TestFont() ttfont = TestFont()
buf = StringIO() buf = StringIO()
writer = XMLWriter(buf, newlinestr='\n') writer = XMLWriter(buf)
try: try:
p.toXML(writer, ttfont) p.toXML(writer, ttfont)
finally: finally:

View File

@ -1411,7 +1411,7 @@ def _dump_ttx(ttFont):
tmp.seek(0) tmp.seek(0)
ttFont2 = ttLib.TTFont(tmp, recalcBBoxes=False, recalcTimestamp=False) ttFont2 = ttLib.TTFont(tmp, recalcBBoxes=False, recalcTimestamp=False)
s = StringIO() s = StringIO()
ttFont2.saveXML(s, newlinestr="\n") ttFont2.saveXML(s)
return _strip_ttLibVersion(s.getvalue()) return _strip_ttLibVersion(s.getvalue())

View File

@ -61,12 +61,11 @@ class InterpolateLayoutTest(unittest.TestCase):
lines = [] lines = []
with open(path, "r", encoding="utf-8") as ttx: with open(path, "r", encoding="utf-8") as ttx:
for line in ttx.readlines(): for line in ttx.readlines():
# Elide ttFont attributes because ttLibVersion may change, # Elide ttFont attributes because ttLibVersion may change.
# and use os-native line separators so we can run difflib.
if line.startswith("<ttFont "): if line.startswith("<ttFont "):
lines.append("<ttFont>" + os.linesep) lines.append("<ttFont>\n")
else: else:
lines.append(line.rstrip() + os.linesep) lines.append(line.rstrip() + "\n")
return lines return lines
def expect_ttx(self, font, expected_ttx, tables): def expect_ttx(self, font, expected_ttx, tables):

View File

@ -59,12 +59,11 @@ class MutatorTest(unittest.TestCase):
lines = [] lines = []
with open(path, "r", encoding="utf-8") as ttx: with open(path, "r", encoding="utf-8") as ttx:
for line in ttx.readlines(): for line in ttx.readlines():
# Elide ttFont attributes because ttLibVersion may change, # Elide ttFont attributes because ttLibVersion may change.
# and use os-native line separators so we can run difflib.
if line.startswith("<ttFont "): if line.startswith("<ttFont "):
lines.append("<ttFont>" + os.linesep) lines.append("<ttFont>\n")
else: else:
lines.append(line.rstrip() + os.linesep) lines.append(line.rstrip() + "\n")
return lines return lines
def expect_ttx(self, font, expected_ttx, tables): def expect_ttx(self, font, expected_ttx, tables):

View File

@ -84,12 +84,11 @@ class BuildTest(unittest.TestCase):
lines = [] lines = []
with open(path, "r", encoding="utf-8") as ttx: with open(path, "r", encoding="utf-8") as ttx:
for line in ttx.readlines(): for line in ttx.readlines():
# Elide ttFont attributes because ttLibVersion may change, # Elide ttFont attributes because ttLibVersion may change.
# and use os-native line separators so we can run difflib.
if line.startswith("<ttFont "): if line.startswith("<ttFont "):
lines.append("<ttFont>" + os.linesep) lines.append("<ttFont>\n")
else: else:
lines.append(line.rstrip() + os.linesep) lines.append(line.rstrip() + "\n")
return lines return lines
def expect_ttx(self, font, expected_ttx, tables): def expect_ttx(self, font, expected_ttx, tables):