prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Creation of temporary files in requirements/ can cause provision to fail
  An example to trigger this for me is was as follows:
  * `cd requirements/`
  * edit file using editor which creates temporary file in this location (eg vim, depending on configuration)
  * `tools/provision`
  * provision fails with an error like
  ```
  UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcd in position 17: invalid continuation byte
  ```
  
  This appears to be due to the venv management script not being able to handle the unexpected file produced by eg. vim.
  
  This is not a major issue, but is a bit of a strange issue to debug if you are not expecting it or are new, and potentially could be easy to fix.
  
  </issue>
  <code>
  [start of scripts/lib/clean_venv_cache.py]
  1 #!/usr/bin/env python3
  2 import argparse
  3 import os
  4 import sys
  5 
  6 from typing import Set
  7 
  8 ZULIP_PATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  9 sys.path.append(ZULIP_PATH)
  10 from scripts.lib.hash_reqs import expand_reqs, hash_deps
  11 from scripts.lib.zulip_tools import \
  12     get_environment, get_recent_deployments, parse_cache_script_args, \
  13     purge_unused_caches
  14 
  15 ENV = get_environment()
  16 VENV_CACHE_DIR = '/srv/zulip-venv-cache'
  17 if ENV == "travis":
  18     VENV_CACHE_DIR = os.path.join(os.environ["HOME"], "zulip-venv-cache")
  19 
  20 def get_caches_in_use(threshold_days):
  21     # type: (int) -> Set[str]
  22     setups_to_check = set([ZULIP_PATH, ])
  23     caches_in_use = set()
  24 
  25     def add_current_venv_cache(venv_name: str) -> None:
  26         CACHE_SYMLINK = os.path.join(os.path.dirname(ZULIP_PATH), venv_name)
  27         CURRENT_CACHE = os.path.dirname(os.path.realpath(CACHE_SYMLINK))
  28         caches_in_use.add(CURRENT_CACHE)
  29 
  30     if ENV == "prod":
  31         setups_to_check |= get_recent_deployments(threshold_days)
  32     if ENV == "dev":
  33         add_current_venv_cache("zulip-py3-venv")
  34         add_current_venv_cache("zulip-thumbor-venv")
  35 
  36     for path in setups_to_check:
  37         reqs_dir = os.path.join(path, "requirements")
  38         # If the target directory doesn't contain a requirements
  39         # directory, skip it to avoid throwing an exception trying to
  40         # list its requirements subdirectory.
  41         if not os.path.exists(reqs_dir):
  42             continue
  43         for filename in os.listdir(reqs_dir):
  44             requirements_file = os.path.join(reqs_dir, filename)
  45             deps = expand_reqs(requirements_file)
  46             hash_val = hash_deps(deps)
  47             caches_in_use.add(os.path.join(VENV_CACHE_DIR, hash_val))
  48 
  49     return caches_in_use
  50 
  51 def main(args: argparse.Namespace) -> None:
  52     caches_in_use = get_caches_in_use(args.threshold_days)
  53     purge_unused_caches(
  54         VENV_CACHE_DIR, caches_in_use, "venv cache", args)
  55 
  56 if __name__ == "__main__":
  57     args = parse_cache_script_args("This script cleans unused zulip venv caches.")
  58     main(args)
  59
  [end of scripts/lib/clean_venv_cache.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/scripts/lib/clean_venv_cache.py b/scripts/lib/clean_venv_cache.py
  --- a/scripts/lib/clean_venv_cache.py
  +++ b/scripts/lib/clean_venv_cache.py
  @@ -1,5 +1,6 @@
   #!/usr/bin/env python3
   import argparse
  +import glob
   import os
   import sys
   
  @@ -40,8 +41,8 @@
           # list its requirements subdirectory.
           if not os.path.exists(reqs_dir):
               continue
  -        for filename in os.listdir(reqs_dir):
  -            requirements_file = os.path.join(reqs_dir, filename)
  +        requirements_files = glob.glob(os.path.join(reqs_dir, "*.txt"))
  +        for requirements_file in requirements_files:
               deps = expand_reqs(requirements_file)
               hash_val = hash_deps(deps)
               caches_in_use.add(os.path.join(VENV_CACHE_DIR, hash_val))
  
verification_info: {"golden_diff": "diff --git a/scripts/lib/clean_venv_cache.py b/scripts/lib/clean_venv_cache.py\n--- a/scripts/lib/clean_venv_cache.py\n+++ b/scripts/lib/clean_venv_cache.py\n@@ -1,5 +1,6 @@\n #!/usr/bin/env python3\n import argparse\n+import glob\n import os\n import sys\n \n@@ -40,8 +41,8 @@\n         # list its requirements subdirectory.\n         if not os.path.exists(reqs_dir):\n             continue\n-        for filename in os.listdir(reqs_dir):\n-            requirements_file = os.path.join(reqs_dir, filename)\n+        requirements_files = glob.glob(os.path.join(reqs_dir, \"*.txt\"))\n+        for requirements_file in requirements_files:\n             deps = expand_reqs(requirements_file)\n             hash_val = hash_deps(deps)\n             caches_in_use.add(os.path.join(VENV_CACHE_DIR, hash_val))\n", "issue": "Creation of temporary files in requirements/ can cause provision to fail\nAn example to trigger this for me is was as follows:\r\n* `cd requirements/`\r\n* edit file using editor which creates temporary file in this location (eg vim, depending on configuration)\r\n* `tools/provision`\r\n* provision fails with an error like\r\n```\r\nUnicodeDecodeError: 'utf-8' codec can't decode byte 0xcd in position 17: invalid continuation byte\r\n```\r\n\r\nThis appears to be due to the venv management script not being able to handle the unexpected file produced by eg. vim.\r\n\r\nThis is not a major issue, but is a bit of a strange issue to debug if you are not expecting it or are new, and potentially could be easy to fix.\n", "before_files": [{"content": "#!/usr/bin/env python3\nimport argparse\nimport os\nimport sys\n\nfrom typing import Set\n\nZULIP_PATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))\nsys.path.append(ZULIP_PATH)\nfrom scripts.lib.hash_reqs import expand_reqs, hash_deps\nfrom scripts.lib.zulip_tools import \\\n    get_environment, get_recent_deployments, parse_cache_script_args, \\\n    purge_unused_caches\n\nENV = get_environment()\nVENV_CACHE_DIR = '/srv/zulip-venv-cache'\nif ENV == \"travis\":\n    VENV_CACHE_DIR = os.path.join(os.environ[\"HOME\"], \"zulip-venv-cache\")\n\ndef get_caches_in_use(threshold_days):\n    # type: (int) -> Set[str]\n    setups_to_check = set([ZULIP_PATH, ])\n    caches_in_use = set()\n\n    def add_current_venv_cache(venv_name: str) -> None:\n        CACHE_SYMLINK = os.path.join(os.path.dirname(ZULIP_PATH), venv_name)\n        CURRENT_CACHE = os.path.dirname(os.path.realpath(CACHE_SYMLINK))\n        caches_in_use.add(CURRENT_CACHE)\n\n    if ENV == \"prod\":\n        setups_to_check |= get_recent_deployments(threshold_days)\n    if ENV == \"dev\":\n        add_current_venv_cache(\"zulip-py3-venv\")\n        add_current_venv_cache(\"zulip-thumbor-venv\")\n\n    for path in setups_to_check:\n        reqs_dir = os.path.join(path, \"requirements\")\n        # If the target directory doesn't contain a requirements\n        # directory, skip it to avoid throwing an exception trying to\n        # list its requirements subdirectory.\n        if not os.path.exists(reqs_dir):\n            continue\n        for filename in os.listdir(reqs_dir):\n            requirements_file = os.path.join(reqs_dir, filename)\n            deps = expand_reqs(requirements_file)\n            hash_val = hash_deps(deps)\n            caches_in_use.add(os.path.join(VENV_CACHE_DIR, hash_val))\n\n    return caches_in_use\n\ndef main(args: argparse.Namespace) -> None:\n    caches_in_use = get_caches_in_use(args.threshold_days)\n    purge_unused_caches(\n        VENV_CACHE_DIR, caches_in_use, \"venv cache\", args)\n\nif __name__ == \"__main__\":\n    args = parse_cache_script_args(\"This script cleans unused zulip venv caches.\")\n    main(args)\n", "path": "scripts/lib/clean_venv_cache.py"}]}