prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  PyMongo v4 removed collection methods
  [PyMongo v4 removed a number of collection methods](https://pymongo.readthedocs.io/en/stable/migrate-to-pymongo4.html). While the agent still functions properly, it's logging failed instrumentation warnings and is breaking the build. 
  
  --- 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/scout_apm/instruments/pymongo.py`
  Content:
  ```
  1 # coding=utf-8
  2 from __future__ import absolute_import, division, print_function, unicode_literals
  3 
  4 import logging
  5 
  6 import wrapt
  7 
  8 from scout_apm.core.tracked_request import TrackedRequest
  9 
  10 try:
  11     from pymongo.collection import Collection
  12 except ImportError:
  13     Collection = None
  14 
  15 logger = logging.getLogger(__name__)
  16 
  17 have_patched_collection = False
  18 
  19 
  20 def ensure_installed():
  21     global have_patched_collection
  22 
  23     logger.debug("Instrumenting pymongo.")
  24 
  25     if Collection is None:
  26         logger.debug("Couldn't import pymongo.Collection - probably not installed.")
  27     elif not have_patched_collection:
  28         for name in COLLECTION_METHODS:
  29             try:
  30                 setattr(
  31                     Collection, name, wrap_collection_method(getattr(Collection, name))
  32                 )
  33             except Exception as exc:
  34                 logger.warning(
  35                     "Failed to instrument pymongo.Collection.%s: %r",
  36                     name,
  37                     exc,
  38                     exc_info=exc,
  39                 )
  40         have_patched_collection = True
  41 
  42 
  43 COLLECTION_METHODS = [
  44     "aggregate",
  45     "aggregate_raw_batches",
  46     "bulk_write",
  47     "count",
  48     "count_documents",
  49     "create_index",
  50     "create_indexes",
  51     "delete_many",
  52     "delete_one",
  53     "distinct",
  54     "drop",
  55     "drop_index",
  56     "drop_indexes",
  57     "ensure_index",
  58     "estimated_document_count",
  59     "find",
  60     "find_and_modify",
  61     "find_one",
  62     "find_one_and_delete",
  63     "find_one_and_replace",
  64     "find_one_and_update",
  65     "find_raw_batches",
  66     "group",
  67     "index_information",
  68     "inline_map_reduce",
  69     "insert",
  70     "insert_many",
  71     "insert_one",
  72     "list_indexes",
  73     "map_reduce",
  74     "parallel_scan",
  75     "reindex",
  76     "remove",
  77     "rename",
  78     "replace_one",
  79     "save",
  80     "update",
  81     "update_many",
  82     "update_one",
  83 ]
  84 
  85 
  86 @wrapt.decorator
  87 def wrap_collection_method(wrapped, instance, args, kwargs):
  88     tracked_request = TrackedRequest.instance()
  89     camel_name = "".join(c.title() for c in wrapped.__name__.split("_"))
  90     operation = "MongoDB/{}.{}".format(instance.name, camel_name)
  91     with tracked_request.span(operation=operation, ignore_children=True) as span:
  92         span.tag("name", instance.name)
  93         return wrapped(*args, **kwargs)
  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()
  
  ```
  
golden_diff: diff --git a/src/scout_apm/instruments/pymongo.py b/src/scout_apm/instruments/pymongo.py
  --- a/src/scout_apm/instruments/pymongo.py
  +++ b/src/scout_apm/instruments/pymongo.py
  @@ -8,8 +8,10 @@
   from scout_apm.core.tracked_request import TrackedRequest
   
   try:
  +    import pymongo
       from pymongo.collection import Collection
   except ImportError:
  +    pymongo = None
       Collection = None
   
   logger = logging.getLogger(__name__)
  @@ -25,7 +27,10 @@
       if Collection is None:
           logger.debug("Couldn't import pymongo.Collection - probably not installed.")
       elif not have_patched_collection:
  -        for name in COLLECTION_METHODS:
  +        methods = COLLECTION_METHODS
  +        if pymongo.version_tuple < (4, 0):
  +            methods = COLLECTION_METHODS_V3
  +        for name in methods:
               try:
                   setattr(
                       Collection, name, wrap_collection_method(getattr(Collection, name))
  @@ -44,7 +49,6 @@
       "aggregate",
       "aggregate_raw_batches",
       "bulk_write",
  -    "count",
       "count_documents",
       "create_index",
       "create_indexes",
  @@ -54,32 +58,36 @@
       "drop",
       "drop_index",
       "drop_indexes",
  -    "ensure_index",
       "estimated_document_count",
       "find",
  -    "find_and_modify",
       "find_one",
       "find_one_and_delete",
       "find_one_and_replace",
       "find_one_and_update",
       "find_raw_batches",
  -    "group",
       "index_information",
  -    "inline_map_reduce",
  -    "insert",
       "insert_many",
       "insert_one",
       "list_indexes",
  +    "rename",
  +    "replace_one",
  +    "update_many",
  +    "update_one",
  +]
  +
  +COLLECTION_METHODS_V3 = COLLECTION_METHODS + [
  +    "count",
  +    "ensure_index",
  +    "find_and_modify",
  +    "group",
  +    "inline_map_reduce",
  +    "insert",
       "map_reduce",
       "parallel_scan",
       "reindex",
       "remove",
  -    "rename",
  -    "replace_one",
       "save",
       "update",
  -    "update_many",
  -    "update_one",
   ]
  
verification_info: {"golden_diff": "diff --git a/src/scout_apm/instruments/pymongo.py b/src/scout_apm/instruments/pymongo.py\n--- a/src/scout_apm/instruments/pymongo.py\n+++ b/src/scout_apm/instruments/pymongo.py\n@@ -8,8 +8,10 @@\n from scout_apm.core.tracked_request import TrackedRequest\n \n try:\n+    import pymongo\n     from pymongo.collection import Collection\n except ImportError:\n+    pymongo = None\n     Collection = None\n \n logger = logging.getLogger(__name__)\n@@ -25,7 +27,10 @@\n     if Collection is None:\n         logger.debug(\"Couldn't import pymongo.Collection - probably not installed.\")\n     elif not have_patched_collection:\n-        for name in COLLECTION_METHODS:\n+        methods = COLLECTION_METHODS\n+        if pymongo.version_tuple < (4, 0):\n+            methods = COLLECTION_METHODS_V3\n+        for name in methods:\n             try:\n                 setattr(\n                     Collection, name, wrap_collection_method(getattr(Collection, name))\n@@ -44,7 +49,6 @@\n     \"aggregate\",\n     \"aggregate_raw_batches\",\n     \"bulk_write\",\n-    \"count\",\n     \"count_documents\",\n     \"create_index\",\n     \"create_indexes\",\n@@ -54,32 +58,36 @@\n     \"drop\",\n     \"drop_index\",\n     \"drop_indexes\",\n-    \"ensure_index\",\n     \"estimated_document_count\",\n     \"find\",\n-    \"find_and_modify\",\n     \"find_one\",\n     \"find_one_and_delete\",\n     \"find_one_and_replace\",\n     \"find_one_and_update\",\n     \"find_raw_batches\",\n-    \"group\",\n     \"index_information\",\n-    \"inline_map_reduce\",\n-    \"insert\",\n     \"insert_many\",\n     \"insert_one\",\n     \"list_indexes\",\n+    \"rename\",\n+    \"replace_one\",\n+    \"update_many\",\n+    \"update_one\",\n+]\n+\n+COLLECTION_METHODS_V3 = COLLECTION_METHODS + [\n+    \"count\",\n+    \"ensure_index\",\n+    \"find_and_modify\",\n+    \"group\",\n+    \"inline_map_reduce\",\n+    \"insert\",\n     \"map_reduce\",\n     \"parallel_scan\",\n     \"reindex\",\n     \"remove\",\n-    \"rename\",\n-    \"replace_one\",\n     \"save\",\n     \"update\",\n-    \"update_many\",\n-    \"update_one\",\n ]\n", "issue": "PyMongo v4 removed collection methods\n[PyMongo v4 removed a number of collection methods](https://pymongo.readthedocs.io/en/stable/migrate-to-pymongo4.html). While the agent still functions properly, it's logging failed instrumentation warnings and is breaking the build. \n", "before_files": [{"content": "# coding=utf-8\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport logging\n\nimport wrapt\n\nfrom scout_apm.core.tracked_request import TrackedRequest\n\ntry:\n    from pymongo.collection import Collection\nexcept ImportError:\n    Collection = None\n\nlogger = logging.getLogger(__name__)\n\nhave_patched_collection = False\n\n\ndef ensure_installed():\n    global have_patched_collection\n\n    logger.debug(\"Instrumenting pymongo.\")\n\n    if Collection is None:\n        logger.debug(\"Couldn't import pymongo.Collection - probably not installed.\")\n    elif not have_patched_collection:\n        for name in COLLECTION_METHODS:\n            try:\n                setattr(\n                    Collection, name, wrap_collection_method(getattr(Collection, name))\n                )\n            except Exception as exc:\n                logger.warning(\n                    \"Failed to instrument pymongo.Collection.%s: %r\",\n                    name,\n                    exc,\n                    exc_info=exc,\n                )\n        have_patched_collection = True\n\n\nCOLLECTION_METHODS = [\n    \"aggregate\",\n    \"aggregate_raw_batches\",\n    \"bulk_write\",\n    \"count\",\n    \"count_documents\",\n    \"create_index\",\n    \"create_indexes\",\n    \"delete_many\",\n    \"delete_one\",\n    \"distinct\",\n    \"drop\",\n    \"drop_index\",\n    \"drop_indexes\",\n    \"ensure_index\",\n    \"estimated_document_count\",\n    \"find\",\n    \"find_and_modify\",\n    \"find_one\",\n    \"find_one_and_delete\",\n    \"find_one_and_replace\",\n    \"find_one_and_update\",\n    \"find_raw_batches\",\n    \"group\",\n    \"index_information\",\n    \"inline_map_reduce\",\n    \"insert\",\n    \"insert_many\",\n    \"insert_one\",\n    \"list_indexes\",\n    \"map_reduce\",\n    \"parallel_scan\",\n    \"reindex\",\n    \"remove\",\n    \"rename\",\n    \"replace_one\",\n    \"save\",\n    \"update\",\n    \"update_many\",\n    \"update_one\",\n]\n\n\n@wrapt.decorator\ndef wrap_collection_method(wrapped, instance, args, kwargs):\n    tracked_request = TrackedRequest.instance()\n    camel_name = \"\".join(c.title() for c in wrapped.__name__.split(\"_\"))\n    operation = \"MongoDB/{}.{}\".format(instance.name, camel_name)\n    with tracked_request.span(operation=operation, ignore_children=True) as span:\n        span.tag(\"name\", instance.name)\n        return wrapped(*args, **kwargs)\n", "path": "src/scout_apm/instruments/pymongo.py"}], "after_files": [{"content": "# coding=utf-8\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport logging\n\nimport wrapt\n\nfrom scout_apm.core.tracked_request import TrackedRequest\n\ntry:\n    import pymongo\n    from pymongo.collection import Collection\nexcept ImportError:\n    pymongo = None\n    Collection = None\n\nlogger = logging.getLogger(__name__)\n\nhave_patched_collection = False\n\n\ndef ensure_installed():\n    global have_patched_collection\n\n    logger.debug(\"Instrumenting pymongo.\")\n\n    if Collection is None:\n        logger.debug(\"Couldn't import pymongo.Collection - probably not installed.\")\n    elif not have_patched_collection:\n        methods = COLLECTION_METHODS\n        if pymongo.version_tuple < (4, 0):\n            methods = COLLECTION_METHODS_V3\n        for name in methods:\n            try:\n                setattr(\n                    Collection, name, wrap_collection_method(getattr(Collection, name))\n                )\n            except Exception as exc:\n                logger.warning(\n                    \"Failed to instrument pymongo.Collection.%s: %r\",\n                    name,\n                    exc,\n                    exc_info=exc,\n                )\n        have_patched_collection = True\n\n\nCOLLECTION_METHODS = [\n    \"aggregate\",\n    \"aggregate_raw_batches\",\n    \"bulk_write\",\n    \"count_documents\",\n    \"create_index\",\n    \"create_indexes\",\n    \"delete_many\",\n    \"delete_one\",\n    \"distinct\",\n    \"drop\",\n    \"drop_index\",\n    \"drop_indexes\",\n    \"estimated_document_count\",\n    \"find\",\n    \"find_one\",\n    \"find_one_and_delete\",\n    \"find_one_and_replace\",\n    \"find_one_and_update\",\n    \"find_raw_batches\",\n    \"index_information\",\n    \"insert_many\",\n    \"insert_one\",\n    \"list_indexes\",\n    \"rename\",\n    \"replace_one\",\n    \"update_many\",\n    \"update_one\",\n]\n\nCOLLECTION_METHODS_V3 = COLLECTION_METHODS + [\n    \"count\",\n    \"ensure_index\",\n    \"find_and_modify\",\n    \"group\",\n    \"inline_map_reduce\",\n    \"insert\",\n    \"map_reduce\",\n    \"parallel_scan\",\n    \"reindex\",\n    \"remove\",\n    \"save\",\n    \"update\",\n]\n\n\n@wrapt.decorator\ndef wrap_collection_method(wrapped, instance, args, kwargs):\n    tracked_request = TrackedRequest.instance()\n    camel_name = \"\".join(c.title() for c in wrapped.__name__.split(\"_\"))\n    operation = \"MongoDB/{}.{}\".format(instance.name, camel_name)\n    with tracked_request.span(operation=operation, ignore_children=True) as span:\n        span.tag(\"name\", instance.name)\n        return wrapped(*args, **kwargs)\n", "path": "src/scout_apm/instruments/pymongo.py"}]}