We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
pre-commit: Add Python linting tool ruff
Add https://beta.ruff.rs to our pre-commit as a replacement for `flake8`, `isort`, `pyupgrade`, etc. but written in Rust instead of Python. It can lint the CPython codebase from scratch in 0.29 seconds.

Adopting Ruff should greatly accelerate our pre-commits and our pre-commit.ci jobs. We will run the new and old tools in parallel for a sprint or two to verify the coverage before we completely drop the old tools.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `openlibrary/catalog/marc/marc_subject.py`
Content:
```
1 """ This entire module is deprecated,
2     openlibrary.catalog.marc.get_subjects is the preferred module
3 """
4 
5 # Tell the flake8 linter to ignore this deprecated file.
6 # flake8: noqa
7 
8 from collections import defaultdict
9 from deprecated import deprecated
10 from lxml import etree
11 import re
12 
13 
14 from openlibrary.catalog.utils.query import get_mc
15 from openlibrary.catalog.get_ia import (
16     get_from_archive,
17     marc_formats,
18     urlopen_keep_trying,
19 )
20 from openlibrary.catalog.marc import get_subjects
21 from openlibrary.catalog.marc.marc_binary import MarcBinary
22 from openlibrary.catalog.marc.marc_xml import (
23     read_marc_file,
24     MarcXml,
25     BlankTag,
26     BadSubtag,
27 )
28 from openlibrary.catalog.utils import (
29     remove_trailing_dot,
30     remove_trailing_number_dot,
31     flip_name,
32 )
33 
34 
35 subject_fields = {'600', '610', '611', '630', '648', '650', '651', '662'}
36 
37 re_flip_name = re.compile('^(.+), ([A-Z].+)$')
38 
39 # 'Rhodes, Dan (Fictitious character)'
40 re_fictitious_character = re.compile(r'^(.+), (.+)( \(.* character\))$')
41 re_etc = re.compile('^(.+?)[, .]+etc[, .]?$', re.I)
42 re_comma = re.compile('^([A-Z])([A-Za-z ]+?) *, ([A-Z][A-Z a-z]+)$')
43 
44 re_place_comma = re.compile('^(.+), (.+)$')
45 re_paren = re.compile('[()]')
46 
47 
48 @deprecated('Use openlibrary.catalog.marc.get_subjects.flip_place() instead.')
49 def flip_place(s):
50     return get_subjects.flip_place(s)
51 
52 
53 @deprecated('Use openlibrary.catalog.marc.get_subjects.flip_subject() instead.')
54 def flip_subject(s):
55     return get_subjects.flip_subject(s)
56 
57 
58 @deprecated('Use openlibrary.catalog.marc.get_subjects.four_types() instead.')
59 def four_types(i):
60     return get_subjects.four_types(i)
61 
62 
63 archive_url = "http://archive.org/download/"
64 
65 
66 @deprecated
67 def load_binary(ia):
68     url = archive_url + ia + '/' + ia + '_meta.mrc'
69     f = urlopen_keep_trying(url)
70     data = f.content
71     assert '<title>Internet Archive: Page Not Found</title>' not in data[:200]
72     if len(data) != int(data[:5]):
73         data = data.decode('utf-8').encode('raw_unicode_escape')
74     if len(data) != int(data[:5]):
75         return
76     return MarcBinary(data)
77 
78 
79 @deprecated
80 def load_xml(ia):
81     url = archive_url + ia + '/' + ia + '_marc.xml'
82     f = urlopen_keep_trying(url)
83     root = etree.fromstring(f.text).getroot()
84     if root.tag == '{http://www.loc.gov/MARC21/slim}collection':
85         root = root[0]
86     return MarcXml(root)
87 
88 
89 @deprecated
90 def subjects_for_work(rec):
91     field_map = {
92         'subject': 'subjects',
93         'place': 'subject_places',
94         'time': 'subject_times',
95         'person': 'subject_people',
96     }
97 
98     subjects = four_types(read_subjects(rec))
99 
100     return {field_map[k]: list(v) for k, v in subjects.items()}
101 
102 
103 re_edition_key = re.compile(r'^/(?:b|books)/(OL\d+M)$')
104 
105 
106 @deprecated
107 def get_subjects_from_ia(ia):
108     formats = marc_formats(ia)
109     if not any(formats.values()):
110         return {}
111     rec = None
112     if formats['bin']:
113         rec = load_binary(ia)
114     if not rec:
115         assert formats['xml']
116         rec = load_xml(ia)
117     return read_subjects(rec)
118 
119 
120 re_ia_marc = re.compile(r'^(?:.*/)?([^/]+)_(marc\.xml|meta\.mrc)(:0:\d+)?$')
121 
122 
123 @deprecated
124 def get_work_subjects(w, do_get_mc=True):
125     found = set()
126     for e in w['editions']:
127         sr = e.get('source_records', [])
128         if sr:
129             for i in sr:
130                 if i.endswith('initial import'):
131                     continue
132                 if i.startswith(('ia:', 'marc:')):
133                     found.add(i)
134                     continue
135         else:
136             mc = None
137             if do_get_mc:
138                 m = re_edition_key.match(e['key'])
139                 mc = get_mc('/b/' + m.group(1))
140             if mc:
141                 if mc.endswith('initial import'):
142                     continue
143                 if not mc.startswith('amazon:') and not re_ia_marc.match(mc):
144                     found.add('marc:' + mc)
145     subjects = []
146     for sr in found:
147         if sr.startswith('marc:ia:'):
148             subjects.append(get_subjects_from_ia(sr[8:]))
149         elif sr.startswith('marc:'):
150             loc = sr[5:]
151             data = get_from_archive(loc)
152             rec = MarcBinary(data)
153             subjects.append(read_subjects(rec))
154         else:
155             assert sr.startswith('ia:')
156             subjects.append(get_subjects_from_ia(sr[3:]))
157     return combine_subjects(subjects)
158 
159 
160 @deprecated('Use openlibrary.catalog.marc.get_subjects.tidy_subject() instead.')
161 def tidy_subject(s):
162     return get_subjects.tidy_subject(s)
163 
164 
165 re_aspects = re.compile(' [Aa]spects$')
166 
167 
168 @deprecated
169 def find_aspects(f):
170     cur = [(i, j) for i, j in f.get_subfields('ax')]
171     if len(cur) < 2 or cur[0][0] != 'a' or cur[1][0] != 'x':
172         return
173     a, x = cur[0][1], cur[1][1]
174     x = x.strip('. ')
175     a = a.strip('. ')
176     if not re_aspects.search(x):
177         return
178     if a == 'Body, Human':
179         a = 'the Human body'
180     return x + ' of ' + flip_subject(a)
181 
182 
183 @deprecated('Use openlibrary.catalog.marc.get_subjects.read_subject() instead.')
184 def read_subjects(rec):
185     return get_subjects.read_subject(s)
186 
187 
188 @deprecated
189 def combine_subjects(subjects):
190     all_subjects = defaultdict(lambda: defaultdict(int))
191     for a in subjects:
192         for b, c in a.items():
193             for d, e in c.items():
194                 all_subjects[b][d] += e
195     return {k: dict(v) for k, v in all_subjects.items()}
196
```
--- 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/openlibrary/catalog/marc/marc_subject.py b/openlibrary/catalog/marc/marc_subject.py
--- a/openlibrary/catalog/marc/marc_subject.py
+++ b/openlibrary/catalog/marc/marc_subject.py
@@ -2,8 +2,8 @@
     openlibrary.catalog.marc.get_subjects is the preferred module
 """
 
-# Tell the flake8 linter to ignore this deprecated file.
-# flake8: noqa
+# Tell the ruff linter to ignore this deprecated file.
+# ruff: noqa
 
 from collections import defaultdict
 from deprecated import deprecated

{"golden_diff": "diff --git a/openlibrary/catalog/marc/marc_subject.py b/openlibrary/catalog/marc/marc_subject.py\n--- a/openlibrary/catalog/marc/marc_subject.py\n+++ b/openlibrary/catalog/marc/marc_subject.py\n@@ -2,8 +2,8 @@\n     openlibrary.catalog.marc.get_subjects is the preferred module\n \"\"\"\n \n-# Tell the flake8 linter to ignore this deprecated file.\n-# flake8: noqa\n+# Tell the ruff linter to ignore this deprecated file.\n+# ruff: noqa\n \n from collections import defaultdict\n from deprecated import deprecated\n", "issue": "pre-commit: Add Python linting tool ruff\nAdd https://beta.ruff.rs to our pre-commit as a replacement for `flake8`, `isort`, `pyupgrade`, etc. but written in Rust instead of Python. It can lint the CPython codebase from scratch in 0.29 seconds.\r\n\r\nAdopting Ruff should greatly accelerate our pre-commits and our pre-commit.ci jobs. We will run the new and old tools in parallel for a sprint or two to verify the coverage before we completely drop the old tools.\n", "before_files": [{"content": "\"\"\" This entire module is deprecated,\n    openlibrary.catalog.marc.get_subjects is the preferred module\n\"\"\"\n\n# Tell the flake8 linter to ignore this deprecated file.\n# flake8: noqa\n\nfrom collections import defaultdict\nfrom deprecated import deprecated\nfrom lxml import etree\nimport re\n\n\nfrom openlibrary.catalog.utils.query import get_mc\nfrom openlibrary.catalog.get_ia import (\n    get_from_archive,\n    marc_formats,\n    urlopen_keep_trying,\n)\nfrom openlibrary.catalog.marc import get_subjects\nfrom openlibrary.catalog.marc.marc_binary import MarcBinary\nfrom openlibrary.catalog.marc.marc_xml import (\n    read_marc_file,\n    MarcXml,\n    BlankTag,\n    BadSubtag,\n)\nfrom openlibrary.catalog.utils import (\n    remove_trailing_dot,\n    remove_trailing_number_dot,\n    flip_name,\n)\n\n\nsubject_fields = {'600', '610', '611', '630', '648', '650', '651', '662'}\n\nre_flip_name = re.compile('^(.+), ([A-Z].+)$')\n\n# 'Rhodes, Dan (Fictitious character)'\nre_fictitious_character = re.compile(r'^(.+), (.+)( \\(.* character\\))$')\nre_etc = re.compile('^(.+?)[, .]+etc[, .]?$', re.I)\nre_comma = re.compile('^([A-Z])([A-Za-z ]+?) *, ([A-Z][A-Z a-z]+)$')\n\nre_place_comma = re.compile('^(.+), (.+)$')\nre_paren = re.compile('[()]')\n\n\n@deprecated('Use openlibrary.catalog.marc.get_subjects.flip_place() instead.')\ndef flip_place(s):\n    return get_subjects.flip_place(s)\n\n\n@deprecated('Use openlibrary.catalog.marc.get_subjects.flip_subject() instead.')\ndef flip_subject(s):\n    return get_subjects.flip_subject(s)\n\n\n@deprecated('Use openlibrary.catalog.marc.get_subjects.four_types() instead.')\ndef four_types(i):\n    return get_subjects.four_types(i)\n\n\narchive_url = \"http://archive.org/download/\"\n\n\n@deprecated\ndef load_binary(ia):\n    url = archive_url + ia + '/' + ia + '_meta.mrc'\n    f = urlopen_keep_trying(url)\n    data = f.content\n    assert '<title>Internet Archive: Page Not Found</title>' not in data[:200]\n    if len(data) != int(data[:5]):\n        data = data.decode('utf-8').encode('raw_unicode_escape')\n    if len(data) != int(data[:5]):\n        return\n    return MarcBinary(data)\n\n\n@deprecated\ndef load_xml(ia):\n    url = archive_url + ia + '/' + ia + '_marc.xml'\n    f = urlopen_keep_trying(url)\n    root = etree.fromstring(f.text).getroot()\n    if root.tag == '{http://www.loc.gov/MARC21/slim}collection':\n        root = root[0]\n    return MarcXml(root)\n\n\n@deprecated\ndef subjects_for_work(rec):\n    field_map = {\n        'subject': 'subjects',\n        'place': 'subject_places',\n        'time': 'subject_times',\n        'person': 'subject_people',\n    }\n\n    subjects = four_types(read_subjects(rec))\n\n    return {field_map[k]: list(v) for k, v in subjects.items()}\n\n\nre_edition_key = re.compile(r'^/(?:b|books)/(OL\\d+M)$')\n\n\n@deprecated\ndef get_subjects_from_ia(ia):\n    formats = marc_formats(ia)\n    if not any(formats.values()):\n        return {}\n    rec = None\n    if formats['bin']:\n        rec = load_binary(ia)\n    if not rec:\n        assert formats['xml']\n        rec = load_xml(ia)\n    return read_subjects(rec)\n\n\nre_ia_marc = re.compile(r'^(?:.*/)?([^/]+)_(marc\\.xml|meta\\.mrc)(:0:\\d+)?$')\n\n\n@deprecated\ndef get_work_subjects(w, do_get_mc=True):\n    found = set()\n    for e in w['editions']:\n        sr = e.get('source_records', [])\n        if sr:\n            for i in sr:\n                if i.endswith('initial import'):\n                    continue\n                if i.startswith(('ia:', 'marc:')):\n                    found.add(i)\n                    continue\n        else:\n            mc = None\n            if do_get_mc:\n                m = re_edition_key.match(e['key'])\n                mc = get_mc('/b/' + m.group(1))\n            if mc:\n                if mc.endswith('initial import'):\n                    continue\n                if not mc.startswith('amazon:') and not re_ia_marc.match(mc):\n                    found.add('marc:' + mc)\n    subjects = []\n    for sr in found:\n        if sr.startswith('marc:ia:'):\n            subjects.append(get_subjects_from_ia(sr[8:]))\n        elif sr.startswith('marc:'):\n            loc = sr[5:]\n            data = get_from_archive(loc)\n            rec = MarcBinary(data)\n            subjects.append(read_subjects(rec))\n        else:\n            assert sr.startswith('ia:')\n            subjects.append(get_subjects_from_ia(sr[3:]))\n    return combine_subjects(subjects)\n\n\n@deprecated('Use openlibrary.catalog.marc.get_subjects.tidy_subject() instead.')\ndef tidy_subject(s):\n    return get_subjects.tidy_subject(s)\n\n\nre_aspects = re.compile(' [Aa]spects$')\n\n\n@deprecated\ndef find_aspects(f):\n    cur = [(i, j) for i, j in f.get_subfields('ax')]\n    if len(cur) < 2 or cur[0][0] != 'a' or cur[1][0] != 'x':\n        return\n    a, x = cur[0][1], cur[1][1]\n    x = x.strip('. ')\n    a = a.strip('. ')\n    if not re_aspects.search(x):\n        return\n    if a == 'Body, Human':\n        a = 'the Human body'\n    return x + ' of ' + flip_subject(a)\n\n\n@deprecated('Use openlibrary.catalog.marc.get_subjects.read_subject() instead.')\ndef read_subjects(rec):\n    return get_subjects.read_subject(s)\n\n\n@deprecated\ndef combine_subjects(subjects):\n    all_subjects = defaultdict(lambda: defaultdict(int))\n    for a in subjects:\n        for b, c in a.items():\n            for d, e in c.items():\n                all_subjects[b][d] += e\n    return {k: dict(v) for k, v in all_subjects.items()}\n", "path": "openlibrary/catalog/marc/marc_subject.py"}], "after_files": [{"content": "\"\"\" This entire module is deprecated,\n    openlibrary.catalog.marc.get_subjects is the preferred module\n\"\"\"\n\n# Tell the ruff linter to ignore this deprecated file.\n# ruff: noqa\n\nfrom collections import defaultdict\nfrom deprecated import deprecated\nfrom lxml import etree\nimport re\n\n\nfrom openlibrary.catalog.utils.query import get_mc\nfrom openlibrary.catalog.get_ia import (\n    get_from_archive,\n    marc_formats,\n    urlopen_keep_trying,\n)\nfrom openlibrary.catalog.marc import get_subjects\nfrom openlibrary.catalog.marc.marc_binary import MarcBinary\nfrom openlibrary.catalog.marc.marc_xml import (\n    read_marc_file,\n    MarcXml,\n    BlankTag,\n    BadSubtag,\n)\nfrom openlibrary.catalog.utils import (\n    remove_trailing_dot,\n    remove_trailing_number_dot,\n    flip_name,\n)\n\n\nsubject_fields = {'600', '610', '611', '630', '648', '650', '651', '662'}\n\nre_flip_name = re.compile('^(.+), ([A-Z].+)$')\n\n# 'Rhodes, Dan (Fictitious character)'\nre_fictitious_character = re.compile(r'^(.+), (.+)( \\(.* character\\))$')\nre_etc = re.compile('^(.+?)[, .]+etc[, .]?$', re.I)\nre_comma = re.compile('^([A-Z])([A-Za-z ]+?) *, ([A-Z][A-Z a-z]+)$')\n\nre_place_comma = re.compile('^(.+), (.+)$')\nre_paren = re.compile('[()]')\n\n\n@deprecated('Use openlibrary.catalog.marc.get_subjects.flip_place() instead.')\ndef flip_place(s):\n    return get_subjects.flip_place(s)\n\n\n@deprecated('Use openlibrary.catalog.marc.get_subjects.flip_subject() instead.')\ndef flip_subject(s):\n    return get_subjects.flip_subject(s)\n\n\n@deprecated('Use openlibrary.catalog.marc.get_subjects.four_types() instead.')\ndef four_types(i):\n    return get_subjects.four_types(i)\n\n\narchive_url = \"http://archive.org/download/\"\n\n\n@deprecated\ndef load_binary(ia):\n    url = archive_url + ia + '/' + ia + '_meta.mrc'\n    f = urlopen_keep_trying(url)\n    data = f.content\n    assert '<title>Internet Archive: Page Not Found</title>' not in data[:200]\n    if len(data) != int(data[:5]):\n        data = data.decode('utf-8').encode('raw_unicode_escape')\n    if len(data) != int(data[:5]):\n        return\n    return MarcBinary(data)\n\n\n@deprecated\ndef load_xml(ia):\n    url = archive_url + ia + '/' + ia + '_marc.xml'\n    f = urlopen_keep_trying(url)\n    root = etree.fromstring(f.text).getroot()\n    if root.tag == '{http://www.loc.gov/MARC21/slim}collection':\n        root = root[0]\n    return MarcXml(root)\n\n\n@deprecated\ndef subjects_for_work(rec):\n    field_map = {\n        'subject': 'subjects',\n        'place': 'subject_places',\n        'time': 'subject_times',\n        'person': 'subject_people',\n    }\n\n    subjects = four_types(read_subjects(rec))\n\n    return {field_map[k]: list(v) for k, v in subjects.items()}\n\n\nre_edition_key = re.compile(r'^/(?:b|books)/(OL\\d+M)$')\n\n\n@deprecated\ndef get_subjects_from_ia(ia):\n    formats = marc_formats(ia)\n    if not any(formats.values()):\n        return {}\n    rec = None\n    if formats['bin']:\n        rec = load_binary(ia)\n    if not rec:\n        assert formats['xml']\n        rec = load_xml(ia)\n    return read_subjects(rec)\n\n\nre_ia_marc = re.compile(r'^(?:.*/)?([^/]+)_(marc\\.xml|meta\\.mrc)(:0:\\d+)?$')\n\n\n@deprecated\ndef get_work_subjects(w, do_get_mc=True):\n    found = set()\n    for e in w['editions']:\n        sr = e.get('source_records', [])\n        if sr:\n            for i in sr:\n                if i.endswith('initial import'):\n                    continue\n                if i.startswith(('ia:', 'marc:')):\n                    found.add(i)\n                    continue\n        else:\n            mc = None\n            if do_get_mc:\n                m = re_edition_key.match(e['key'])\n                mc = get_mc('/b/' + m.group(1))\n            if mc:\n                if mc.endswith('initial import'):\n                    continue\n                if not mc.startswith('amazon:') and not re_ia_marc.match(mc):\n                    found.add('marc:' + mc)\n    subjects = []\n    for sr in found:\n        if sr.startswith('marc:ia:'):\n            subjects.append(get_subjects_from_ia(sr[8:]))\n        elif sr.startswith('marc:'):\n            loc = sr[5:]\n            data = get_from_archive(loc)\n            rec = MarcBinary(data)\n            subjects.append(read_subjects(rec))\n        else:\n            assert sr.startswith('ia:')\n            subjects.append(get_subjects_from_ia(sr[3:]))\n    return combine_subjects(subjects)\n\n\n@deprecated('Use openlibrary.catalog.marc.get_subjects.tidy_subject() instead.')\ndef tidy_subject(s):\n    return get_subjects.tidy_subject(s)\n\n\nre_aspects = re.compile(' [Aa]spects$')\n\n\n@deprecated\ndef find_aspects(f):\n    cur = [(i, j) for i, j in f.get_subfields('ax')]\n    if len(cur) < 2 or cur[0][0] != 'a' or cur[1][0] != 'x':\n        return\n    a, x = cur[0][1], cur[1][1]\n    x = x.strip('. ')\n    a = a.strip('. ')\n    if not re_aspects.search(x):\n        return\n    if a == 'Body, Human':\n        a = 'the Human body'\n    return x + ' of ' + flip_subject(a)\n\n\n@deprecated('Use openlibrary.catalog.marc.get_subjects.read_subject() instead.')\ndef read_subjects(rec):\n    return get_subjects.read_subject(s)\n\n\n@deprecated\ndef combine_subjects(subjects):\n    all_subjects = defaultdict(lambda: defaultdict(int))\n    for a in subjects:\n        for b, c in a.items():\n            for d, e in c.items():\n                all_subjects[b][d] += e\n    return {k: dict(v) for k, v in all_subjects.items()}\n", "path": "openlibrary/catalog/marc/marc_subject.py"}]}