We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Initial calculation of unicode table is not atomic
If you're using e.g. pytest-xdist this can result in a corrupt unicode table, which is bad. Instead the file should be created under a temporary name then moved atomically.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/hypothesis/internal/charmap.py`
Content:
```
1 # coding=utf-8
2 #
3 # This file is part of Hypothesis (https://github.com/DRMacIver/hypothesis)
4 #
5 # Most of this work is copyright (C) 2013-2015 David R. MacIver
6 # (david@drmaciver.com), but it contains contributions by others. See
7 # https://github.com/DRMacIver/hypothesis/blob/master/CONTRIBUTING.rst for a
8 # full list of people who may hold copyright, and consult the git log if you
9 # need to determine who owns an individual contribution.
10 #
11 # This Source Code Form is subject to the terms of the Mozilla Public License,
12 # v. 2.0. If a copy of the MPL was not distributed with this file, You can
13 # obtain one at http://mozilla.org/MPL/2.0/.
14 #
15 # END HEADER
16 
17 from __future__ import division, print_function, absolute_import
18 
19 import os
20 import sys
21 import gzip
22 import pickle
23 import unicodedata
24 
25 from hypothesis.configuration import storage_directory
26 from hypothesis.internal.compat import hunichr
27 
28 
29 def charmap_file():
30     return os.path.join(
31         storage_directory('unicodedata', unicodedata.unidata_version),
32         'charmap.pickle.gz'
33     )
34 
35 _charmap = None
36 
37 
38 def charmap():
39     global _charmap
40     if _charmap is None:
41         f = charmap_file()
42         if not os.path.exists(f):
43             _charmap = {}
44             for i in range(0, sys.maxunicode + 1):
45                 cat = unicodedata.category(hunichr(i))
46                 rs = _charmap.setdefault(cat, [])
47                 if rs and rs[-1][-1] == i - 1:
48                     rs[-1][-1] += 1
49                 else:
50                     rs.append([i, i])
51             # We explicitly set the mtime to an arbitary value so as to get
52             # a stable format for our charmap.
53             data = sorted(
54                 (k, tuple((map(tuple, v))))
55                 for k, v in _charmap.items())
56             with gzip.GzipFile(f, 'wb', mtime=1) as o:
57                 o.write(pickle.dumps(data, pickle.HIGHEST_PROTOCOL))
58         with gzip.open(f, 'rb') as i:
59             _charmap = dict(pickle.loads(i.read()))
60     assert _charmap is not None
61     return _charmap
62 
63 
64 _categories = None
65 
66 
67 def categories():
68     global _categories
69     if _categories is None:
70         cm = charmap()
71         _categories = sorted(
72             cm.keys(), key=lambda c: len(cm[c])
73         )
74         _categories.remove('Cc')
75         _categories.remove('Cs')
76         _categories.append('Cc')
77         _categories.append('Cs')
78     return _categories
79 
80 
81 def _union_interval_lists(x, y):
82     if not x:
83         return y
84     if not y:
85         return x
86     intervals = sorted(x + y, reverse=True)
87     result = [intervals.pop()]
88     while intervals:
89         u, v = intervals.pop()
90         a, b = result[-1]
91         if u <= b + 1:
92             result[-1] = (a, v)
93         else:
94             result.append((u, v))
95     return tuple(result)
96 
97 
98 category_index_cache = {
99     (): (),
100 }
101 
102 
103 def _category_key(exclude, include):
104     cs = categories()
105     if include is None:
106         include = set(cs)
107     else:
108         include = set(include)
109     exclude = set(exclude or ())
110     include -= exclude
111     result = tuple(c for c in cs if c in include)
112     return result
113 
114 
115 def _query_for_key(key):
116     try:
117         return category_index_cache[key]
118     except KeyError:
119         pass
120     assert key
121     cs = categories()
122     if len(key) == len(cs):
123         result = ((0, sys.maxunicode),)
124     else:
125         result = _union_interval_lists(
126             _query_for_key(key[:-1]), charmap()[key[-1]]
127         )
128     category_index_cache[key] = result
129     return result
130 
131 
132 limited_category_index_cache = {}
133 
134 
135 def query(
136     exclude_categories=(), include_categories=None,
137     min_codepoint=None, max_codepoint=None
138 ):
139     if min_codepoint is None:
140         min_codepoint = 0
141     if max_codepoint is None:
142         max_codepoint = sys.maxunicode
143     catkey = _category_key(exclude_categories, include_categories)
144     qkey = (catkey, min_codepoint, max_codepoint)
145     try:
146         return limited_category_index_cache[qkey]
147     except KeyError:
148         pass
149     base = _query_for_key(catkey)
150     result = []
151     for u, v in base:
152         if v >= min_codepoint and u <= max_codepoint:
153             result.append((
154                 max(u, min_codepoint), min(v, max_codepoint)
155             ))
156     result = tuple(result)
157     limited_category_index_cache[qkey] = result
158     return result
159
```
--- 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()

```

diff --git a/src/hypothesis/internal/charmap.py b/src/hypothesis/internal/charmap.py
--- a/src/hypothesis/internal/charmap.py
+++ b/src/hypothesis/internal/charmap.py
@@ -20,6 +20,8 @@
 import sys
 import gzip
 import pickle
+import shutil
+import tempfile
 import unicodedata
 
 from hypothesis.configuration import storage_directory
@@ -53,8 +55,13 @@
             data = sorted(
                 (k, tuple((map(tuple, v))))
                 for k, v in _charmap.items())
-            with gzip.GzipFile(f, 'wb', mtime=1) as o:
+
+            # Write the Unicode table atomically
+            _, tmpfile = tempfile.mkstemp()
+            with gzip.GzipFile(tmpfile, 'wb', mtime=1) as o:
                 o.write(pickle.dumps(data, pickle.HIGHEST_PROTOCOL))
+            shutil.move(tmpfile, f)
+
         with gzip.open(f, 'rb') as i:
             _charmap = dict(pickle.loads(i.read()))
     assert _charmap is not None

{"golden_diff": "diff --git a/src/hypothesis/internal/charmap.py b/src/hypothesis/internal/charmap.py\n--- a/src/hypothesis/internal/charmap.py\n+++ b/src/hypothesis/internal/charmap.py\n@@ -20,6 +20,8 @@\n import sys\n import gzip\n import pickle\n+import shutil\n+import tempfile\n import unicodedata\n \n from hypothesis.configuration import storage_directory\n@@ -53,8 +55,13 @@\n             data = sorted(\n                 (k, tuple((map(tuple, v))))\n                 for k, v in _charmap.items())\n-            with gzip.GzipFile(f, 'wb', mtime=1) as o:\n+\n+            # Write the Unicode table atomically\n+            _, tmpfile = tempfile.mkstemp()\n+            with gzip.GzipFile(tmpfile, 'wb', mtime=1) as o:\n                 o.write(pickle.dumps(data, pickle.HIGHEST_PROTOCOL))\n+            shutil.move(tmpfile, f)\n+\n         with gzip.open(f, 'rb') as i:\n             _charmap = dict(pickle.loads(i.read()))\n     assert _charmap is not None\n", "issue": "Initial calculation of unicode table is not atomic\nIf you're using e.g. pytest-xdist this can result in a corrupt unicode table, which is bad. Instead the file should be created under a temporary name then moved atomically.\n\n", "before_files": [{"content": "# coding=utf-8\n#\n# This file is part of Hypothesis (https://github.com/DRMacIver/hypothesis)\n#\n# Most of this work is copyright (C) 2013-2015 David R. MacIver\n# (david@drmaciver.com), but it contains contributions by others. See\n# https://github.com/DRMacIver/hypothesis/blob/master/CONTRIBUTING.rst for a\n# full list of people who may hold copyright, and consult the git log if you\n# need to determine who owns an individual contribution.\n#\n# This Source Code Form is subject to the terms of the Mozilla Public License,\n# v. 2.0. If a copy of the MPL was not distributed with this file, You can\n# obtain one at http://mozilla.org/MPL/2.0/.\n#\n# END HEADER\n\nfrom __future__ import division, print_function, absolute_import\n\nimport os\nimport sys\nimport gzip\nimport pickle\nimport unicodedata\n\nfrom hypothesis.configuration import storage_directory\nfrom hypothesis.internal.compat import hunichr\n\n\ndef charmap_file():\n    return os.path.join(\n        storage_directory('unicodedata', unicodedata.unidata_version),\n        'charmap.pickle.gz'\n    )\n\n_charmap = None\n\n\ndef charmap():\n    global _charmap\n    if _charmap is None:\n        f = charmap_file()\n        if not os.path.exists(f):\n            _charmap = {}\n            for i in range(0, sys.maxunicode + 1):\n                cat = unicodedata.category(hunichr(i))\n                rs = _charmap.setdefault(cat, [])\n                if rs and rs[-1][-1] == i - 1:\n                    rs[-1][-1] += 1\n                else:\n                    rs.append([i, i])\n            # We explicitly set the mtime to an arbitary value so as to get\n            # a stable format for our charmap.\n            data = sorted(\n                (k, tuple((map(tuple, v))))\n                for k, v in _charmap.items())\n            with gzip.GzipFile(f, 'wb', mtime=1) as o:\n                o.write(pickle.dumps(data, pickle.HIGHEST_PROTOCOL))\n        with gzip.open(f, 'rb') as i:\n            _charmap = dict(pickle.loads(i.read()))\n    assert _charmap is not None\n    return _charmap\n\n\n_categories = None\n\n\ndef categories():\n    global _categories\n    if _categories is None:\n        cm = charmap()\n        _categories = sorted(\n            cm.keys(), key=lambda c: len(cm[c])\n        )\n        _categories.remove('Cc')\n        _categories.remove('Cs')\n        _categories.append('Cc')\n        _categories.append('Cs')\n    return _categories\n\n\ndef _union_interval_lists(x, y):\n    if not x:\n        return y\n    if not y:\n        return x\n    intervals = sorted(x + y, reverse=True)\n    result = [intervals.pop()]\n    while intervals:\n        u, v = intervals.pop()\n        a, b = result[-1]\n        if u <= b + 1:\n            result[-1] = (a, v)\n        else:\n            result.append((u, v))\n    return tuple(result)\n\n\ncategory_index_cache = {\n    (): (),\n}\n\n\ndef _category_key(exclude, include):\n    cs = categories()\n    if include is None:\n        include = set(cs)\n    else:\n        include = set(include)\n    exclude = set(exclude or ())\n    include -= exclude\n    result = tuple(c for c in cs if c in include)\n    return result\n\n\ndef _query_for_key(key):\n    try:\n        return category_index_cache[key]\n    except KeyError:\n        pass\n    assert key\n    cs = categories()\n    if len(key) == len(cs):\n        result = ((0, sys.maxunicode),)\n    else:\n        result = _union_interval_lists(\n            _query_for_key(key[:-1]), charmap()[key[-1]]\n        )\n    category_index_cache[key] = result\n    return result\n\n\nlimited_category_index_cache = {}\n\n\ndef query(\n    exclude_categories=(), include_categories=None,\n    min_codepoint=None, max_codepoint=None\n):\n    if min_codepoint is None:\n        min_codepoint = 0\n    if max_codepoint is None:\n        max_codepoint = sys.maxunicode\n    catkey = _category_key(exclude_categories, include_categories)\n    qkey = (catkey, min_codepoint, max_codepoint)\n    try:\n        return limited_category_index_cache[qkey]\n    except KeyError:\n        pass\n    base = _query_for_key(catkey)\n    result = []\n    for u, v in base:\n        if v >= min_codepoint and u <= max_codepoint:\n            result.append((\n                max(u, min_codepoint), min(v, max_codepoint)\n            ))\n    result = tuple(result)\n    limited_category_index_cache[qkey] = result\n    return result\n", "path": "src/hypothesis/internal/charmap.py"}], "after_files": [{"content": "# coding=utf-8\n#\n# This file is part of Hypothesis (https://github.com/DRMacIver/hypothesis)\n#\n# Most of this work is copyright (C) 2013-2015 David R. MacIver\n# (david@drmaciver.com), but it contains contributions by others. See\n# https://github.com/DRMacIver/hypothesis/blob/master/CONTRIBUTING.rst for a\n# full list of people who may hold copyright, and consult the git log if you\n# need to determine who owns an individual contribution.\n#\n# This Source Code Form is subject to the terms of the Mozilla Public License,\n# v. 2.0. If a copy of the MPL was not distributed with this file, You can\n# obtain one at http://mozilla.org/MPL/2.0/.\n#\n# END HEADER\n\nfrom __future__ import division, print_function, absolute_import\n\nimport os\nimport sys\nimport gzip\nimport pickle\nimport shutil\nimport tempfile\nimport unicodedata\n\nfrom hypothesis.configuration import storage_directory\nfrom hypothesis.internal.compat import hunichr\n\n\ndef charmap_file():\n    return os.path.join(\n        storage_directory('unicodedata', unicodedata.unidata_version),\n        'charmap.pickle.gz'\n    )\n\n_charmap = None\n\n\ndef charmap():\n    global _charmap\n    if _charmap is None:\n        f = charmap_file()\n        if not os.path.exists(f):\n            _charmap = {}\n            for i in range(0, sys.maxunicode + 1):\n                cat = unicodedata.category(hunichr(i))\n                rs = _charmap.setdefault(cat, [])\n                if rs and rs[-1][-1] == i - 1:\n                    rs[-1][-1] += 1\n                else:\n                    rs.append([i, i])\n            # We explicitly set the mtime to an arbitary value so as to get\n            # a stable format for our charmap.\n            data = sorted(\n                (k, tuple((map(tuple, v))))\n                for k, v in _charmap.items())\n\n            # Write the Unicode table atomically\n            _, tmpfile = tempfile.mkstemp()\n            with gzip.GzipFile(tmpfile, 'wb', mtime=1) as o:\n                o.write(pickle.dumps(data, pickle.HIGHEST_PROTOCOL))\n            shutil.move(tmpfile, f)\n\n        with gzip.open(f, 'rb') as i:\n            _charmap = dict(pickle.loads(i.read()))\n    assert _charmap is not None\n    return _charmap\n\n\n_categories = None\n\n\ndef categories():\n    global _categories\n    if _categories is None:\n        cm = charmap()\n        _categories = sorted(\n            cm.keys(), key=lambda c: len(cm[c])\n        )\n        _categories.remove('Cc')\n        _categories.remove('Cs')\n        _categories.append('Cc')\n        _categories.append('Cs')\n    return _categories\n\n\ndef _union_interval_lists(x, y):\n    if not x:\n        return y\n    if not y:\n        return x\n    intervals = sorted(x + y, reverse=True)\n    result = [intervals.pop()]\n    while intervals:\n        u, v = intervals.pop()\n        a, b = result[-1]\n        if u <= b + 1:\n            result[-1] = (a, v)\n        else:\n            result.append((u, v))\n    return tuple(result)\n\n\ncategory_index_cache = {\n    (): (),\n}\n\n\ndef _category_key(exclude, include):\n    cs = categories()\n    if include is None:\n        include = set(cs)\n    else:\n        include = set(include)\n    exclude = set(exclude or ())\n    include -= exclude\n    result = tuple(c for c in cs if c in include)\n    return result\n\n\ndef _query_for_key(key):\n    try:\n        return category_index_cache[key]\n    except KeyError:\n        pass\n    assert key\n    cs = categories()\n    if len(key) == len(cs):\n        result = ((0, sys.maxunicode),)\n    else:\n        result = _union_interval_lists(\n            _query_for_key(key[:-1]), charmap()[key[-1]]\n        )\n    category_index_cache[key] = result\n    return result\n\n\nlimited_category_index_cache = {}\n\n\ndef query(\n    exclude_categories=(), include_categories=None,\n    min_codepoint=None, max_codepoint=None\n):\n    if min_codepoint is None:\n        min_codepoint = 0\n    if max_codepoint is None:\n        max_codepoint = sys.maxunicode\n    catkey = _category_key(exclude_categories, include_categories)\n    qkey = (catkey, min_codepoint, max_codepoint)\n    try:\n        return limited_category_index_cache[qkey]\n    except KeyError:\n        pass\n    base = _query_for_key(catkey)\n    result = []\n    for u, v in base:\n        if v >= min_codepoint and u <= max_codepoint:\n            result.append((\n                max(u, min_codepoint), min(v, max_codepoint)\n            ))\n    result = tuple(result)\n    limited_category_index_cache[qkey] = result\n    return result\n", "path": "src/hypothesis/internal/charmap.py"}]}