diff --git a/pymongo/asynchronous/cursor.py b/pymongo/asynchronous/cursor.py index 02954fb559..51efab4f43 100644 --- a/pymongo/asynchronous/cursor.py +++ b/pymongo/asynchronous/cursor.py @@ -767,6 +767,8 @@ async def explain(self) -> _DocumentType: :meth:`~pymongo.asynchronous.database.AsyncDatabase.command` to run the explain command directly. + .. note:: The timeout of this method can be set using :func:`pymongo.timeout`. + .. seealso:: The MongoDB documentation on `explain `_. """ c = self.clone() diff --git a/pymongo/synchronous/cursor.py b/pymongo/synchronous/cursor.py index ba35316516..e49141e811 100644 --- a/pymongo/synchronous/cursor.py +++ b/pymongo/synchronous/cursor.py @@ -765,6 +765,8 @@ def explain(self) -> _DocumentType: :meth:`~pymongo.database.Database.command` to run the explain command directly. + .. note:: The timeout of this method can be set using :func:`pymongo.timeout`. + .. seealso:: The MongoDB documentation on `explain `_. """ c = self.clone() diff --git a/test/asynchronous/test_cursor.py b/test/asynchronous/test_cursor.py index 8d2dbf532e..53b3289fb8 100644 --- a/test/asynchronous/test_cursor.py +++ b/test/asynchronous/test_cursor.py @@ -362,6 +362,24 @@ async def test_explain_with_read_concern(self): self.assertEqual(len(started), 1) self.assertNotIn("readConcern", started[0].command) + # https://github.com/mongodb/specifications/blob/master/source/crud/tests/README.md#14-explain-helpers-allow-users-to-specify-maxtimems + async def test_explain_csot(self): + # Create a MongoClient with command monitoring enabled (referred to as client). + listener = AllowListEventListener("explain") + client = await self.async_rs_or_single_client(event_listeners=[listener]) + + # Create a collection, referred to as collection, with the namespace explain-test.collection. + collection = client["explain-test"]["collection"] + + # Run an explained find on collection. The find will have the query predicate { name: 'john doe' }. Specify a maxTimeMS value of 2000ms for the explain. + with pymongo.timeout(2.0): + self.assertTrue(await collection.find({"name": "john doe"}).explain()) + + # Obtain the command started event for the explain. Confirm that the top-level explain command should has a maxTimeMS value of 2000. + started = listener.started_events + self.assertEqual(len(started), 1) + assert 1500 < started[0].command["maxTimeMS"] <= 2000 + async def test_hint(self): db = self.db with self.assertRaises(TypeError): diff --git a/test/test_cursor.py b/test/test_cursor.py index 4902d9e4df..d0bd48e747 100644 --- a/test/test_cursor.py +++ b/test/test_cursor.py @@ -354,6 +354,24 @@ def test_explain_with_read_concern(self): self.assertEqual(len(started), 1) self.assertNotIn("readConcern", started[0].command) + # https://github.com/mongodb/specifications/blob/master/source/crud/tests/README.md#14-explain-helpers-allow-users-to-specify-maxtimems + def test_explain_csot(self): + # Create a MongoClient with command monitoring enabled (referred to as client). + listener = AllowListEventListener("explain") + client = self.rs_or_single_client(event_listeners=[listener]) + + # Create a collection, referred to as collection, with the namespace explain-test.collection. + collection = client["explain-test"]["collection"] + + # Run an explained find on collection. The find will have the query predicate { name: 'john doe' }. Specify a maxTimeMS value of 2000ms for the explain. + with pymongo.timeout(2.0): + self.assertTrue(collection.find({"name": "john doe"}).explain()) + + # Obtain the command started event for the explain. Confirm that the top-level explain command should has a maxTimeMS value of 2000. + started = listener.started_events + self.assertEqual(len(started), 1) + assert 1500 < started[0].command["maxTimeMS"] <= 2000 + def test_hint(self): db = self.db with self.assertRaises(TypeError):