prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Importing ABC directly from collections has been deprecated and will be removed in Python 3.10
  Use `collections` for Python 2 and `collections.abc` for Python 3.4+
  
  https://github.com/mozilla/kitsune/blob/db42cf7841b75ff0d4b6d3b21ac2524636110429/kitsune/wiki/widgets.py#L34
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `kitsune/wiki/widgets.py`
  Content:
  ```
  1 import collections
  2 
  3 from django import forms
  4 from django.template.loader import render_to_string
  5 
  6 from kitsune.products.models import Topic
  7 from kitsune.wiki.models import Document
  8 
  9 
  10 class ProductTopicsAndSubtopicsWidget(forms.widgets.SelectMultiple):
  11     """A widget to render topics organized by product and with subtopics."""
  12 
  13     def render(self, name, value, attrs=None, renderer=None):
  14         topics_and_subtopics = Topic.objects.all()
  15         topics = [t for t in topics_and_subtopics if t.parent_id is None]
  16 
  17         for topic in topics:
  18             self.process_topic(value, topic)
  19 
  20             topic.my_subtopics = [t for t in topics_and_subtopics if t.parent_id == topic.id]
  21 
  22             for subtopic in topic.my_subtopics:
  23                 self.process_topic(value, subtopic)
  24 
  25         return render_to_string(
  26             "wiki/includes/product_topics_widget.html",
  27             {
  28                 "topics": topics,
  29                 "name": name,
  30             },
  31         )
  32 
  33     def process_topic(self, value, topic):
  34         if isinstance(value, int) and topic.id == value:
  35             topic.checked = True
  36         elif (
  37             not isinstance(value, str)
  38             and isinstance(value, collections.Iterable)
  39             and topic.id in value
  40         ):
  41             topic.checked = True
  42         else:
  43             topic.checked = False
  44 
  45 
  46 class RelatedDocumentsWidget(forms.widgets.SelectMultiple):
  47     """A widget to render the related documents list and search field."""
  48 
  49     def render(self, name, value, attrs=None, renderer=None):
  50         if isinstance(value, int):
  51             related_documents = Document.objects.filter(id__in=[value])
  52         elif not isinstance(value, str) and isinstance(value, collections.Iterable):
  53             related_documents = Document.objects.filter(id__in=value)
  54         else:
  55             related_documents = Document.objects.none()
  56 
  57         return render_to_string(
  58             "wiki/includes/related_docs_widget.html",
  59             {"related_documents": related_documents, "name": name},
  60         )
  61
  ```
  --- 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/kitsune/wiki/widgets.py b/kitsune/wiki/widgets.py
  --- a/kitsune/wiki/widgets.py
  +++ b/kitsune/wiki/widgets.py
  @@ -1,4 +1,3 @@
  -import collections
   
   from django import forms
   from django.template.loader import render_to_string
  @@ -6,6 +5,11 @@
   from kitsune.products.models import Topic
   from kitsune.wiki.models import Document
   
  +try:
  +    from collections.abc import Iterable
  +except ImportError:
  +    from collections import Iterable
  +
   
   class ProductTopicsAndSubtopicsWidget(forms.widgets.SelectMultiple):
       """A widget to render topics organized by product and with subtopics."""
  @@ -35,7 +39,7 @@
               topic.checked = True
           elif (
               not isinstance(value, str)
  -            and isinstance(value, collections.Iterable)
  +            and isinstance(value, Iterable)
               and topic.id in value
           ):
               topic.checked = True
  @@ -49,7 +53,7 @@
       def render(self, name, value, attrs=None, renderer=None):
           if isinstance(value, int):
               related_documents = Document.objects.filter(id__in=[value])
  -        elif not isinstance(value, str) and isinstance(value, collections.Iterable):
  +        elif not isinstance(value, str) and isinstance(value, Iterable):
               related_documents = Document.objects.filter(id__in=value)
           else:
               related_documents = Document.objects.none()
  
verification_info: {"golden_diff": "diff --git a/kitsune/wiki/widgets.py b/kitsune/wiki/widgets.py\n--- a/kitsune/wiki/widgets.py\n+++ b/kitsune/wiki/widgets.py\n@@ -1,4 +1,3 @@\n-import collections\n \n from django import forms\n from django.template.loader import render_to_string\n@@ -6,6 +5,11 @@\n from kitsune.products.models import Topic\n from kitsune.wiki.models import Document\n \n+try:\n+    from collections.abc import Iterable\n+except ImportError:\n+    from collections import Iterable\n+\n \n class ProductTopicsAndSubtopicsWidget(forms.widgets.SelectMultiple):\n     \"\"\"A widget to render topics organized by product and with subtopics.\"\"\"\n@@ -35,7 +39,7 @@\n             topic.checked = True\n         elif (\n             not isinstance(value, str)\n-            and isinstance(value, collections.Iterable)\n+            and isinstance(value, Iterable)\n             and topic.id in value\n         ):\n             topic.checked = True\n@@ -49,7 +53,7 @@\n     def render(self, name, value, attrs=None, renderer=None):\n         if isinstance(value, int):\n             related_documents = Document.objects.filter(id__in=[value])\n-        elif not isinstance(value, str) and isinstance(value, collections.Iterable):\n+        elif not isinstance(value, str) and isinstance(value, Iterable):\n             related_documents = Document.objects.filter(id__in=value)\n         else:\n             related_documents = Document.objects.none()\n", "issue": "Importing ABC directly from collections has been deprecated and will be removed in Python 3.10\nUse `collections` for Python 2 and `collections.abc` for Python 3.4+\r\n\r\nhttps://github.com/mozilla/kitsune/blob/db42cf7841b75ff0d4b6d3b21ac2524636110429/kitsune/wiki/widgets.py#L34\n", "before_files": [{"content": "import collections\n\nfrom django import forms\nfrom django.template.loader import render_to_string\n\nfrom kitsune.products.models import Topic\nfrom kitsune.wiki.models import Document\n\n\nclass ProductTopicsAndSubtopicsWidget(forms.widgets.SelectMultiple):\n    \"\"\"A widget to render topics organized by product and with subtopics.\"\"\"\n\n    def render(self, name, value, attrs=None, renderer=None):\n        topics_and_subtopics = Topic.objects.all()\n        topics = [t for t in topics_and_subtopics if t.parent_id is None]\n\n        for topic in topics:\n            self.process_topic(value, topic)\n\n            topic.my_subtopics = [t for t in topics_and_subtopics if t.parent_id == topic.id]\n\n            for subtopic in topic.my_subtopics:\n                self.process_topic(value, subtopic)\n\n        return render_to_string(\n            \"wiki/includes/product_topics_widget.html\",\n            {\n                \"topics\": topics,\n                \"name\": name,\n            },\n        )\n\n    def process_topic(self, value, topic):\n        if isinstance(value, int) and topic.id == value:\n            topic.checked = True\n        elif (\n            not isinstance(value, str)\n            and isinstance(value, collections.Iterable)\n            and topic.id in value\n        ):\n            topic.checked = True\n        else:\n            topic.checked = False\n\n\nclass RelatedDocumentsWidget(forms.widgets.SelectMultiple):\n    \"\"\"A widget to render the related documents list and search field.\"\"\"\n\n    def render(self, name, value, attrs=None, renderer=None):\n        if isinstance(value, int):\n            related_documents = Document.objects.filter(id__in=[value])\n        elif not isinstance(value, str) and isinstance(value, collections.Iterable):\n            related_documents = Document.objects.filter(id__in=value)\n        else:\n            related_documents = Document.objects.none()\n\n        return render_to_string(\n            \"wiki/includes/related_docs_widget.html\",\n            {\"related_documents\": related_documents, \"name\": name},\n        )\n", "path": "kitsune/wiki/widgets.py"}], "after_files": [{"content": "\nfrom django import forms\nfrom django.template.loader import render_to_string\n\nfrom kitsune.products.models import Topic\nfrom kitsune.wiki.models import Document\n\ntry:\n    from collections.abc import Iterable\nexcept ImportError:\n    from collections import Iterable\n\n\nclass ProductTopicsAndSubtopicsWidget(forms.widgets.SelectMultiple):\n    \"\"\"A widget to render topics organized by product and with subtopics.\"\"\"\n\n    def render(self, name, value, attrs=None, renderer=None):\n        topics_and_subtopics = Topic.objects.all()\n        topics = [t for t in topics_and_subtopics if t.parent_id is None]\n\n        for topic in topics:\n            self.process_topic(value, topic)\n\n            topic.my_subtopics = [t for t in topics_and_subtopics if t.parent_id == topic.id]\n\n            for subtopic in topic.my_subtopics:\n                self.process_topic(value, subtopic)\n\n        return render_to_string(\n            \"wiki/includes/product_topics_widget.html\",\n            {\n                \"topics\": topics,\n                \"name\": name,\n            },\n        )\n\n    def process_topic(self, value, topic):\n        if isinstance(value, int) and topic.id == value:\n            topic.checked = True\n        elif (\n            not isinstance(value, str)\n            and isinstance(value, Iterable)\n            and topic.id in value\n        ):\n            topic.checked = True\n        else:\n            topic.checked = False\n\n\nclass RelatedDocumentsWidget(forms.widgets.SelectMultiple):\n    \"\"\"A widget to render the related documents list and search field.\"\"\"\n\n    def render(self, name, value, attrs=None, renderer=None):\n        if isinstance(value, int):\n            related_documents = Document.objects.filter(id__in=[value])\n        elif not isinstance(value, str) and isinstance(value, Iterable):\n            related_documents = Document.objects.filter(id__in=value)\n        else:\n            related_documents = Document.objects.none()\n\n        return render_to_string(\n            \"wiki/includes/related_docs_widget.html\",\n            {\"related_documents\": related_documents, \"name\": name},\n        )\n", "path": "kitsune/wiki/widgets.py"}]}