prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  deploy crashes with state system
  Will investigate later.
  
  ``` pytb
  Traceback (most recent call last):
    File "/home/kwpolska/virtualenvs/nikola-py3/lib/python3.5/site-packages/doit/doit_cmd.py", line 168, in run
      return command.parse_execute(args)
    File "/home/kwpolska/virtualenvs/nikola-py3/lib/python3.5/site-packages/doit/cmd_base.py", line 122, in parse_execute
      return self.execute(params, args)
    File "/home/kwpolska/git/nikola/nikola/plugin_categories.py", line 124, in execute
      return self._execute(options, args)
    File "/home/kwpolska/git/nikola/nikola/plugins/command/deploy.py", line 135, in _execute
      self.site.state.set('last_deploy', new_deploy.isoformat())
    File "/home/kwpolska/git/nikola/nikola/state.py", line 64, in set
      self._save()
    File "/home/kwpolska/git/nikola/nikola/state.py", line 82, in _save
      json.dump(self._local.data, outf, sort_keys=True, indent=2)
    File "/usr/lib64/python3.5/json/__init__.py", line 179, in dump
      fp.write(chunk)
    File "/home/kwpolska/virtualenvs/nikola-py3/lib/python3.5/tempfile.py", line 483, in func_wrapper
      return func(*args, **kwargs)
  TypeError: a bytes-like object is required, not 'str'
  ```
  
  
  </issue>
  <code>
  [start of nikola/state.py]
  1 # -*- coding: utf-8 -*-
  2 
  3 # Copyright © 2012-2016 Roberto Alsina and others.
  4 
  5 # Permission is hereby granted, free of charge, to any
  6 # person obtaining a copy of this software and associated
  7 # documentation files (the "Software"), to deal in the
  8 # Software without restriction, including without limitation
  9 # the rights to use, copy, modify, merge, publish,
  10 # distribute, sublicense, and/or sell copies of the
  11 # Software, and to permit persons to whom the Software is
  12 # furnished to do so, subject to the following conditions:
  13 #
  14 # The above copyright notice and this permission notice
  15 # shall be included in all copies or substantial portions of
  16 # the Software.
  17 #
  18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
  19 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  20 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  21 # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
  22 # OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  23 # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  24 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  25 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26 
  27 """Persistent state implementation."""
  28 
  29 import json
  30 import os
  31 import shutil
  32 import tempfile
  33 import threading
  34 
  35 from . import utils
  36 
  37 
  38 class Persistor():
  39     """Persist stuff in a place.
  40 
  41     This is an intentionally dumb implementation. It is *not* meant to be
  42     fast, or useful for arbitrarily large data. Use lightly.
  43 
  44     Intentionally it has no namespaces, sections, etc. Use as a
  45     responsible adult.
  46     """
  47 
  48     def __init__(self, path):
  49         """Where do you want it persisted."""
  50         self._path = path
  51         utils.makedirs(os.path.dirname(path))
  52         self._local = threading.local()
  53         self._local.data = {}
  54 
  55     def get(self, key):
  56         """Get data stored in key."""
  57         self._read()
  58         return self._local.data.get(key)
  59 
  60     def set(self, key, value):
  61         """Store value in key."""
  62         self._read()
  63         self._local.data[key] = value
  64         self._save()
  65 
  66     def delete(self, key):
  67         """Delete key and the value it contains."""
  68         self._read()
  69         if key in self._local.data:
  70             self._local.data.pop(key)
  71         self._save()
  72 
  73     def _read(self):
  74         if os.path.isfile(self._path):
  75             with open(self._path) as inf:
  76                 self._local.data = json.load(inf)
  77 
  78     def _save(self):
  79         dname = os.path.dirname(self._path)
  80         with tempfile.NamedTemporaryFile(dir=dname, delete=False) as outf:
  81             tname = outf.name
  82             json.dump(self._local.data, outf, sort_keys=True, indent=2)
  83         shutil.move(tname, self._path)
  84
  [end of nikola/state.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/nikola/state.py b/nikola/state.py
  --- a/nikola/state.py
  +++ b/nikola/state.py
  @@ -78,6 +78,11 @@
       def _save(self):
           dname = os.path.dirname(self._path)
           with tempfile.NamedTemporaryFile(dir=dname, delete=False) as outf:
  +            # TODO replace with encoding='utf-8' and mode 'w+' in v8
               tname = outf.name
  -            json.dump(self._local.data, outf, sort_keys=True, indent=2)
  +            data = json.dumps(self._local.data, sort_keys=True, indent=2)
  +            try:
  +                outf.write(data)
  +            except TypeError:
  +                outf.write(data.encode('utf-8'))
           shutil.move(tname, self._path)
  
verification_info: {"golden_diff": "diff --git a/nikola/state.py b/nikola/state.py\n--- a/nikola/state.py\n+++ b/nikola/state.py\n@@ -78,6 +78,11 @@\n     def _save(self):\n         dname = os.path.dirname(self._path)\n         with tempfile.NamedTemporaryFile(dir=dname, delete=False) as outf:\n+            # TODO replace with encoding='utf-8' and mode 'w+' in v8\n             tname = outf.name\n-            json.dump(self._local.data, outf, sort_keys=True, indent=2)\n+            data = json.dumps(self._local.data, sort_keys=True, indent=2)\n+            try:\n+                outf.write(data)\n+            except TypeError:\n+                outf.write(data.encode('utf-8'))\n         shutil.move(tname, self._path)\n", "issue": "deploy crashes with state system\nWill investigate later.\n\n``` pytb\nTraceback (most recent call last):\n  File \"/home/kwpolska/virtualenvs/nikola-py3/lib/python3.5/site-packages/doit/doit_cmd.py\", line 168, in run\n    return command.parse_execute(args)\n  File \"/home/kwpolska/virtualenvs/nikola-py3/lib/python3.5/site-packages/doit/cmd_base.py\", line 122, in parse_execute\n    return self.execute(params, args)\n  File \"/home/kwpolska/git/nikola/nikola/plugin_categories.py\", line 124, in execute\n    return self._execute(options, args)\n  File \"/home/kwpolska/git/nikola/nikola/plugins/command/deploy.py\", line 135, in _execute\n    self.site.state.set('last_deploy', new_deploy.isoformat())\n  File \"/home/kwpolska/git/nikola/nikola/state.py\", line 64, in set\n    self._save()\n  File \"/home/kwpolska/git/nikola/nikola/state.py\", line 82, in _save\n    json.dump(self._local.data, outf, sort_keys=True, indent=2)\n  File \"/usr/lib64/python3.5/json/__init__.py\", line 179, in dump\n    fp.write(chunk)\n  File \"/home/kwpolska/virtualenvs/nikola-py3/lib/python3.5/tempfile.py\", line 483, in func_wrapper\n    return func(*args, **kwargs)\nTypeError: a bytes-like object is required, not 'str'\n```\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Copyright \u00a9 2012-2016 Roberto Alsina and others.\n\n# Permission is hereby granted, free of charge, to any\n# person obtaining a copy of this software and associated\n# documentation files (the \"Software\"), to deal in the\n# Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the\n# Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice\n# shall be included in all copies or substantial portions of\n# the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY\n# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS\n# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\"\"\"Persistent state implementation.\"\"\"\n\nimport json\nimport os\nimport shutil\nimport tempfile\nimport threading\n\nfrom . import utils\n\n\nclass Persistor():\n    \"\"\"Persist stuff in a place.\n\n    This is an intentionally dumb implementation. It is *not* meant to be\n    fast, or useful for arbitrarily large data. Use lightly.\n\n    Intentionally it has no namespaces, sections, etc. Use as a\n    responsible adult.\n    \"\"\"\n\n    def __init__(self, path):\n        \"\"\"Where do you want it persisted.\"\"\"\n        self._path = path\n        utils.makedirs(os.path.dirname(path))\n        self._local = threading.local()\n        self._local.data = {}\n\n    def get(self, key):\n        \"\"\"Get data stored in key.\"\"\"\n        self._read()\n        return self._local.data.get(key)\n\n    def set(self, key, value):\n        \"\"\"Store value in key.\"\"\"\n        self._read()\n        self._local.data[key] = value\n        self._save()\n\n    def delete(self, key):\n        \"\"\"Delete key and the value it contains.\"\"\"\n        self._read()\n        if key in self._local.data:\n            self._local.data.pop(key)\n        self._save()\n\n    def _read(self):\n        if os.path.isfile(self._path):\n            with open(self._path) as inf:\n                self._local.data = json.load(inf)\n\n    def _save(self):\n        dname = os.path.dirname(self._path)\n        with tempfile.NamedTemporaryFile(dir=dname, delete=False) as outf:\n            tname = outf.name\n            json.dump(self._local.data, outf, sort_keys=True, indent=2)\n        shutil.move(tname, self._path)\n", "path": "nikola/state.py"}]}