prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  wikipedia: may trigger other Sopel instances
  Reported by `sloopy` in IRC. bot2-. uses prefix `.` and bot1-# uses `#`
  
  ```
  <sloopy> .w Star Trek
  <bot2-.> [WIKIPEDIA] Star Trek | "Star Trek is an American science fiction entertainment franchise created by Gene Roddenberry and owned by CBS and Paramount Pictures. The television series Star Trek: The Original Series, Star Trek: The Animated Series, Star Trek: The Next Generation, Star Trek: Deep Space Nine, Star Trek: Voyager, Star..." | https://en.wikipedia.org/wiki/Star_Trek
  <bot1-#> [WIKIPEDIA] Star Trek | "Star Trek is an American science fiction entertainment franchise created by Gene Roddenberry and owned by CBS and Paramount Pictures. The television series Star Trek: The Original Series, Star Trek: The Animated Series, Star Trek: The Next Generation, Star Trek: Deep Space Nine, Star Trek: Voyager, Star..."
  ```
  
  
  --- 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/wikipedia.py`
  Content:
  ```
  1 # coding=utf-8
  2 # Copyright 2013 Elsie Powell - embolalia.com
  3 # Licensed under the Eiffel Forum License 2.
  4 from __future__ import unicode_literals, absolute_import, print_function, division
  5 
  6 from sopel import tools
  7 from sopel.config.types import StaticSection, ValidatedAttribute
  8 from sopel.module import NOLIMIT, commands, example, rule
  9 from requests import get
  10 import re
  11 
  12 import sys
  13 if sys.version_info.major < 3:
  14     from urllib import quote as _quote
  15     from urlparse import unquote as _unquote
  16     quote = lambda s: _quote(s.encode('utf-8')).decode('utf-8')
  17     unquote = lambda s: _unquote(s.encode('utf-8')).decode('utf-8')
  18 else:
  19     from urllib.parse import quote, unquote
  20 
  21 REDIRECT = re.compile(r'^REDIRECT (.*)')
  22 
  23 
  24 class WikipediaSection(StaticSection):
  25     default_lang = ValidatedAttribute('default_lang', default='en')
  26     """The default language to find articles from."""
  27     lang_per_channel = ValidatedAttribute('lang_per_channel')
  28 
  29 
  30 def setup(bot):
  31     bot.config.define_section('wikipedia', WikipediaSection)
  32 
  33     regex = re.compile('([a-z]+).(wikipedia.org/wiki/)([^ ]+)')
  34     if not bot.memory.contains('url_callbacks'):
  35         bot.memory['url_callbacks'] = tools.SopelMemory()
  36     bot.memory['url_callbacks'][regex] = mw_info
  37 
  38 
  39 def configure(config):
  40     config.define_section('wikipedia', WikipediaSection)
  41     config.wikipedia.configure_setting(
  42         'default_lang',
  43         "Enter the default language to find articles from."
  44     )
  45 
  46 
  47 def mw_search(server, query, num):
  48     """
  49     Searches the specified MediaWiki server for the given query, and returns
  50     the specified number of results.
  51     """
  52     search_url = ('http://%s/w/api.php?format=json&action=query'
  53                   '&list=search&srlimit=%d&srprop=timestamp&srwhat=text'
  54                   '&srsearch=') % (server, num)
  55     search_url += query
  56     query = get(search_url).json()
  57     if 'query' in query:
  58         query = query['query']['search']
  59         return [r['title'] for r in query]
  60     else:
  61         return None
  62 
  63 
  64 def say_snippet(bot, server, query, show_url=True):
  65     page_name = query.replace('_', ' ')
  66     query = quote(query.replace(' ', '_'))
  67     try:
  68         snippet = mw_snippet(server, query)
  69     except KeyError:
  70         if show_url:
  71             bot.say("[WIKIPEDIA] Error fetching snippet for \"{}\".".format(page_name))
  72         return
  73     msg = '[WIKIPEDIA] {} | "{}"'.format(page_name, snippet)
  74     if show_url:
  75         msg = msg + ' | https://{}/wiki/{}'.format(server, query)
  76     bot.say(msg)
  77 
  78 
  79 def mw_snippet(server, query):
  80     """
  81     Retrives a snippet of the specified length from the given page on the given
  82     server.
  83     """
  84     snippet_url = ('https://' + server + '/w/api.php?format=json'
  85                    '&action=query&prop=extracts&exintro&explaintext'
  86                    '&exchars=300&redirects&titles=')
  87     snippet_url += query
  88     snippet = get(snippet_url).json()
  89     snippet = snippet['query']['pages']
  90 
  91     # For some reason, the API gives the page *number* as the key, so we just
  92     # grab the first page number in the results.
  93     snippet = snippet[list(snippet.keys())[0]]
  94 
  95     return snippet['extract']
  96 
  97 
  98 @rule('.*\/([a-z]+\.wikipedia.org)\/wiki\/((?!File\:)[^ ]+).*')
  99 def mw_info(bot, trigger, found_match=None):
  100     """
  101     Retrives a snippet of the specified length from the given page on the given
  102     server.
  103     """
  104     match = found_match or trigger
  105     say_snippet(bot, match.group(1), unquote(match.group(2)), show_url=False)
  106 
  107 
  108 @commands('w', 'wiki', 'wik')
  109 @example('.w San Francisco')
  110 def wikipedia(bot, trigger):
  111     lang = bot.config.wikipedia.default_lang
  112 
  113     # change lang if channel has custom language set
  114     if (trigger.sender and not trigger.sender.is_nick() and
  115             bot.config.wikipedia.lang_per_channel):
  116         customlang = re.search('(' + trigger.sender + '):(\w+)',
  117                                bot.config.wikipedia.lang_per_channel)
  118         if customlang is not None:
  119             lang = customlang.group(2)
  120 
  121     if trigger.group(2) is None:
  122         bot.reply("What do you want me to look up?")
  123         return NOLIMIT
  124 
  125     query = trigger.group(2)
  126     args = re.search(r'^-([a-z]{2,12})\s(.*)', query)
  127     if args is not None:
  128         lang = args.group(1)
  129         query = args.group(2)
  130 
  131     if not query:
  132         bot.reply('What do you want me to look up?')
  133         return NOLIMIT
  134     server = lang + '.wikipedia.org'
  135     query = mw_search(server, query, 1)
  136     if not query:
  137         bot.reply("I can't find any results for that.")
  138         return NOLIMIT
  139     else:
  140         query = query[0]
  141     say_snippet(bot, server, query)
  142
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/sopel/modules/wikipedia.py b/sopel/modules/wikipedia.py
  --- a/sopel/modules/wikipedia.py
  +++ b/sopel/modules/wikipedia.py
  @@ -61,7 +61,7 @@
           return None
   
   
  -def say_snippet(bot, server, query, show_url=True):
  +def say_snippet(bot, trigger, server, query, show_url=True):
       page_name = query.replace('_', ' ')
       query = quote(query.replace(' ', '_'))
       try:
  @@ -71,8 +71,11 @@
               bot.say("[WIKIPEDIA] Error fetching snippet for \"{}\".".format(page_name))
           return
       msg = '[WIKIPEDIA] {} | "{}"'.format(page_name, snippet)
  +    msg_url = msg + ' | https://{}/wiki/{}'.format(server, query)
  +    if msg_url == trigger:  # prevents triggering on another instance of Sopel
  +        return
       if show_url:
  -        msg = msg + ' | https://{}/wiki/{}'.format(server, query)
  +        msg = msg_url
       bot.say(msg)
   
   
  @@ -102,7 +105,7 @@
       server.
       """
       match = found_match or trigger
  -    say_snippet(bot, match.group(1), unquote(match.group(2)), show_url=False)
  +    say_snippet(bot, trigger, match.group(1), unquote(match.group(2)), show_url=False)
   
   
   @commands('w', 'wiki', 'wik')
  @@ -138,4 +141,4 @@
           return NOLIMIT
       else:
           query = query[0]
  -    say_snippet(bot, server, query)
  +    say_snippet(bot, trigger, server, query)
  
verification_info: {"golden_diff": "diff --git a/sopel/modules/wikipedia.py b/sopel/modules/wikipedia.py\n--- a/sopel/modules/wikipedia.py\n+++ b/sopel/modules/wikipedia.py\n@@ -61,7 +61,7 @@\n         return None\n \n \n-def say_snippet(bot, server, query, show_url=True):\n+def say_snippet(bot, trigger, server, query, show_url=True):\n     page_name = query.replace('_', ' ')\n     query = quote(query.replace(' ', '_'))\n     try:\n@@ -71,8 +71,11 @@\n             bot.say(\"[WIKIPEDIA] Error fetching snippet for \\\"{}\\\".\".format(page_name))\n         return\n     msg = '[WIKIPEDIA] {} | \"{}\"'.format(page_name, snippet)\n+    msg_url = msg + ' | https://{}/wiki/{}'.format(server, query)\n+    if msg_url == trigger:  # prevents triggering on another instance of Sopel\n+        return\n     if show_url:\n-        msg = msg + ' | https://{}/wiki/{}'.format(server, query)\n+        msg = msg_url\n     bot.say(msg)\n \n \n@@ -102,7 +105,7 @@\n     server.\n     \"\"\"\n     match = found_match or trigger\n-    say_snippet(bot, match.group(1), unquote(match.group(2)), show_url=False)\n+    say_snippet(bot, trigger, match.group(1), unquote(match.group(2)), show_url=False)\n \n \n @commands('w', 'wiki', 'wik')\n@@ -138,4 +141,4 @@\n         return NOLIMIT\n     else:\n         query = query[0]\n-    say_snippet(bot, server, query)\n+    say_snippet(bot, trigger, server, query)\n", "issue": "wikipedia: may trigger other Sopel instances\nReported by `sloopy` in IRC. bot2-. uses prefix `.` and bot1-# uses `#`\n\n```\n<sloopy> .w Star Trek\n<bot2-.> [WIKIPEDIA] Star Trek | \"Star Trek is an American science fiction entertainment franchise created by Gene Roddenberry and owned by CBS and Paramount Pictures. The television series Star Trek: The Original Series, Star Trek: The Animated Series, Star Trek: The Next Generation, Star Trek: Deep Space Nine, Star Trek: Voyager, Star...\" | https://en.wikipedia.org/wiki/Star_Trek\n<bot1-#> [WIKIPEDIA] Star Trek | \"Star Trek is an American science fiction entertainment franchise created by Gene Roddenberry and owned by CBS and Paramount Pictures. The television series Star Trek: The Original Series, Star Trek: The Animated Series, Star Trek: The Next Generation, Star Trek: Deep Space Nine, Star Trek: Voyager, Star...\"\n```\n\n", "before_files": [{"content": "# coding=utf-8\n# Copyright 2013 Elsie Powell - embolalia.com\n# Licensed under the Eiffel Forum License 2.\nfrom __future__ import unicode_literals, absolute_import, print_function, division\n\nfrom sopel import tools\nfrom sopel.config.types import StaticSection, ValidatedAttribute\nfrom sopel.module import NOLIMIT, commands, example, rule\nfrom requests import get\nimport re\n\nimport sys\nif sys.version_info.major < 3:\n    from urllib import quote as _quote\n    from urlparse import unquote as _unquote\n    quote = lambda s: _quote(s.encode('utf-8')).decode('utf-8')\n    unquote = lambda s: _unquote(s.encode('utf-8')).decode('utf-8')\nelse:\n    from urllib.parse import quote, unquote\n\nREDIRECT = re.compile(r'^REDIRECT (.*)')\n\n\nclass WikipediaSection(StaticSection):\n    default_lang = ValidatedAttribute('default_lang', default='en')\n    \"\"\"The default language to find articles from.\"\"\"\n    lang_per_channel = ValidatedAttribute('lang_per_channel')\n\n\ndef setup(bot):\n    bot.config.define_section('wikipedia', WikipediaSection)\n\n    regex = re.compile('([a-z]+).(wikipedia.org/wiki/)([^ ]+)')\n    if not bot.memory.contains('url_callbacks'):\n        bot.memory['url_callbacks'] = tools.SopelMemory()\n    bot.memory['url_callbacks'][regex] = mw_info\n\n\ndef configure(config):\n    config.define_section('wikipedia', WikipediaSection)\n    config.wikipedia.configure_setting(\n        'default_lang',\n        \"Enter the default language to find articles from.\"\n    )\n\n\ndef mw_search(server, query, num):\n    \"\"\"\n    Searches the specified MediaWiki server for the given query, and returns\n    the specified number of results.\n    \"\"\"\n    search_url = ('http://%s/w/api.php?format=json&action=query'\n                  '&list=search&srlimit=%d&srprop=timestamp&srwhat=text'\n                  '&srsearch=') % (server, num)\n    search_url += query\n    query = get(search_url).json()\n    if 'query' in query:\n        query = query['query']['search']\n        return [r['title'] for r in query]\n    else:\n        return None\n\n\ndef say_snippet(bot, server, query, show_url=True):\n    page_name = query.replace('_', ' ')\n    query = quote(query.replace(' ', '_'))\n    try:\n        snippet = mw_snippet(server, query)\n    except KeyError:\n        if show_url:\n            bot.say(\"[WIKIPEDIA] Error fetching snippet for \\\"{}\\\".\".format(page_name))\n        return\n    msg = '[WIKIPEDIA] {} | \"{}\"'.format(page_name, snippet)\n    if show_url:\n        msg = msg + ' | https://{}/wiki/{}'.format(server, query)\n    bot.say(msg)\n\n\ndef mw_snippet(server, query):\n    \"\"\"\n    Retrives a snippet of the specified length from the given page on the given\n    server.\n    \"\"\"\n    snippet_url = ('https://' + server + '/w/api.php?format=json'\n                   '&action=query&prop=extracts&exintro&explaintext'\n                   '&exchars=300&redirects&titles=')\n    snippet_url += query\n    snippet = get(snippet_url).json()\n    snippet = snippet['query']['pages']\n\n    # For some reason, the API gives the page *number* as the key, so we just\n    # grab the first page number in the results.\n    snippet = snippet[list(snippet.keys())[0]]\n\n    return snippet['extract']\n\n\n@rule('.*\\/([a-z]+\\.wikipedia.org)\\/wiki\\/((?!File\\:)[^ ]+).*')\ndef mw_info(bot, trigger, found_match=None):\n    \"\"\"\n    Retrives a snippet of the specified length from the given page on the given\n    server.\n    \"\"\"\n    match = found_match or trigger\n    say_snippet(bot, match.group(1), unquote(match.group(2)), show_url=False)\n\n\n@commands('w', 'wiki', 'wik')\n@example('.w San Francisco')\ndef wikipedia(bot, trigger):\n    lang = bot.config.wikipedia.default_lang\n\n    # change lang if channel has custom language set\n    if (trigger.sender and not trigger.sender.is_nick() and\n            bot.config.wikipedia.lang_per_channel):\n        customlang = re.search('(' + trigger.sender + '):(\\w+)',\n                               bot.config.wikipedia.lang_per_channel)\n        if customlang is not None:\n            lang = customlang.group(2)\n\n    if trigger.group(2) is None:\n        bot.reply(\"What do you want me to look up?\")\n        return NOLIMIT\n\n    query = trigger.group(2)\n    args = re.search(r'^-([a-z]{2,12})\\s(.*)', query)\n    if args is not None:\n        lang = args.group(1)\n        query = args.group(2)\n\n    if not query:\n        bot.reply('What do you want me to look up?')\n        return NOLIMIT\n    server = lang + '.wikipedia.org'\n    query = mw_search(server, query, 1)\n    if not query:\n        bot.reply(\"I can't find any results for that.\")\n        return NOLIMIT\n    else:\n        query = query[0]\n    say_snippet(bot, server, query)\n", "path": "sopel/modules/wikipedia.py"}], "after_files": [{"content": "# coding=utf-8\n# Copyright 2013 Elsie Powell - embolalia.com\n# Licensed under the Eiffel Forum License 2.\nfrom __future__ import unicode_literals, absolute_import, print_function, division\n\nfrom sopel import tools\nfrom sopel.config.types import StaticSection, ValidatedAttribute\nfrom sopel.module import NOLIMIT, commands, example, rule\nfrom requests import get\nimport re\n\nimport sys\nif sys.version_info.major < 3:\n    from urllib import quote as _quote\n    from urlparse import unquote as _unquote\n    quote = lambda s: _quote(s.encode('utf-8')).decode('utf-8')\n    unquote = lambda s: _unquote(s.encode('utf-8')).decode('utf-8')\nelse:\n    from urllib.parse import quote, unquote\n\nREDIRECT = re.compile(r'^REDIRECT (.*)')\n\n\nclass WikipediaSection(StaticSection):\n    default_lang = ValidatedAttribute('default_lang', default='en')\n    \"\"\"The default language to find articles from.\"\"\"\n    lang_per_channel = ValidatedAttribute('lang_per_channel')\n\n\ndef setup(bot):\n    bot.config.define_section('wikipedia', WikipediaSection)\n\n    regex = re.compile('([a-z]+).(wikipedia.org/wiki/)([^ ]+)')\n    if not bot.memory.contains('url_callbacks'):\n        bot.memory['url_callbacks'] = tools.SopelMemory()\n    bot.memory['url_callbacks'][regex] = mw_info\n\n\ndef configure(config):\n    config.define_section('wikipedia', WikipediaSection)\n    config.wikipedia.configure_setting(\n        'default_lang',\n        \"Enter the default language to find articles from.\"\n    )\n\n\ndef mw_search(server, query, num):\n    \"\"\"\n    Searches the specified MediaWiki server for the given query, and returns\n    the specified number of results.\n    \"\"\"\n    search_url = ('http://%s/w/api.php?format=json&action=query'\n                  '&list=search&srlimit=%d&srprop=timestamp&srwhat=text'\n                  '&srsearch=') % (server, num)\n    search_url += query\n    query = get(search_url).json()\n    if 'query' in query:\n        query = query['query']['search']\n        return [r['title'] for r in query]\n    else:\n        return None\n\n\ndef say_snippet(bot, trigger, server, query, show_url=True):\n    page_name = query.replace('_', ' ')\n    query = quote(query.replace(' ', '_'))\n    try:\n        snippet = mw_snippet(server, query)\n    except KeyError:\n        if show_url:\n            bot.say(\"[WIKIPEDIA] Error fetching snippet for \\\"{}\\\".\".format(page_name))\n        return\n    msg = '[WIKIPEDIA] {} | \"{}\"'.format(page_name, snippet)\n    msg_url = msg + ' | https://{}/wiki/{}'.format(server, query)\n    if msg_url == trigger:  # prevents triggering on another instance of Sopel\n        return\n    if show_url:\n        msg = msg_url\n    bot.say(msg)\n\n\ndef mw_snippet(server, query):\n    \"\"\"\n    Retrives a snippet of the specified length from the given page on the given\n    server.\n    \"\"\"\n    snippet_url = ('https://' + server + '/w/api.php?format=json'\n                   '&action=query&prop=extracts&exintro&explaintext'\n                   '&exchars=300&redirects&titles=')\n    snippet_url += query\n    snippet = get(snippet_url).json()\n    snippet = snippet['query']['pages']\n\n    # For some reason, the API gives the page *number* as the key, so we just\n    # grab the first page number in the results.\n    snippet = snippet[list(snippet.keys())[0]]\n\n    return snippet['extract']\n\n\n@rule('.*\\/([a-z]+\\.wikipedia.org)\\/wiki\\/((?!File\\:)[^ ]+).*')\ndef mw_info(bot, trigger, found_match=None):\n    \"\"\"\n    Retrives a snippet of the specified length from the given page on the given\n    server.\n    \"\"\"\n    match = found_match or trigger\n    say_snippet(bot, trigger, match.group(1), unquote(match.group(2)), show_url=False)\n\n\n@commands('w', 'wiki', 'wik')\n@example('.w San Francisco')\ndef wikipedia(bot, trigger):\n    lang = bot.config.wikipedia.default_lang\n\n    # change lang if channel has custom language set\n    if (trigger.sender and not trigger.sender.is_nick() and\n            bot.config.wikipedia.lang_per_channel):\n        customlang = re.search('(' + trigger.sender + '):(\\w+)',\n                               bot.config.wikipedia.lang_per_channel)\n        if customlang is not None:\n            lang = customlang.group(2)\n\n    if trigger.group(2) is None:\n        bot.reply(\"What do you want me to look up?\")\n        return NOLIMIT\n\n    query = trigger.group(2)\n    args = re.search(r'^-([a-z]{2,12})\\s(.*)', query)\n    if args is not None:\n        lang = args.group(1)\n        query = args.group(2)\n\n    if not query:\n        bot.reply('What do you want me to look up?')\n        return NOLIMIT\n    server = lang + '.wikipedia.org'\n    query = mw_search(server, query, 1)\n    if not query:\n        bot.reply(\"I can't find any results for that.\")\n        return NOLIMIT\n    else:\n        query = query[0]\n    say_snippet(bot, trigger, server, query)\n", "path": "sopel/modules/wikipedia.py"}]}