<commit_before>from fontTools.misc import xmlWriter
from fontTools.misc.textTools import Tag, byteord, tostr
from fontTools.misc.loggingTools import deprecateArgument
from fontTools.ttLib import TTLibError
from fontTools.ttLib.sfnt import SFNTReader, SFNTWriter
from io import BytesIO, StringIO
import os
import logging
import traceback

log = logging.getLogger(__name__)

class TTFont(object):

	"""Represents a TrueType font.

	The object manages file input and output, and offers a convenient way of
	accessing tables. Tables will be only decompiled when necessary, ie. when
	they're actually accessed. This means that simple operations can be extremely fast.

	Example usage::

		>> from fontTools import ttLib
		>> tt = ttLib.TTFont("afont.ttf") # Load an existing font file
		>> tt['maxp'].numGlyphs
		242
		>> tt['OS/2'].achVendID
		'B&H\000'
		>> tt['head'].unitsPerEm
		2048

	For details of the objects returned when accessing each table, see :ref:`tables`.
	To add a table to the font, use the :py:func:`newTable` function::

		>> os2 = newTable("OS/2")
		>> os2.version = 4
		>> # set other attributes
		>> font["OS/2"] = os2

	TrueType fonts can also be serialized to and from XML format (see also the
	:ref:`ttx` binary)::

		>> tt.saveXML("afont.ttx")
		Dumping 'LTSH' table...
		Dumping 'OS/2' table...
		[...]

		>> tt2 = ttLib.TTFont() # Create a new font object
		>> tt2.importXML("afont.ttx")
		>> tt2['maxp'].numGlyphs
		242
	
	The TTFont object may be used as a context manager; this will cause the file
	reader to be closed after the context ``with`` block is exited::

		with TTFont(filename) as f:
			# Do stuff

	Args:
		file: When reading a font from disk, either a pathname pointing to a file,
			or a readable file object.
		res_name_or_index: If running on a Macintosh, either a sfnt resource name or
			an sfnt resource index number. If the index number is zero, TTLib will
			autodetect whether the file is a flat file or a suitcase. (If it is a suitcase,
			only the first 'sfnt' resource will be read.)
		sfntVersion (str): When constructing a font object from scratch, sets the four-byte
			sfnt magic number to be used. Defaults to ``\0\1\0\0`` (TrueType). To create
			an OpenType file, use ``OTTO``.
		flavor (str): Set this to ``woff`` when creating a WOFF file or ``woff2`` for a WOFF2
			file.
		checkChecksums (int): How checksum data should be treated. Default is 0
			(no checking). Set to 1 to check and warn on wrong checksums; set to 2 to
			raise an exception if any wrong checksums are found.
		recalcBBoxes (bool): If true (the default), recalculates ``glyf``, ``CFF ``,
			``head`` bounding box values and ``hhea``/``vhea`` min/max values on save.
			Also compiles the glyphs on importing, which saves memory consumption and
			time.
		ignoreDecompileErrors (bool): If true, exceptions raised during table decompilation
			will be ignored, and the binary data will be returned for those tables instead.
		recalcTimestamp (bool): If true (the default), sets the ``modified`` timestamp in
			the ``head`` table on save.
		fontNumber (int): The index of the font in a TrueType Collection file.
		lazy (bool): If lazy is set to True, many data structures are loaded lazily, upon
			access only. If it is set to False, many data structures are loaded immediately.
			The default is ``lazy=None`` which is somewhere in between.
	"""

	def __init__(self, file=None, res_name_or_index=None,
			sfntVersion="\000\001\000\000", flavor=None, checkChecksums=0,
			verbose=None, recalcBBoxes=True, allowVID=NotImplemented, ignoreDecompileErrors=False,
			recalcTimestamp=True, fontNumber=-1, lazy=None, quiet=None,
			_tableCache=None):
		for name in ("verbose", "quiet"):
			val = locals().get(name)
			if val is not None:
				deprecateArgument(name, "configure logging instead")
			setattr(self, name, val)

		self.lazy = lazy
		self.recalcBBoxes = recalcBBoxes
		self.recalcTimestamp = recalcTimestamp
		self.tables = {}
		self.reader = None
		self.ignoreDecompileErrors = ignoreDecompileErrors

		if not file:
			self.sfntVersion = sfntVersion
			self.flavor = flavor
			self.flavorData = None
			return
		if not hasattr(file, "read"):
			closeStream = True
			# assume file is a string
			if res_name_or_index is not None:
				# see if it contains 'sfnt' resources in the resource or data fork
				from . import macUtils
				if res_name_or_index == 0:
					if macUtils.getSFNTResIndices(file):
						# get the first available sfnt font.
						file = macUtils.SFNTResourceReader(file, 1)
					else:
						file = open(file, "rb")
				else:
					file = macUtils.SFNTResourceReader(file, res_name_or_index)
			else:
				file = open(file, "rb")
		else:
			# assume "file" is a readable file object
			closeStream = False
			file.seek(0)

		if self.lazy is None:
			# read input file in memory and wrap a stream around it to allow overwriting
			file.seek(0)
			tmp = BytesIO(file.read())
			if hasattr(file, 'name'):
				# save reference to input file name
				tmp.name = file.name
			if closeStream:
				file.close()
			file = tmp

		self._tableCache = _tableCache
		self.reader = SFNTReader(file, checkChecksums, fontNumber=fontNumber)
		self.sfntVersion = self.reader.sfntVersion
		self.flavor = self.reader.flavor
		self.flavorData = self.reader.flavorData

		if self.lazy is False:
			# if lazy=False immediately load all the tables
			self.ensureDecompiled()
			if closeStream:
				file.close()

	def __enter__(self):
		return self

	def __exit__(self, type, value, traceback):
		self.close()

	def close(self):
		"""If we still have a reader object, close it."""<commit_msg>TTFont: don't load all tables upon opening even with lazy=False<commit_after>from fontTools.misc import xmlWriter
from fontTools.misc.textTools import Tag, byteord, tostr
from fontTools.misc.loggingTools import deprecateArgument
from fontTools.ttLib import TTLibError
from fontTools.ttLib.sfnt import SFNTReader, SFNTWriter
from io import BytesIO, StringIO
import os
import logging
import traceback

log = logging.getLogger(__name__)

class TTFont(object):

	"""Represents a TrueType font.

	The object manages file input and output, and offers a convenient way of
	accessing tables. Tables will be only decompiled when necessary, ie. when
	they're actually accessed. This means that simple operations can be extremely fast.

	Example usage::

		>> from fontTools import ttLib
		>> tt = ttLib.TTFont("afont.ttf") # Load an existing font file
		>> tt['maxp'].numGlyphs
		242
		>> tt['OS/2'].achVendID
		'B&H\000'
		>> tt['head'].unitsPerEm
		2048

	For details of the objects returned when accessing each table, see :ref:`tables`.
	To add a table to the font, use the :py:func:`newTable` function::

		>> os2 = newTable("OS/2")
		>> os2.version = 4
		>> # set other attributes
		>> font["OS/2"] = os2

	TrueType fonts can also be serialized to and from XML format (see also the
	:ref:`ttx` binary)::

		>> tt.saveXML("afont.ttx")
		Dumping 'LTSH' table...
		Dumping 'OS/2' table...
		[...]

		>> tt2 = ttLib.TTFont() # Create a new font object
		>> tt2.importXML("afont.ttx")
		>> tt2['maxp'].numGlyphs
		242
	
	The TTFont object may be used as a context manager; this will cause the file
	reader to be closed after the context ``with`` block is exited::

		with TTFont(filename) as f:
			# Do stuff

	Args:
		file: When reading a font from disk, either a pathname pointing to a file,
			or a readable file object.
		res_name_or_index: If running on a Macintosh, either a sfnt resource name or
			an sfnt resource index number. If the index number is zero, TTLib will
			autodetect whether the file is a flat file or a suitcase. (If it is a suitcase,
			only the first 'sfnt' resource will be read.)
		sfntVersion (str): When constructing a font object from scratch, sets the four-byte
			sfnt magic number to be used. Defaults to ``\0\1\0\0`` (TrueType). To create
			an OpenType file, use ``OTTO``.
		flavor (str): Set this to ``woff`` when creating a WOFF file or ``woff2`` for a WOFF2
			file.
		checkChecksums (int): How checksum data should be treated. Default is 0
			(no checking). Set to 1 to check and warn on wrong checksums; set to 2 to
			raise an exception if any wrong checksums are found.
		recalcBBoxes (bool): If true (the default), recalculates ``glyf``, ``CFF ``,
			``head`` bounding box values and ``hhea``/``vhea`` min/max values on save.
			Also compiles the glyphs on importing, which saves memory consumption and
			time.
		ignoreDecompileErrors (bool): If true, exceptions raised during table decompilation
			will be ignored, and the binary data will be returned for those tables instead.
		recalcTimestamp (bool): If true (the default), sets the ``modified`` timestamp in
			the ``head`` table on save.
		fontNumber (int): The index of the font in a TrueType Collection file.
		lazy (bool): If lazy is set to True, many data structures are loaded lazily, upon
			access only. If it is set to False, many data structures are loaded immediately.
			The default is ``lazy=None`` which is somewhere in between.
	"""

	def __init__(self, file=None, res_name_or_index=None,
			sfntVersion="\000\001\000\000", flavor=None, checkChecksums=0,
			verbose=None, recalcBBoxes=True, allowVID=NotImplemented, ignoreDecompileErrors=False,
			recalcTimestamp=True, fontNumber=-1, lazy=None, quiet=None,
			_tableCache=None):
		for name in ("verbose", "quiet"):
			val = locals().get(name)
			if val is not None:
				deprecateArgument(name, "configure logging instead")
			setattr(self, name, val)

		self.lazy = lazy
		self.recalcBBoxes = recalcBBoxes
		self.recalcTimestamp = recalcTimestamp
		self.tables = {}
		self.reader = None
		self.ignoreDecompileErrors = ignoreDecompileErrors

		if not file:
			self.sfntVersion = sfntVersion
			self.flavor = flavor
			self.flavorData = None
			return
		if not hasattr(file, "read"):
			closeStream = True
			# assume file is a string
			if res_name_or_index is not None:
				# see if it contains 'sfnt' resources in the resource or data fork
				from . import macUtils
				if res_name_or_index == 0:
					if macUtils.getSFNTResIndices(file):
						# get the first available sfnt font.
						file = macUtils.SFNTResourceReader(file, 1)
					else:
						file = open(file, "rb")
				else:
					file = macUtils.SFNTResourceReader(file, res_name_or_index)
			else:
				file = open(file, "rb")
		else:
			# assume "file" is a readable file object
			closeStream = False
			file.seek(0)

		if not self.lazy:
			# read input file in memory and wrap a stream around it to allow overwriting
			file.seek(0)
			tmp = BytesIO(file.read())
			if hasattr(file, 'name'):
				# save reference to input file name
				tmp.name = file.name
			if closeStream:
				file.close()
			file = tmp
		self._tableCache = _tableCache
		self.reader = SFNTReader(file, checkChecksums, fontNumber=fontNumber)
		self.sfntVersion = self.reader.sfntVersion
		self.flavor = self.reader.flavor
		self.flavorData = self.reader.flavorData

	def __enter__(self):
		return self

	def __exit__(self, type, value, traceback):
		self.close()

	def close(self):
		"""If we still have a reader object, close it."""
{'fraction_non_alphanumeric': 0.09440904603787131, 'fraction_numerical': 0.00915372879834874, 'mean_word_length': 3.7320594479830147, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1854457', 'n_tokens_mistral': 3988, 'n_tokens_neox': 3455, 'n_words': 1340}