We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
etymology: Empty argument not handled
Doing `.ety` with no or an empty argument doesn't behave properly.

On Python 2 (my old personal instance), it causes `TypeError: None object cannot be quoted (file "/usr/lib/python2.7/urllib.py", line 1255, in quote)`

On Python 3 ("official" Sopel instance on freenode), the command looks up the etymology of "None" (and gets no results, because of the capital letter).

This is a good, easy issue for first-time contributors to fix.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sopel/modules/etymology.py`
Content:
```
1 # coding=utf-8
2 """
3 etymology.py - Sopel Etymology Module
4 Copyright 2007-9, Sean B. Palmer, inamidst.com
5 Copyright 2018-9, Sopel contributors
6 Licensed under the Eiffel Forum License 2.
7 
8 https://sopel.chat
9 """
10 from __future__ import unicode_literals, absolute_import, print_function, division
11 
12 from re import sub
13 
14 from requests import get
15 
16 from sopel.module import commands, example, NOLIMIT
17 from sopel.tools import web
18 
19 try:
20     # Python 2.7
21     from HTMLParser import HTMLParser
22     h = HTMLParser()
23     unescape = h.unescape
24 except ImportError:
25     try:
26         # Python 3.4+
27         from html import unescape  # https://stackoverflow.com/a/2087433
28     except ImportError:
29         # Python 3.3... sigh
30         from html.parser import HTMLParser
31         h = HTMLParser()
32         unescape = h.unescape
33 
34 
35 ETYURI = 'https://www.etymonline.com/word/%s'
36 ETYSEARCH = 'https://www.etymonline.com/search?q=%s'
37 
38 
39 def etymology(word):
40     # @@ <nsh> sbp, would it be possible to have a flag for .ety to get 2nd/etc
41     # entries? - http://swhack.com/logs/2006-07-19#T15-05-29
42 
43     if len(word) > 25:
44         raise ValueError("Word too long: %s[…]" % word[:10])
45 
46     ety = get(ETYURI % web.quote(word))
47     if ety.status_code != 200:
48         return None
49 
50     # Let's find it
51     start = ety.text.find("word__defination")
52     start = ety.text.find("<p>", start)
53     stop = ety.text.find("</p>", start)
54     sentence = ety.text[start + 3:stop]
55     # Clean up
56     sentence = unescape(sentence)
57     sentence = sub('<[^<]+?>', '', sentence)
58 
59     maxlength = 275
60     if len(sentence) > maxlength:
61         sentence = sentence[:maxlength]
62         words = sentence[:-5].split(' ')
63         words.pop()
64         sentence = ' '.join(words) + ' […]'
65 
66     sentence = '"' + sentence.replace('"', "'") + '"'
67     return sentence + ' - ' + (ETYURI % web.quote(word))
68 
69 
70 @commands('ety')
71 @example('.ety word')
72 def f_etymology(bot, trigger):
73     """Look up the etymology of a word"""
74     word = trigger.group(2)
75 
76     try:
77         result = etymology(word)
78     except IOError:
79         msg = "Can't connect to etymonline.com (%s)" % (ETYURI % web.quote(word))
80         bot.say(msg, trigger.sender)
81         return NOLIMIT
82     except (AttributeError, TypeError):
83         result = None
84     except ValueError as ve:
85         result = str(ve)
86 
87     if result is not None:
88         bot.say(result, trigger.sender)
89     else:
90         uri = ETYSEARCH % web.quote(word)
91         msg = 'Can\'t find the etymology for "%s". Try %s' % (word, uri)
92         bot.say(msg, trigger.sender)
93         return NOLIMIT
94
```
--- 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/sopel/modules/etymology.py b/sopel/modules/etymology.py
--- a/sopel/modules/etymology.py
+++ b/sopel/modules/etymology.py
@@ -40,6 +40,9 @@
     # @@ <nsh> sbp, would it be possible to have a flag for .ety to get 2nd/etc
     # entries? - http://swhack.com/logs/2006-07-19#T15-05-29
 
+    if not word:
+        raise ValueError("No word to look for.")
+
     if len(word) > 25:
         raise ValueError("Word too long: %s[…]" % word[:10])

{"golden_diff": "diff --git a/sopel/modules/etymology.py b/sopel/modules/etymology.py\n--- a/sopel/modules/etymology.py\n+++ b/sopel/modules/etymology.py\n@@ -40,6 +40,9 @@\n     # @@ <nsh> sbp, would it be possible to have a flag for .ety to get 2nd/etc\n     # entries? - http://swhack.com/logs/2006-07-19#T15-05-29\n \n+    if not word:\n+        raise ValueError(\"No word to look for.\")\n+\n     if len(word) > 25:\n         raise ValueError(\"Word too long: %s[\u2026]\" % word[:10])\n", "issue": "etymology: Empty argument not handled\nDoing `.ety` with no or an empty argument doesn't behave properly.\r\n\r\nOn Python 2 (my old personal instance), it causes `TypeError: None object cannot be quoted (file \"/usr/lib/python2.7/urllib.py\", line 1255, in quote)`\r\n\r\nOn Python 3 (\"official\" Sopel instance on freenode), the command looks up the etymology of \"None\" (and gets no results, because of the capital letter).\r\n\r\nThis is a good, easy issue for first-time contributors to fix.\n", "before_files": [{"content": "# coding=utf-8\n\"\"\"\netymology.py - Sopel Etymology Module\nCopyright 2007-9, Sean B. Palmer, inamidst.com\nCopyright 2018-9, Sopel contributors\nLicensed under the Eiffel Forum License 2.\n\nhttps://sopel.chat\n\"\"\"\nfrom __future__ import unicode_literals, absolute_import, print_function, division\n\nfrom re import sub\n\nfrom requests import get\n\nfrom sopel.module import commands, example, NOLIMIT\nfrom sopel.tools import web\n\ntry:\n    # Python 2.7\n    from HTMLParser import HTMLParser\n    h = HTMLParser()\n    unescape = h.unescape\nexcept ImportError:\n    try:\n        # Python 3.4+\n        from html import unescape  # https://stackoverflow.com/a/2087433\n    except ImportError:\n        # Python 3.3... sigh\n        from html.parser import HTMLParser\n        h = HTMLParser()\n        unescape = h.unescape\n\n\nETYURI = 'https://www.etymonline.com/word/%s'\nETYSEARCH = 'https://www.etymonline.com/search?q=%s'\n\n\ndef etymology(word):\n    # @@ <nsh> sbp, would it be possible to have a flag for .ety to get 2nd/etc\n    # entries? - http://swhack.com/logs/2006-07-19#T15-05-29\n\n    if len(word) > 25:\n        raise ValueError(\"Word too long: %s[\u2026]\" % word[:10])\n\n    ety = get(ETYURI % web.quote(word))\n    if ety.status_code != 200:\n        return None\n\n    # Let's find it\n    start = ety.text.find(\"word__defination\")\n    start = ety.text.find(\"<p>\", start)\n    stop = ety.text.find(\"</p>\", start)\n    sentence = ety.text[start + 3:stop]\n    # Clean up\n    sentence = unescape(sentence)\n    sentence = sub('<[^<]+?>', '', sentence)\n\n    maxlength = 275\n    if len(sentence) > maxlength:\n        sentence = sentence[:maxlength]\n        words = sentence[:-5].split(' ')\n        words.pop()\n        sentence = ' '.join(words) + ' [\u2026]'\n\n    sentence = '\"' + sentence.replace('\"', \"'\") + '\"'\n    return sentence + ' - ' + (ETYURI % web.quote(word))\n\n\n@commands('ety')\n@example('.ety word')\ndef f_etymology(bot, trigger):\n    \"\"\"Look up the etymology of a word\"\"\"\n    word = trigger.group(2)\n\n    try:\n        result = etymology(word)\n    except IOError:\n        msg = \"Can't connect to etymonline.com (%s)\" % (ETYURI % web.quote(word))\n        bot.say(msg, trigger.sender)\n        return NOLIMIT\n    except (AttributeError, TypeError):\n        result = None\n    except ValueError as ve:\n        result = str(ve)\n\n    if result is not None:\n        bot.say(result, trigger.sender)\n    else:\n        uri = ETYSEARCH % web.quote(word)\n        msg = 'Can\\'t find the etymology for \"%s\". Try %s' % (word, uri)\n        bot.say(msg, trigger.sender)\n        return NOLIMIT\n", "path": "sopel/modules/etymology.py"}], "after_files": [{"content": "# coding=utf-8\n\"\"\"\netymology.py - Sopel Etymology Module\nCopyright 2007-9, Sean B. Palmer, inamidst.com\nCopyright 2018-9, Sopel contributors\nLicensed under the Eiffel Forum License 2.\n\nhttps://sopel.chat\n\"\"\"\nfrom __future__ import unicode_literals, absolute_import, print_function, division\n\nfrom re import sub\n\nfrom requests import get\n\nfrom sopel.module import commands, example, NOLIMIT\nfrom sopel.tools import web\n\ntry:\n    # Python 2.7\n    from HTMLParser import HTMLParser\n    h = HTMLParser()\n    unescape = h.unescape\nexcept ImportError:\n    try:\n        # Python 3.4+\n        from html import unescape  # https://stackoverflow.com/a/2087433\n    except ImportError:\n        # Python 3.3... sigh\n        from html.parser import HTMLParser\n        h = HTMLParser()\n        unescape = h.unescape\n\n\nETYURI = 'https://www.etymonline.com/word/%s'\nETYSEARCH = 'https://www.etymonline.com/search?q=%s'\n\n\ndef etymology(word):\n    # @@ <nsh> sbp, would it be possible to have a flag for .ety to get 2nd/etc\n    # entries? - http://swhack.com/logs/2006-07-19#T15-05-29\n\n    if not word:\n        raise ValueError(\"No word to look for.\")\n\n    if len(word) > 25:\n        raise ValueError(\"Word too long: %s[\u2026]\" % word[:10])\n\n    ety = get(ETYURI % web.quote(word))\n    if ety.status_code != 200:\n        return None\n\n    # Let's find it\n    start = ety.text.find(\"word__defination\")\n    start = ety.text.find(\"<p>\", start)\n    stop = ety.text.find(\"</p>\", start)\n    sentence = ety.text[start + 3:stop]\n    # Clean up\n    sentence = unescape(sentence)\n    sentence = sub('<[^<]+?>', '', sentence)\n\n    maxlength = 275\n    if len(sentence) > maxlength:\n        sentence = sentence[:maxlength]\n        words = sentence[:-5].split(' ')\n        words.pop()\n        sentence = ' '.join(words) + ' [\u2026]'\n\n    sentence = '\"' + sentence.replace('\"', \"'\") + '\"'\n    return sentence + ' - ' + (ETYURI % web.quote(word))\n\n\n@commands('ety')\n@example('.ety word')\ndef f_etymology(bot, trigger):\n    \"\"\"Look up the etymology of a word\"\"\"\n    word = trigger.group(2)\n\n    try:\n        result = etymology(word)\n    except IOError:\n        msg = \"Can't connect to etymonline.com (%s)\" % (ETYURI % web.quote(word))\n        bot.say(msg, trigger.sender)\n        return NOLIMIT\n    except (AttributeError, TypeError):\n        result = None\n    except ValueError as ve:\n        result = str(ve)\n\n    if result is not None:\n        bot.say(result, trigger.sender)\n    else:\n        uri = ETYSEARCH % web.quote(word)\n        msg = 'Can\\'t find the etymology for \"%s\". Try %s' % (word, uri)\n        bot.say(msg, trigger.sender)\n        return NOLIMIT\n", "path": "sopel/modules/etymology.py"}]}