prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Attaching binary file using test.attach raises UnicodeDecodeError
  If I attach a png or avi I see the following in OutputTestRecord
  
  Python2.7/site-packages/openhtf/**init**.py", line 185, in OutputTestRecord
      output_cb(test_record)
    File "virtualenv/local/lib/python2.7/site-packages/openhtf/**init**.py", line 83, in **call**
      f.write(self.encode(as_dict))
    File "/usr/lib/python2.7/json/encoder.py", line 209, in encode
      chunks = list(chunks)
    File "/usr/lib/python2.7/json/encoder.py", line 434, in _iterencode
      for chunk in _iterencode_dict(o, _current_indent_level):
    File "/usr/lib/python2.7/json/encoder.py", line 408, in _iterencode_dict
      for chunk in chunks:
    File "/usr/lib/python2.7/json/encoder.py", line 332, in _iterencode_list
      for chunk in chunks:
    File "/usr/lib/python2.7/json/encoder.py", line 408, in _iterencode_dict
      for chunk in chunks:
    File "/usr/lib/python2.7/json/encoder.py", line 408, in _iterencode_dict
      for chunk in chunks:
    File "/usr/lib/python2.7/json/encoder.py", line 390, in _iterencode_dict
      yield _encoder(value)
  UnicodeDecodeError: 'utf8' codec can't decode byte 0x89 in position 0: invalid start byte
  
  
  </issue>
  <code>
  [start of openhtf/io/output/json_factory.py]
  1 """Module for outputting test record to JSON-formatted files."""
  2 
  3 from json import JSONEncoder
  4 
  5 from openhtf import util
  6 from openhtf.exe import test_state
  7 
  8 
  9 class OutputToJSON(JSONEncoder):
  10   """Return an output callback that writes JSON Test Records.
  11 
  12   An example filename_pattern might be:
  13     '/data/test_records/%(dut_id)s.%(start_time_millis)s'
  14 
  15   To use this output mechanism:
  16     test = openhtf.Test(PhaseOne, PhaseTwo)
  17     test.AddOutputCallback(openhtf.OutputToJson(
  18         '/data/test_records/%(dut_id)s.%(start_time_millis)s'))
  19 
  20   Args:
  21     filename_pattern: A format string specifying the filename to write to,
  22       will be formatted with the Test Record as a dictionary.
  23     inline_attachments: Whether attachments should be included inline in the
  24       output.  Set to False if you expect to have large binary attachments.
  25   """
  26 
  27   def __init__(self, filename_pattern=None, inline_attachments=True, **kwargs):
  28     super(OutputToJSON, self).__init__(**kwargs)
  29     self.filename_pattern = filename_pattern
  30     self.inline_attachments = inline_attachments
  31 
  32   def default(self, obj):
  33     if isinstance(obj, BaseException):
  34       # Just repr exceptions.
  35       return repr(obj)
  36     return super(OutputToJSON, self).default(obj)
  37 
  38   # pylint: disable=invalid-name
  39   def __call__(self, test_record):
  40     assert self.filename_pattern, 'filename_pattern required'
  41     if self.inline_attachments:
  42       as_dict = util.ConvertToBaseTypes(test_record)
  43     else:
  44       as_dict = util.ConvertToBaseTypes(test_record, ignore_keys='attachments')
  45     with open(self.filename_pattern % as_dict, 'w') as f:
  46       f.write(self.encode(as_dict))
  47   # pylint: enable=invalid-name
  48
  [end of openhtf/io/output/json_factory.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/openhtf/io/output/json_factory.py b/openhtf/io/output/json_factory.py
  --- a/openhtf/io/output/json_factory.py
  +++ b/openhtf/io/output/json_factory.py
  @@ -1,5 +1,6 @@
   """Module for outputting test record to JSON-formatted files."""
   
  +import base64
   from json import JSONEncoder
   
   from openhtf import util
  @@ -21,7 +22,9 @@
       filename_pattern: A format string specifying the filename to write to,
         will be formatted with the Test Record as a dictionary.
       inline_attachments: Whether attachments should be included inline in the
  -      output.  Set to False if you expect to have large binary attachments.
  +      output. Set to False if you expect to have large binary attachments. If
  +      True (the default), then attachments are base64 encoded to allow for
  +      binary data that's not supported by JSON directly.
     """
   
     def __init__(self, filename_pattern=None, inline_attachments=True, **kwargs):
  @@ -40,6 +43,9 @@
       assert self.filename_pattern, 'filename_pattern required'
       if self.inline_attachments:
         as_dict = util.ConvertToBaseTypes(test_record)
  +      for phase in as_dict['phases']:
  +        for value in phase['attachments'].itervalues():
  +          value['data'] = base64.standard_b64encode(value['data'])
       else:
         as_dict = util.ConvertToBaseTypes(test_record, ignore_keys='attachments')
       with open(self.filename_pattern % as_dict, 'w') as f:
  
verification_info: {"golden_diff": "diff --git a/openhtf/io/output/json_factory.py b/openhtf/io/output/json_factory.py\n--- a/openhtf/io/output/json_factory.py\n+++ b/openhtf/io/output/json_factory.py\n@@ -1,5 +1,6 @@\n \"\"\"Module for outputting test record to JSON-formatted files.\"\"\"\n \n+import base64\n from json import JSONEncoder\n \n from openhtf import util\n@@ -21,7 +22,9 @@\n     filename_pattern: A format string specifying the filename to write to,\n       will be formatted with the Test Record as a dictionary.\n     inline_attachments: Whether attachments should be included inline in the\n-      output.  Set to False if you expect to have large binary attachments.\n+      output. Set to False if you expect to have large binary attachments. If\n+      True (the default), then attachments are base64 encoded to allow for\n+      binary data that's not supported by JSON directly.\n   \"\"\"\n \n   def __init__(self, filename_pattern=None, inline_attachments=True, **kwargs):\n@@ -40,6 +43,9 @@\n     assert self.filename_pattern, 'filename_pattern required'\n     if self.inline_attachments:\n       as_dict = util.ConvertToBaseTypes(test_record)\n+      for phase in as_dict['phases']:\n+        for value in phase['attachments'].itervalues():\n+          value['data'] = base64.standard_b64encode(value['data'])\n     else:\n       as_dict = util.ConvertToBaseTypes(test_record, ignore_keys='attachments')\n     with open(self.filename_pattern % as_dict, 'w') as f:\n", "issue": "Attaching binary file using test.attach raises UnicodeDecodeError\nIf I attach a png or avi I see the following in OutputTestRecord\n\nPython2.7/site-packages/openhtf/**init**.py\", line 185, in OutputTestRecord\n    output_cb(test_record)\n  File \"virtualenv/local/lib/python2.7/site-packages/openhtf/**init**.py\", line 83, in **call**\n    f.write(self.encode(as_dict))\n  File \"/usr/lib/python2.7/json/encoder.py\", line 209, in encode\n    chunks = list(chunks)\n  File \"/usr/lib/python2.7/json/encoder.py\", line 434, in _iterencode\n    for chunk in _iterencode_dict(o, _current_indent_level):\n  File \"/usr/lib/python2.7/json/encoder.py\", line 408, in _iterencode_dict\n    for chunk in chunks:\n  File \"/usr/lib/python2.7/json/encoder.py\", line 332, in _iterencode_list\n    for chunk in chunks:\n  File \"/usr/lib/python2.7/json/encoder.py\", line 408, in _iterencode_dict\n    for chunk in chunks:\n  File \"/usr/lib/python2.7/json/encoder.py\", line 408, in _iterencode_dict\n    for chunk in chunks:\n  File \"/usr/lib/python2.7/json/encoder.py\", line 390, in _iterencode_dict\n    yield _encoder(value)\nUnicodeDecodeError: 'utf8' codec can't decode byte 0x89 in position 0: invalid start byte\n\n", "before_files": [{"content": "\"\"\"Module for outputting test record to JSON-formatted files.\"\"\"\n\nfrom json import JSONEncoder\n\nfrom openhtf import util\nfrom openhtf.exe import test_state\n\n\nclass OutputToJSON(JSONEncoder):\n  \"\"\"Return an output callback that writes JSON Test Records.\n\n  An example filename_pattern might be:\n    '/data/test_records/%(dut_id)s.%(start_time_millis)s'\n\n  To use this output mechanism:\n    test = openhtf.Test(PhaseOne, PhaseTwo)\n    test.AddOutputCallback(openhtf.OutputToJson(\n        '/data/test_records/%(dut_id)s.%(start_time_millis)s'))\n\n  Args:\n    filename_pattern: A format string specifying the filename to write to,\n      will be formatted with the Test Record as a dictionary.\n    inline_attachments: Whether attachments should be included inline in the\n      output.  Set to False if you expect to have large binary attachments.\n  \"\"\"\n\n  def __init__(self, filename_pattern=None, inline_attachments=True, **kwargs):\n    super(OutputToJSON, self).__init__(**kwargs)\n    self.filename_pattern = filename_pattern\n    self.inline_attachments = inline_attachments\n\n  def default(self, obj):\n    if isinstance(obj, BaseException):\n      # Just repr exceptions.\n      return repr(obj)\n    return super(OutputToJSON, self).default(obj)\n\n  # pylint: disable=invalid-name\n  def __call__(self, test_record):\n    assert self.filename_pattern, 'filename_pattern required'\n    if self.inline_attachments:\n      as_dict = util.ConvertToBaseTypes(test_record)\n    else:\n      as_dict = util.ConvertToBaseTypes(test_record, ignore_keys='attachments')\n    with open(self.filename_pattern % as_dict, 'w') as f:\n      f.write(self.encode(as_dict))\n  # pylint: enable=invalid-name\n", "path": "openhtf/io/output/json_factory.py"}]}