prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Float yMin value: required argument is not an integer
  If a font file has a float value in `yMin`—and I assume equally in `xMin`, `xMax` or `yMax`—it will fail to save with the error `required argument is not an integer` ([`fontTools/misc/sstruct.py in pack at line 75`](https://github.com/fonttools/fonttools/blob/3.40.0/Lib/fontTools/misc/sstruct.py#L75), fonttools v3.40.0).
  
  Trace:
  ```
  fontTools/misc/sstruct.py in pack at line 75
  fontTools/ttLib/tables/_h_e_a_d.py in compile at line 69
  fontTools/ttLib/ttFont.py in getTableData at line 651
  fontTools/ttLib/ttFont.py in _writeTable at line 633
  fontTools/ttLib/ttFont.py in _save at line 212
  fontTools/ttLib/ttFont.py in save at line 173
  ```
  
  Variables at point of error:
  ```python
  formatstring = ">llIIHHQQhhhhHHhhh"
  elements = [
      65536, 
      65601, 
      1208942685, 
      1594834165, 
      3, 
      1000, 
      3551183604, 
      3640213847, 
      -132, 
      -170.009, 
      788, 
      835, 
      0, 
      3, 
      2, 
      0, 
      0
  ]
  ```
  
  As you can see the value `-170.009` would trigger the error. If integers are expected then rounding should probably be applied.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `Lib/fontTools/ttLib/tables/_h_e_a_d.py`
  Content:
  ```
  1 from __future__ import print_function, division, absolute_import
  2 from fontTools.misc.py23 import *
  3 from fontTools.misc import sstruct
  4 from fontTools.misc.textTools import safeEval, num2binary, binary2num
  5 from fontTools.misc.timeTools import timestampFromString, timestampToString, timestampNow
  6 from fontTools.misc.timeTools import epoch_diff as mac_epoch_diff # For backward compat
  7 from . import DefaultTable
  8 import logging
  9 
  10 
  11 log = logging.getLogger(__name__)
  12 
  13 headFormat = """
  14 		>	# big endian
  15 		tableVersion:       16.16F
  16 		fontRevision:       16.16F
  17 		checkSumAdjustment: I
  18 		magicNumber:        I
  19 		flags:              H
  20 		unitsPerEm:         H
  21 		created:            Q
  22 		modified:           Q
  23 		xMin:               h
  24 		yMin:               h
  25 		xMax:               h
  26 		yMax:               h
  27 		macStyle:           H
  28 		lowestRecPPEM:      H
  29 		fontDirectionHint:  h
  30 		indexToLocFormat:   h
  31 		glyphDataFormat:    h
  32 """
  33 
  34 class table__h_e_a_d(DefaultTable.DefaultTable):
  35 
  36 	dependencies = ['maxp', 'loca', 'CFF ']
  37 
  38 	def decompile(self, data, ttFont):
  39 		dummy, rest = sstruct.unpack2(headFormat, data, self)
  40 		if rest:
  41 			# this is quite illegal, but there seem to be fonts out there that do this
  42 			log.warning("extra bytes at the end of 'head' table")
  43 			assert rest == "\0\0"
  44 
  45 		# For timestamp fields, ignore the top four bytes.  Some fonts have
  46 		# bogus values there.  Since till 2038 those bytes only can be zero,
  47 		# ignore them.
  48 		#
  49 		# https://github.com/fonttools/fonttools/issues/99#issuecomment-66776810
  50 		for stamp in 'created', 'modified':
  51 			value = getattr(self, stamp)
  52 			if value > 0xFFFFFFFF:
  53 				log.warning("'%s' timestamp out of range; ignoring top bytes", stamp)
  54 				value &= 0xFFFFFFFF
  55 				setattr(self, stamp, value)
  56 			if value < 0x7C259DC0: # January 1, 1970 00:00:00
  57 				log.warning("'%s' timestamp seems very low; regarding as unix timestamp", stamp)
  58 				value += 0x7C259DC0
  59 				setattr(self, stamp, value)
  60 
  61 	def compile(self, ttFont):
  62 		if ttFont.recalcBBoxes:
  63 			# For TT-flavored fonts, xMin, yMin, xMax and yMax are set in table__m_a_x_p.recalc().
  64 			if 'CFF ' in ttFont:
  65 				topDict = ttFont['CFF '].cff.topDictIndex[0]
  66 				self.xMin, self.yMin, self.xMax, self.yMax = topDict.FontBBox
  67 		if ttFont.recalcTimestamp:
  68 			self.modified = timestampNow()
  69 		data = sstruct.pack(headFormat, self)
  70 		return data
  71 
  72 	def toXML(self, writer, ttFont):
  73 		writer.comment("Most of this table will be recalculated by the compiler")
  74 		writer.newline()
  75 		formatstring, names, fixes = sstruct.getformat(headFormat)
  76 		for name in names:
  77 			value = getattr(self, name)
  78 			if name in ("created", "modified"):
  79 				value = timestampToString(value)
  80 			if name in ("magicNumber", "checkSumAdjustment"):
  81 				if value < 0:
  82 					value = value + 0x100000000
  83 				value = hex(value)
  84 				if value[-1:] == "L":
  85 					value = value[:-1]
  86 			elif name in ("macStyle", "flags"):
  87 				value = num2binary(value, 16)
  88 			writer.simpletag(name, value=value)
  89 			writer.newline()
  90 
  91 	def fromXML(self, name, attrs, content, ttFont):
  92 		value = attrs["value"]
  93 		if name in ("created", "modified"):
  94 			value = timestampFromString(value)
  95 		elif name in ("macStyle", "flags"):
  96 			value = binary2num(value)
  97 		else:
  98 			value = safeEval(value)
  99 		setattr(self, name, value)
  100
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/Lib/fontTools/ttLib/tables/_h_e_a_d.py b/Lib/fontTools/ttLib/tables/_h_e_a_d.py
  --- a/Lib/fontTools/ttLib/tables/_h_e_a_d.py
  +++ b/Lib/fontTools/ttLib/tables/_h_e_a_d.py
  @@ -4,6 +4,7 @@
   from fontTools.misc.textTools import safeEval, num2binary, binary2num
   from fontTools.misc.timeTools import timestampFromString, timestampToString, timestampNow
   from fontTools.misc.timeTools import epoch_diff as mac_epoch_diff # For backward compat
  +from fontTools.misc.arrayTools import intRect
   from . import DefaultTable
   import logging
   
  @@ -63,7 +64,7 @@
   			# For TT-flavored fonts, xMin, yMin, xMax and yMax are set in table__m_a_x_p.recalc().
   			if 'CFF ' in ttFont:
   				topDict = ttFont['CFF '].cff.topDictIndex[0]
  -				self.xMin, self.yMin, self.xMax, self.yMax = topDict.FontBBox
  +				self.xMin, self.yMin, self.xMax, self.yMax = intRect(topDict.FontBBox)
   		if ttFont.recalcTimestamp:
   			self.modified = timestampNow()
   		data = sstruct.pack(headFormat, self)
  
verification_info: {"golden_diff": "diff --git a/Lib/fontTools/ttLib/tables/_h_e_a_d.py b/Lib/fontTools/ttLib/tables/_h_e_a_d.py\n--- a/Lib/fontTools/ttLib/tables/_h_e_a_d.py\n+++ b/Lib/fontTools/ttLib/tables/_h_e_a_d.py\n@@ -4,6 +4,7 @@\n from fontTools.misc.textTools import safeEval, num2binary, binary2num\n from fontTools.misc.timeTools import timestampFromString, timestampToString, timestampNow\n from fontTools.misc.timeTools import epoch_diff as mac_epoch_diff # For backward compat\n+from fontTools.misc.arrayTools import intRect\n from . import DefaultTable\n import logging\n \n@@ -63,7 +64,7 @@\n \t\t\t# For TT-flavored fonts, xMin, yMin, xMax and yMax are set in table__m_a_x_p.recalc().\n \t\t\tif 'CFF ' in ttFont:\n \t\t\t\ttopDict = ttFont['CFF '].cff.topDictIndex[0]\n-\t\t\t\tself.xMin, self.yMin, self.xMax, self.yMax = topDict.FontBBox\n+\t\t\t\tself.xMin, self.yMin, self.xMax, self.yMax = intRect(topDict.FontBBox)\n \t\tif ttFont.recalcTimestamp:\n \t\t\tself.modified = timestampNow()\n \t\tdata = sstruct.pack(headFormat, self)\n", "issue": "Float yMin value: required argument is not an integer\nIf a font file has a float value in `yMin`\u2014and I assume equally in `xMin`, `xMax` or `yMax`\u2014it will fail to save with the error `required argument is not an integer` ([`fontTools/misc/sstruct.py in pack at line 75`](https://github.com/fonttools/fonttools/blob/3.40.0/Lib/fontTools/misc/sstruct.py#L75), fonttools v3.40.0).\r\n\r\nTrace:\r\n```\r\nfontTools/misc/sstruct.py in pack at line 75\r\nfontTools/ttLib/tables/_h_e_a_d.py in compile at line 69\r\nfontTools/ttLib/ttFont.py in getTableData at line 651\r\nfontTools/ttLib/ttFont.py in _writeTable at line 633\r\nfontTools/ttLib/ttFont.py in _save at line 212\r\nfontTools/ttLib/ttFont.py in save at line 173\r\n```\r\n\r\nVariables at point of error:\r\n```python\r\nformatstring = \">llIIHHQQhhhhHHhhh\"\r\nelements = [\r\n    65536, \r\n    65601, \r\n    1208942685, \r\n    1594834165, \r\n    3, \r\n    1000, \r\n    3551183604, \r\n    3640213847, \r\n    -132, \r\n    -170.009, \r\n    788, \r\n    835, \r\n    0, \r\n    3, \r\n    2, \r\n    0, \r\n    0\r\n]\r\n```\r\n\r\nAs you can see the value `-170.009` would trigger the error. If integers are expected then rounding should probably be applied.\n", "before_files": [{"content": "from __future__ import print_function, division, absolute_import\nfrom fontTools.misc.py23 import *\nfrom fontTools.misc import sstruct\nfrom fontTools.misc.textTools import safeEval, num2binary, binary2num\nfrom fontTools.misc.timeTools import timestampFromString, timestampToString, timestampNow\nfrom fontTools.misc.timeTools import epoch_diff as mac_epoch_diff # For backward compat\nfrom . import DefaultTable\nimport logging\n\n\nlog = logging.getLogger(__name__)\n\nheadFormat = \"\"\"\n\t\t>\t# big endian\n\t\ttableVersion:       16.16F\n\t\tfontRevision:       16.16F\n\t\tcheckSumAdjustment: I\n\t\tmagicNumber:        I\n\t\tflags:              H\n\t\tunitsPerEm:         H\n\t\tcreated:            Q\n\t\tmodified:           Q\n\t\txMin:               h\n\t\tyMin:               h\n\t\txMax:               h\n\t\tyMax:               h\n\t\tmacStyle:           H\n\t\tlowestRecPPEM:      H\n\t\tfontDirectionHint:  h\n\t\tindexToLocFormat:   h\n\t\tglyphDataFormat:    h\n\"\"\"\n\nclass table__h_e_a_d(DefaultTable.DefaultTable):\n\n\tdependencies = ['maxp', 'loca', 'CFF ']\n\n\tdef decompile(self, data, ttFont):\n\t\tdummy, rest = sstruct.unpack2(headFormat, data, self)\n\t\tif rest:\n\t\t\t# this is quite illegal, but there seem to be fonts out there that do this\n\t\t\tlog.warning(\"extra bytes at the end of 'head' table\")\n\t\t\tassert rest == \"\\0\\0\"\n\n\t\t# For timestamp fields, ignore the top four bytes.  Some fonts have\n\t\t# bogus values there.  Since till 2038 those bytes only can be zero,\n\t\t# ignore them.\n\t\t#\n\t\t# https://github.com/fonttools/fonttools/issues/99#issuecomment-66776810\n\t\tfor stamp in 'created', 'modified':\n\t\t\tvalue = getattr(self, stamp)\n\t\t\tif value > 0xFFFFFFFF:\n\t\t\t\tlog.warning(\"'%s' timestamp out of range; ignoring top bytes\", stamp)\n\t\t\t\tvalue &= 0xFFFFFFFF\n\t\t\t\tsetattr(self, stamp, value)\n\t\t\tif value < 0x7C259DC0: # January 1, 1970 00:00:00\n\t\t\t\tlog.warning(\"'%s' timestamp seems very low; regarding as unix timestamp\", stamp)\n\t\t\t\tvalue += 0x7C259DC0\n\t\t\t\tsetattr(self, stamp, value)\n\n\tdef compile(self, ttFont):\n\t\tif ttFont.recalcBBoxes:\n\t\t\t# For TT-flavored fonts, xMin, yMin, xMax and yMax are set in table__m_a_x_p.recalc().\n\t\t\tif 'CFF ' in ttFont:\n\t\t\t\ttopDict = ttFont['CFF '].cff.topDictIndex[0]\n\t\t\t\tself.xMin, self.yMin, self.xMax, self.yMax = topDict.FontBBox\n\t\tif ttFont.recalcTimestamp:\n\t\t\tself.modified = timestampNow()\n\t\tdata = sstruct.pack(headFormat, self)\n\t\treturn data\n\n\tdef toXML(self, writer, ttFont):\n\t\twriter.comment(\"Most of this table will be recalculated by the compiler\")\n\t\twriter.newline()\n\t\tformatstring, names, fixes = sstruct.getformat(headFormat)\n\t\tfor name in names:\n\t\t\tvalue = getattr(self, name)\n\t\t\tif name in (\"created\", \"modified\"):\n\t\t\t\tvalue = timestampToString(value)\n\t\t\tif name in (\"magicNumber\", \"checkSumAdjustment\"):\n\t\t\t\tif value < 0:\n\t\t\t\t\tvalue = value + 0x100000000\n\t\t\t\tvalue = hex(value)\n\t\t\t\tif value[-1:] == \"L\":\n\t\t\t\t\tvalue = value[:-1]\n\t\t\telif name in (\"macStyle\", \"flags\"):\n\t\t\t\tvalue = num2binary(value, 16)\n\t\t\twriter.simpletag(name, value=value)\n\t\t\twriter.newline()\n\n\tdef fromXML(self, name, attrs, content, ttFont):\n\t\tvalue = attrs[\"value\"]\n\t\tif name in (\"created\", \"modified\"):\n\t\t\tvalue = timestampFromString(value)\n\t\telif name in (\"macStyle\", \"flags\"):\n\t\t\tvalue = binary2num(value)\n\t\telse:\n\t\t\tvalue = safeEval(value)\n\t\tsetattr(self, name, value)\n", "path": "Lib/fontTools/ttLib/tables/_h_e_a_d.py"}], "after_files": [{"content": "from __future__ import print_function, division, absolute_import\nfrom fontTools.misc.py23 import *\nfrom fontTools.misc import sstruct\nfrom fontTools.misc.textTools import safeEval, num2binary, binary2num\nfrom fontTools.misc.timeTools import timestampFromString, timestampToString, timestampNow\nfrom fontTools.misc.timeTools import epoch_diff as mac_epoch_diff # For backward compat\nfrom fontTools.misc.arrayTools import intRect\nfrom . import DefaultTable\nimport logging\n\n\nlog = logging.getLogger(__name__)\n\nheadFormat = \"\"\"\n\t\t>\t# big endian\n\t\ttableVersion:       16.16F\n\t\tfontRevision:       16.16F\n\t\tcheckSumAdjustment: I\n\t\tmagicNumber:        I\n\t\tflags:              H\n\t\tunitsPerEm:         H\n\t\tcreated:            Q\n\t\tmodified:           Q\n\t\txMin:               h\n\t\tyMin:               h\n\t\txMax:               h\n\t\tyMax:               h\n\t\tmacStyle:           H\n\t\tlowestRecPPEM:      H\n\t\tfontDirectionHint:  h\n\t\tindexToLocFormat:   h\n\t\tglyphDataFormat:    h\n\"\"\"\n\nclass table__h_e_a_d(DefaultTable.DefaultTable):\n\n\tdependencies = ['maxp', 'loca', 'CFF ']\n\n\tdef decompile(self, data, ttFont):\n\t\tdummy, rest = sstruct.unpack2(headFormat, data, self)\n\t\tif rest:\n\t\t\t# this is quite illegal, but there seem to be fonts out there that do this\n\t\t\tlog.warning(\"extra bytes at the end of 'head' table\")\n\t\t\tassert rest == \"\\0\\0\"\n\n\t\t# For timestamp fields, ignore the top four bytes.  Some fonts have\n\t\t# bogus values there.  Since till 2038 those bytes only can be zero,\n\t\t# ignore them.\n\t\t#\n\t\t# https://github.com/fonttools/fonttools/issues/99#issuecomment-66776810\n\t\tfor stamp in 'created', 'modified':\n\t\t\tvalue = getattr(self, stamp)\n\t\t\tif value > 0xFFFFFFFF:\n\t\t\t\tlog.warning(\"'%s' timestamp out of range; ignoring top bytes\", stamp)\n\t\t\t\tvalue &= 0xFFFFFFFF\n\t\t\t\tsetattr(self, stamp, value)\n\t\t\tif value < 0x7C259DC0: # January 1, 1970 00:00:00\n\t\t\t\tlog.warning(\"'%s' timestamp seems very low; regarding as unix timestamp\", stamp)\n\t\t\t\tvalue += 0x7C259DC0\n\t\t\t\tsetattr(self, stamp, value)\n\n\tdef compile(self, ttFont):\n\t\tif ttFont.recalcBBoxes:\n\t\t\t# For TT-flavored fonts, xMin, yMin, xMax and yMax are set in table__m_a_x_p.recalc().\n\t\t\tif 'CFF ' in ttFont:\n\t\t\t\ttopDict = ttFont['CFF '].cff.topDictIndex[0]\n\t\t\t\tself.xMin, self.yMin, self.xMax, self.yMax = intRect(topDict.FontBBox)\n\t\tif ttFont.recalcTimestamp:\n\t\t\tself.modified = timestampNow()\n\t\tdata = sstruct.pack(headFormat, self)\n\t\treturn data\n\n\tdef toXML(self, writer, ttFont):\n\t\twriter.comment(\"Most of this table will be recalculated by the compiler\")\n\t\twriter.newline()\n\t\tformatstring, names, fixes = sstruct.getformat(headFormat)\n\t\tfor name in names:\n\t\t\tvalue = getattr(self, name)\n\t\t\tif name in (\"created\", \"modified\"):\n\t\t\t\tvalue = timestampToString(value)\n\t\t\tif name in (\"magicNumber\", \"checkSumAdjustment\"):\n\t\t\t\tif value < 0:\n\t\t\t\t\tvalue = value + 0x100000000\n\t\t\t\tvalue = hex(value)\n\t\t\t\tif value[-1:] == \"L\":\n\t\t\t\t\tvalue = value[:-1]\n\t\t\telif name in (\"macStyle\", \"flags\"):\n\t\t\t\tvalue = num2binary(value, 16)\n\t\t\twriter.simpletag(name, value=value)\n\t\t\twriter.newline()\n\n\tdef fromXML(self, name, attrs, content, ttFont):\n\t\tvalue = attrs[\"value\"]\n\t\tif name in (\"created\", \"modified\"):\n\t\t\tvalue = timestampFromString(value)\n\t\telif name in (\"macStyle\", \"flags\"):\n\t\t\tvalue = binary2num(value)\n\t\telse:\n\t\t\tvalue = safeEval(value)\n\t\tsetattr(self, name, value)\n", "path": "Lib/fontTools/ttLib/tables/_h_e_a_d.py"}]}