From 8f71800c4a891ed11b8f70efb3116ecc3d50db50 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 8 Nov 2023 10:13:38 -0600 Subject: [PATCH] MOTOR-1210 Update pre-commit to match PyMongo Checks (#232) * MOTOR-1210 Update pre-commit to match PyMongo Checks * update doctests --- .pre-commit-config.yaml | 63 +++++++++++--- RELEASE.rst | 8 +- doc/changelog.rst | 56 ++++++------- doc/differences.rst | 20 ++--- doc/examples/aiohttp_example.py | 1 + doc/examples/bulk.rst | 43 +++++----- doc/examples/tailable-cursors.rst | 15 ++-- .../tornado_change_stream_example.rst | 4 +- doc/features.rst | 4 +- doc/migrate-to-motor-2.rst | 6 +- doc/migrate-to-motor-3.rst | 2 +- doc/mongo_extensions.py | 1 - doc/tutorial-asyncio.rst | 82 ++++++++++--------- doc/tutorial-tornado.rst | 82 +++++++++---------- motor/aiohttp/__init__.py | 6 +- motor/core.py | 61 +++++++------- motor/docstrings.py | 57 ++++++------- motor/motor_gridfs.py | 2 +- motor/motor_gridfs.pyi | 2 +- motor/web.py | 8 +- pyproject.toml | 7 +- synchro/__init__.py | 6 +- synchro/synchrotest.py | 2 +- test/asyncio_tests/__init__.py | 2 +- test/asyncio_tests/test_examples.py | 1 - test/tornado_tests/__init__.py | 1 - 26 files changed, 293 insertions(+), 249 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 14f6dfaf..6abbcc2c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,13 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.5.0 hooks: - id: check-added-large-files - id: check-case-conflict - id: check-toml - id: check-yaml + exclude: template.yaml - id: debug-statements - id: end-of-file-fixer exclude: WHEEL @@ -16,34 +17,74 @@ repos: exclude: .patch exclude_types: [json] -- repo: https://github.com/psf/black - rev: 22.3.0 - hooks: - - id: black - files: \.(py|pyi)$ - args: [--line-length=100] - - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.1.1 + rev: v0.1.3 hooks: - id: ruff args: ["--fix", "--show-fixes"] + - id: ruff-format + +- repo: https://github.com/adamchainz/blacken-docs + rev: "1.16.0" + hooks: + - id: blacken-docs + additional_dependencies: + - black==22.3.0 + +- repo: https://github.com/pre-commit/pygrep-hooks + rev: "v1.10.0" + hooks: + - id: rst-backticks + - id: rst-directive-colons + - id: rst-inline-touching-normal + +- repo: https://github.com/rstcheck/rstcheck + rev: v6.2.0 + hooks: + - id: rstcheck + additional_dependencies: [sphinx] + args: ["--ignore-directives=doctest,testsetup,todo,automodule,mongodoc,autodoc,testcleanup,autoclass","--ignore-substitutions=release", "--report-level=error"] + exclude: '^doc/migrate-to-motor-3.rst' # We use the Python version instead of the original version which seems to require Docker # https://github.com/koalaman/shellcheck-precommit - repo: https://github.com/shellcheck-py/shellcheck-py - rev: v0.8.0.4 + rev: v0.9.0.6 hooks: - id: shellcheck name: shellcheck args: ["--severity=warning"] + stages: [manual] + +- repo: https://github.com/PyCQA/doc8 + rev: v1.1.1 + hooks: + - id: doc8 + args: ["--ignore=D001"] # ignore line length + stages: [manual] - repo: https://github.com/sirosen/check-jsonschema - rev: 0.14.1 + rev: 0.27.0 hooks: - id: check-jsonschema name: "Check GitHub Workflows" files: ^\.github/workflows/ types: [yaml] args: ["--schemafile", "https://json.schemastore.org/github-workflow"] + +- repo: https://github.com/ariebovenberg/slotscheck + rev: v0.17.0 + hooks: + - id: slotscheck + files: \.py$ + exclude: "^(doc|test)/" + stages: [manual] + args: ["--no-strict-imports"] + + +- repo: https://github.com/codespell-project/codespell + rev: "v2.2.6" + hooks: + - id: codespell + args: ["-L", "fle"] diff --git a/RELEASE.rst b/RELEASE.rst index 2cb046cb..ad944a11 100644 --- a/RELEASE.rst +++ b/RELEASE.rst @@ -29,13 +29,13 @@ and a `source distribution " @@ -45,7 +45,7 @@ and a `source distribution >> db.system_js.my_func = 'function(x) { return x * x; }' + >>> db.system_js.my_func = "function(x) { return x * x; }" >>> db.system_js.my_func(2) 4.0 @@ -133,17 +133,10 @@ There are two ways to create a capped collection using PyMongo: .. code-block:: python # Typical: - db.create_collection( - 'collection1', - capped=True, - size=1000) + db.create_collection("collection1", capped=True, size=1000) # Unusual: - collection = Collection( - db, - 'collection2', - capped=True, - size=1000) + collection = Collection(db, "collection2", capped=True, size=1000) Motor can't do I/O in a constructor, so the unusual style is prohibited and only the typical style is allowed: @@ -151,7 +144,4 @@ only the typical style is allowed: .. code-block:: python async def f(): - await db.create_collection( - 'collection1', - capped=True, - size=1000) + await db.create_collection("collection1", capped=True, size=1000) diff --git a/doc/examples/aiohttp_example.py b/doc/examples/aiohttp_example.py index f768a7ab..113bcb2f 100644 --- a/doc/examples/aiohttp_example.py +++ b/doc/examples/aiohttp_example.py @@ -38,6 +38,7 @@ async def page_handler(request): # -- handler-end -- + # -- main-start -- async def init_connection(): db = await setup_db() diff --git a/doc/examples/bulk.rst b/doc/examples/bulk.rst index d2a46c82..441966eb 100644 --- a/doc/examples/bulk.rst +++ b/doc/examples/bulk.rst @@ -31,9 +31,10 @@ bulk insert operations. .. doctest:: >>> async def f(): - ... await db.test.insert_many(({'i': i} for i in range(10000))) + ... await db.test.insert_many(({"i": i} for i in range(10000))) ... count = await db.test.count_documents({}) ... print("Final count: %d" % count) + ... >>> >>> IOLoop.current().run_sync(f) Final count: 10000 @@ -61,14 +62,17 @@ of operations performed. >>> from pprint import pprint >>> from pymongo import InsertOne, DeleteMany, ReplaceOne, UpdateOne >>> async def f(): - ... result = await db.test.bulk_write([ - ... DeleteMany({}), # Remove all documents from the previous example. - ... InsertOne({'_id': 1}), - ... InsertOne({'_id': 2}), - ... InsertOne({'_id': 3}), - ... UpdateOne({'_id': 1}, {'$set': {'foo': 'bar'}}), - ... UpdateOne({'_id': 4}, {'$inc': {'j': 1}}, upsert=True), - ... ReplaceOne({'j': 1}, {'j': 2})]) + ... result = await db.test.bulk_write( + ... [ + ... DeleteMany({}), # Remove all documents from the previous example. + ... InsertOne({"_id": 1}), + ... InsertOne({"_id": 2}), + ... InsertOne({"_id": 3}), + ... UpdateOne({"_id": 1}, {"$set": {"foo": "bar"}}), + ... UpdateOne({"_id": 4}, {"$inc": {"j": 1}}, upsert=True), + ... ReplaceOne({"j": 1}, {"j": 2}), + ... ] + ... ) ... pprint(result.bulk_api_result) ... >>> IOLoop.current().run_sync(f) @@ -95,9 +99,10 @@ the failure. >>> from pymongo.errors import BulkWriteError >>> async def f(): ... requests = [ - ... ReplaceOne({'j': 2}, {'i': 5}), - ... InsertOne({'_id': 4}), # Violates the unique key constraint on _id. - ... DeleteOne({'i': 5})] + ... ReplaceOne({"j": 2}, {"i": 5}), + ... InsertOne({"_id": 4}), # Violates the unique key constraint on _id. + ... DeleteOne({"i": 5}), + ... ] ... try: ... await db.test.bulk_write(requests) ... except BulkWriteError as bwe: @@ -136,10 +141,11 @@ and fourth operations succeed. >>> async def f(): ... requests = [ - ... InsertOne({'_id': 1}), - ... DeleteOne({'_id': 2}), - ... InsertOne({'_id': 3}), - ... ReplaceOne({'_id': 4}, {'i': 1})] + ... InsertOne({"_id": 1}), + ... DeleteOne({"_id": 2}), + ... InsertOne({"_id": 3}), + ... ReplaceOne({"_id": 4}, {"i": 1}), + ... ] ... try: ... await db.test.bulk_write(requests, ordered=False) ... except BulkWriteError as bwe: @@ -181,10 +187,9 @@ after all operations are attempted, regardless of execution order. >>> from pymongo import WriteConcern >>> async def f(): - ... coll = db.get_collection( - ... 'test', write_concern=WriteConcern(w=4, wtimeout=1)) + ... coll = db.get_collection("test", write_concern=WriteConcern(w=4, wtimeout=1)) ... try: - ... await coll.bulk_write([InsertOne({'a': i}) for i in range(4)]) + ... await coll.bulk_write([InsertOne({"a": i}) for i in range(4)]) ... except BulkWriteError as bwe: ... pprint(bwe.details) ... diff --git a/doc/examples/tailable-cursors.rst b/doc/examples/tailable-cursors.rst index 43ac4940..88ea994d 100644 --- a/doc/examples/tailable-cursors.rst +++ b/doc/examples/tailable-cursors.rst @@ -16,11 +16,12 @@ of a replica set member: from asyncio import sleep from pymongo.cursor import CursorType + async def tail_oplog_example(): oplog = client.local.oplog.rs - first = await oplog.find().sort('$natural', pymongo.ASCENDING).limit(-1).next() + first = await oplog.find().sort("$natural", pymongo.ASCENDING).limit(-1).next() print(first) - ts = first['ts'] + ts = first["ts"] while True: # For a regular capped collection CursorType.TAILABLE_AWAIT is the @@ -30,12 +31,14 @@ of a replica set member: # can only be used when querying the oplog. Starting in MongoDB 4.4 # this option is ignored by the server as queries against the oplog # are optimized automatically by the MongoDB query engine. - cursor = oplog.find({'ts': {'$gt': ts}}, - cursor_type=CursorType.TAILABLE_AWAIT, - oplog_replay=True) + cursor = oplog.find( + {"ts": {"$gt": ts}}, + cursor_type=CursorType.TAILABLE_AWAIT, + oplog_replay=True, + ) while cursor.alive: async for doc in cursor: - ts = doc['ts'] + ts = doc["ts"] print(doc) # We end up here if the find() returned no documents or if the # tailable cursor timed out (no new documents were added to the diff --git a/doc/examples/tornado_change_stream_example.rst b/doc/examples/tornado_change_stream_example.rst index 0a3a8d58..55c8009e 100644 --- a/doc/examples/tornado_change_stream_example.rst +++ b/doc/examples/tornado_change_stream_example.rst @@ -18,7 +18,7 @@ http://localhost:8888 Open a ``mongo`` shell in the terminal and perform some operations on the "test" collection in the "test" database: -.. code-block:: none +.. code-block:: text > use test switched to db test @@ -29,7 +29,7 @@ Open a ``mongo`` shell in the terminal and perform some operations on the The application receives each change notification and displays it as JSON on the web page: -.. code-block:: none +.. code-block:: text Changes diff --git a/doc/features.rst b/doc/features.rst index 91150938..d028254e 100644 --- a/doc/features.rst +++ b/doc/features.rst @@ -20,8 +20,8 @@ Featureful Motor wraps almost all of PyMongo's API and makes it non-blocking. For the few PyMongo features not implemented in Motor, see :doc:`differences`. -Convenient With `tornado.gen` -============================= +Convenient With ``tornado.gen`` +=============================== The :mod:`tornado.gen` module lets you use coroutines to simplify asynchronous code. Motor methods return Futures that are convenient to use with coroutines. diff --git a/doc/migrate-to-motor-2.rst b/doc/migrate-to-motor-2.rst index 5ef1a5d1..f90be847 100644 --- a/doc/migrate-to-motor-2.rst +++ b/doc/migrate-to-motor-2.rst @@ -118,6 +118,7 @@ used callbacks: else: print(result) + collection.find_one({}, callback=callback) Callbacks have been largely superseded by a Futures API intended for use with @@ -134,6 +135,7 @@ a parameter: except Exception as exc: print(exc) + future = collection.find_one({}) future.add_done_callback(callback) @@ -181,7 +183,7 @@ Or: .. code-block:: python3 with client.start_session() as session: - doc = client.db.collection.find_one({}, session=session) + doc = client.db.collection.find_one({}, session=session) To support multi-document transactions, in Motor 2.0 :meth:`MotorClient.start_session` is a coroutine, not a regular method. It must @@ -203,4 +205,4 @@ Or: .. code-block:: python3 async with client.start_session() as session: - doc = await client.db.collection.find_one({}, session=session) + doc = await client.db.collection.find_one({}, session=session) diff --git a/doc/migrate-to-motor-3.rst b/doc/migrate-to-motor-3.rst index 004fab35..41f523f7 100644 --- a/doc/migrate-to-motor-3.rst +++ b/doc/migrate-to-motor-3.rst @@ -422,7 +422,7 @@ GridFS changes disable_md5 parameter is removed ................................ -Removed the `disable_md5` option for :class:`~motor.motor_tornado.gridfs.MotorGridFSBucket` and +Removed the ``disable_md5`` option for :class:`~motor.motor_tornado.gridfs.MotorGridFSBucket` and :class:`~motor.motor_tornado.gridfs.MotorGridFS`. GridFS no longer generates checksums. Applications that desire a file digest should implement it outside GridFS and store it with other file metadata. For example:: diff --git a/doc/mongo_extensions.py b/doc/mongo_extensions.py index 7382dc05..ddc76a3d 100644 --- a/doc/mongo_extensions.py +++ b/doc/mongo_extensions.py @@ -47,7 +47,6 @@ def depart_mongoref_node(self, node): class MongodocDirective(rst.Directive): - has_content = True required_arguments = 0 optional_arguments = 0 diff --git a/doc/tutorial-asyncio.rst b/doc/tutorial-asyncio.rst index 59153eb9..cfa69204 100644 --- a/doc/tutorial-asyncio.rst +++ b/doc/tutorial-asyncio.rst @@ -12,6 +12,7 @@ Tutorial: Using Motor With :mod:`asyncio` import pymongo import motor.motor_asyncio import asyncio + client = motor.motor_asyncio.AsyncIOMotorClient() db = client.test_database @@ -20,14 +21,17 @@ Tutorial: Using Motor With :mod:`asyncio` import pymongo import motor.motor_asyncio import asyncio + client = motor.motor_asyncio.AsyncIOMotorClient() db = client.test_database pymongo.MongoClient().test_database.test_collection.insert_many( - [{'i': i} for i in range(2000)]) + [{"i": i} for i in range(2000)] + ) .. testcleanup:: * import pymongo + pymongo.MongoClient().test_database.test_collection.delete_many({}) A guide to using MongoDB and asyncio with Motor. @@ -87,13 +91,13 @@ specify the host and port like: .. doctest:: before-inserting-2000-docs - >>> client = motor.motor_asyncio.AsyncIOMotorClient('localhost', 27017) + >>> client = motor.motor_asyncio.AsyncIOMotorClient("localhost", 27017) Motor also supports `connection URIs`_: .. doctest:: before-inserting-2000-docs - >>> client = motor.motor_asyncio.AsyncIOMotorClient('mongodb://localhost:27017') + >>> client = motor.motor_asyncio.AsyncIOMotorClient("mongodb://localhost:27017") Connect to a replica set like: @@ -111,7 +115,7 @@ dot-notation or bracket-notation: .. doctest:: before-inserting-2000-docs >>> db = client.test_database - >>> db = client['test_database'] + >>> db = client["test_database"] Creating a reference to a database does no I/O and does not require an ``await`` expression. @@ -126,7 +130,7 @@ collection in Motor works the same as getting a database: .. doctest:: before-inserting-2000-docs >>> collection = db.test_collection - >>> collection = db['test_collection'] + >>> collection = db["test_collection"] Just like getting a reference to a database, getting a reference to a collection does no I/O and doesn't require an ``await`` expression. @@ -140,9 +144,9 @@ store a document in MongoDB, call :meth:`~AsyncIOMotorCollection.insert_one` in .. doctest:: before-inserting-2000-docs >>> async def do_insert(): - ... document = {'key': 'value'} + ... document = {"key": "value"} ... result = await db.test_collection.insert_one(document) - ... print('result %s' % repr(result.inserted_id)) + ... print("result %s" % repr(result.inserted_id)) ... >>> >>> import asyncio @@ -157,23 +161,22 @@ store a document in MongoDB, call :meth:`~AsyncIOMotorCollection.insert_one` in >>> # Clean up from previous insert >>> pymongo.MongoClient().test_database.test_collection.delete_many({}) - + DeleteResult({'n': 1, 'ok': 1.0}, acknowledged=True) Insert documents in large batches with :meth:`~AsyncIOMotorCollection.insert_many`: .. doctest:: before-inserting-2000-docs >>> async def do_insert(): - ... result = await db.test_collection.insert_many( - ... [{'i': i} for i in range(2000)]) - ... print('inserted %d docs' % (len(result.inserted_ids),)) + ... result = await db.test_collection.insert_many([{"i": i} for i in range(2000)]) + ... print("inserted %d docs" % (len(result.inserted_ids),)) ... >>> loop = client.get_io_loop() >>> loop.run_until_complete(do_insert()) inserted 2000 docs -Getting a Single Document With `find_one` ------------------------------------------ +Getting a Single Document With ``find_one`` +------------------------------------------- Use :meth:`~motor.motor_asyncio.AsyncIOMotorCollection.find_one` to get the first document that matches a query. For example, to get a document where the value for key "i" is @@ -182,7 +185,7 @@ less than 1: .. doctest:: after-inserting-2000-docs >>> async def do_find_one(): - ... document = await db.test_collection.find_one({'i': {'$lt': 1}}) + ... document = await db.test_collection.find_one({"i": {"$lt": 1}}) ... pprint.pprint(document) ... >>> loop = client.get_io_loop() @@ -209,7 +212,7 @@ To find all documents with "i" less than 5: .. doctest:: after-inserting-2000-docs >>> async def do_find(): - ... cursor = db.test_collection.find({'i': {'$lt': 5}}).sort('i') + ... cursor = db.test_collection.find({"i": {"$lt": 5}}).sort("i") ... for document in await cursor.to_list(length=100): ... pprint.pprint(document) ... @@ -233,7 +236,7 @@ You can handle one document at a time in an ``async for`` loop: >>> async def do_find(): ... c = db.test_collection - ... async for document in c.find({'i': {'$lt': 2}}): + ... async for document in c.find({"i": {"$lt": 2}}): ... pprint.pprint(document) ... >>> loop = client.get_io_loop() @@ -246,9 +249,9 @@ You can apply a sort, limit, or skip to a query before you begin iterating: .. doctest:: after-inserting-2000-docs >>> async def do_find(): - ... cursor = db.test_collection.find({'i': {'$lt': 4}}) + ... cursor = db.test_collection.find({"i": {"$lt": 4}}) ... # Modify the query before iterating - ... cursor.sort('i', -1).skip(1).limit(2) + ... cursor.sort("i", -1).skip(1).limit(2) ... async for document in cursor: ... pprint.pprint(document) ... @@ -272,9 +275,9 @@ that match a query: >>> async def do_count(): ... n = await db.test_collection.count_documents({}) - ... print('%s documents in collection' % n) - ... n = await db.test_collection.count_documents({'i': {'$gt': 1000}}) - ... print('%s documents where i > 1000' % n) + ... print("%s documents in collection" % n) + ... n = await db.test_collection.count_documents({"i": {"$gt": 1000}}) + ... print("%s documents where i > 1000" % n) ... >>> loop = client.get_io_loop() >>> loop.run_until_complete(do_count()) @@ -293,13 +296,13 @@ replacement document. The query follows the same syntax as for :meth:`find` or >>> async def do_replace(): ... coll = db.test_collection - ... old_document = await coll.find_one({'i': 50}) - ... print('found document: %s' % pprint.pformat(old_document)) - ... _id = old_document['_id'] - ... result = await coll.replace_one({'_id': _id}, {'key': 'value'}) - ... print('replaced %s document' % result.modified_count) - ... new_document = await coll.find_one({'_id': _id}) - ... print('document is now %s' % pprint.pformat(new_document)) + ... old_document = await coll.find_one({"i": 50}) + ... print("found document: %s" % pprint.pformat(old_document)) + ... _id = old_document["_id"] + ... result = await coll.replace_one({"_id": _id}, {"key": "value"}) + ... print("replaced %s document" % result.modified_count) + ... new_document = await coll.find_one({"_id": _id}) + ... print("document is now %s" % pprint.pformat(new_document)) ... >>> loop = client.get_io_loop() >>> loop.run_until_complete(do_replace()) @@ -319,10 +322,10 @@ operator to set "key" to "value": >>> async def do_update(): ... coll = db.test_collection - ... result = await coll.update_one({'i': 51}, {'$set': {'key': 'value'}}) - ... print('updated %s document' % result.modified_count) - ... new_document = await coll.find_one({'i': 51}) - ... print('document is now %s' % pprint.pformat(new_document)) + ... result = await coll.update_one({"i": 51}, {"$set": {"key": "value"}}) + ... print("updated %s document" % result.modified_count) + ... new_document = await coll.find_one({"i": 51}) + ... print("document is now %s" % pprint.pformat(new_document)) ... >>> loop = client.get_io_loop() >>> loop.run_until_complete(do_update()) @@ -351,9 +354,9 @@ Deleting Documents >>> async def do_delete_one(): ... coll = db.test_collection ... n = await coll.count_documents({}) - ... print('%s documents before calling delete_one()' % n) - ... result = await db.test_collection.delete_one({'i': {'$gte': 1000}}) - ... print('%s documents after' % (await coll.count_documents({}))) + ... print("%s documents before calling delete_one()" % n) + ... result = await db.test_collection.delete_one({"i": {"$gte": 1000}}) + ... print("%s documents after" % (await coll.count_documents({}))) ... >>> loop = client.get_io_loop() >>> loop.run_until_complete(do_delete_one()) @@ -369,9 +372,9 @@ Deleting Documents >>> async def do_delete_many(): ... coll = db.test_collection ... n = await coll.count_documents({}) - ... print('%s documents before calling delete_many()' % n) - ... result = await db.test_collection.delete_many({'i': {'$gte': 1000}}) - ... print('%s documents after' % (await coll.count_documents({}))) + ... print("%s documents before calling delete_many()" % n) + ... result = await db.test_collection.delete_many({"i": {"$gte": 1000}}) + ... print("%s documents after" % (await coll.count_documents({}))) ... >>> loop = client.get_io_loop() >>> loop.run_until_complete(do_delete_many()) @@ -390,8 +393,7 @@ the :meth:`~motor.motor_asyncio.AsyncIOMotorDatabase.command` method on >>> from bson import SON >>> async def use_distinct_command(): - ... response = await db.command(SON([("distinct", "test_collection"), - ... ("key", "i")])) + ... response = await db.command(SON([("distinct", "test_collection"), ("key", "i")])) ... >>> loop = client.get_io_loop() >>> loop.run_until_complete(use_distinct_command()) diff --git a/doc/tutorial-tornado.rst b/doc/tutorial-tornado.rst index 2d235e97..5004d9d9 100644 --- a/doc/tutorial-tornado.rst +++ b/doc/tutorial-tornado.rst @@ -14,6 +14,7 @@ Tutorial: Using Motor With Tornado import tornado.web from tornado.ioloop import IOLoop from tornado import gen + db = motor.motor_tornado.MotorClient().test_database .. testsetup:: after-inserting-2000-docs @@ -23,15 +24,16 @@ Tutorial: Using Motor With Tornado import tornado.web from tornado.ioloop import IOLoop from tornado import gen + db = motor.motor_tornado.MotorClient().test_database sync_db = pymongo.MongoClient().test_database sync_db.test_collection.drop() - sync_db.test_collection.insert_many( - [{'i': i} for i in range(2000)]) + sync_db.test_collection.insert_many([{"i": i} for i in range(2000)]) .. testcleanup:: * import pymongo + pymongo.MongoClient().test_database.test_collection.delete_many({}) A guide to using MongoDB and Tornado with Motor. @@ -96,13 +98,13 @@ specify the host and port like: .. doctest:: before-inserting-2000-docs - >>> client = motor.motor_tornado.MotorClient('localhost', 27017) + >>> client = motor.motor_tornado.MotorClient("localhost", 27017) Motor also supports `connection URIs`_: .. doctest:: before-inserting-2000-docs - >>> client = motor.motor_tornado.MotorClient('mongodb://localhost:27017') + >>> client = motor.motor_tornado.MotorClient("mongodb://localhost:27017") Connect to a replica set like: @@ -120,7 +122,7 @@ dot-notation or bracket-notation: .. doctest:: before-inserting-2000-docs >>> db = client.test_database - >>> db = client['test_database'] + >>> db = client["test_database"] Creating a reference to a database does no I/O and does not require an ``await`` expression. @@ -187,7 +189,7 @@ collection in Motor works the same as getting a database: .. doctest:: before-inserting-2000-docs >>> collection = db.test_collection - >>> collection = db['test_collection'] + >>> collection = db["test_collection"] Just like getting a reference to a database, getting a reference to a collection does no I/O and doesn't require an ``await`` expression. @@ -201,9 +203,9 @@ store a document in MongoDB, call :meth:`~MotorCollection.insert_one` in an .. doctest:: before-inserting-2000-docs >>> async def do_insert(): - ... document = {'key': 'value'} + ... document = {"key": "value"} ... result = await db.test_collection.insert_one(document) - ... print('result %s' % repr(result.inserted_id)) + ... print("result %s" % repr(result.inserted_id)) ... >>> >>> IOLoop.current().run_sync(do_insert) @@ -216,7 +218,7 @@ store a document in MongoDB, call :meth:`~MotorCollection.insert_one` in an >>> # Clean up from previous insert >>> pymongo.MongoClient().test_database.test_collection.delete_many({}) - + DeleteResult({'n': 1, 'ok': 1.0}, acknowledged=True) A typical beginner's mistake with Motor is to insert documents in a loop, not waiting for each insert to complete before beginning the next:: @@ -236,7 +238,7 @@ sequence, use ``await``: >>> async def do_insert(): ... for i in range(2000): - ... await db.test_collection.insert_one({'i': i}) + ... await db.test_collection.insert_one({"i": i}) ... >>> IOLoop.current().run_sync(do_insert) @@ -249,7 +251,7 @@ sequence, use ``await``: >>> # Clean up from previous insert >>> pymongo.MongoClient().test_database.test_collection.delete_many({}) - + DeleteResult({'n': 2000, 'ok': 1.0}, acknowledged=True) For better performance, insert documents in large batches with :meth:`~MotorCollection.insert_many`: @@ -257,9 +259,8 @@ For better performance, insert documents in large batches with .. doctest:: before-inserting-2000-docs >>> async def do_insert(): - ... result = await db.test_collection.insert_many( - ... [{'i': i} for i in range(2000)]) - ... print('inserted %d docs' % (len(result.inserted_ids),)) + ... result = await db.test_collection.insert_many([{"i": i} for i in range(2000)]) + ... print("inserted %d docs" % (len(result.inserted_ids),)) ... >>> IOLoop.current().run_sync(do_insert) inserted 2000 docs @@ -273,7 +274,7 @@ less than 1: .. doctest:: after-inserting-2000-docs >>> async def do_find_one(): - ... document = await db.test_collection.find_one({'i': {'$lt': 1}}) + ... document = await db.test_collection.find_one({"i": {"$lt": 1}}) ... pprint.pprint(document) ... >>> IOLoop.current().run_sync(do_find_one) @@ -302,7 +303,7 @@ To find all documents with "i" less than 5: .. doctest:: after-inserting-2000-docs >>> async def do_find(): - ... cursor = db.test_collection.find({'i': {'$lt': 5}}).sort('i') + ... cursor = db.test_collection.find({"i": {"$lt": 5}}).sort("i") ... for document in await cursor.to_list(length=100): ... pprint.pprint(document) ... @@ -325,7 +326,7 @@ You can handle one document at a time in an ``async for`` loop: >>> async def do_find(): ... c = db.test_collection - ... async for document in c.find({'i': {'$lt': 2}}): + ... async for document in c.find({"i": {"$lt": 2}}): ... pprint.pprint(document) ... >>> IOLoop.current().run_sync(do_find) @@ -337,9 +338,9 @@ You can apply a sort, limit, or skip to a query before you begin iterating: .. doctest:: after-inserting-2000-docs >>> async def do_find(): - ... cursor = db.test_collection.find({'i': {'$lt': 4}}) + ... cursor = db.test_collection.find({"i": {"$lt": 4}}) ... # Modify the query before iterating - ... cursor.sort('i', -1).skip(1).limit(2) + ... cursor.sort("i", -1).skip(1).limit(2) ... async for document in cursor: ... pprint.pprint(document) ... @@ -361,9 +362,9 @@ documents in a collection, or the number of documents that match a query: >>> async def do_count(): ... n = await db.test_collection.count_documents({}) - ... print('%s documents in collection' % n) - ... n = await db.test_collection.count_documents({'i': {'$gt': 1000}}) - ... print('%s documents where i > 1000' % n) + ... print("%s documents in collection" % n) + ... n = await db.test_collection.count_documents({"i": {"$gt": 1000}}) + ... print("%s documents where i > 1000" % n) ... >>> IOLoop.current().run_sync(do_count) 2000 documents in collection @@ -381,13 +382,13 @@ replacement document. The query follows the same syntax as for :meth:`find` or >>> async def do_replace(): ... coll = db.test_collection - ... old_document = await coll.find_one({'i': 50}) - ... print('found document: %s' % pprint.pformat(old_document)) - ... _id = old_document['_id'] - ... result = await coll.replace_one({'_id': _id}, {'key': 'value'}) - ... print('replaced %s document' % result.modified_count) - ... new_document = await coll.find_one({'_id': _id}) - ... print('document is now %s' % pprint.pformat(new_document)) + ... old_document = await coll.find_one({"i": 50}) + ... print("found document: %s" % pprint.pformat(old_document)) + ... _id = old_document["_id"] + ... result = await coll.replace_one({"_id": _id}, {"key": "value"}) + ... print("replaced %s document" % result.modified_count) + ... new_document = await coll.find_one({"_id": _id}) + ... print("document is now %s" % pprint.pformat(new_document)) ... >>> IOLoop.current().run_sync(do_replace) found document: {'_id': ObjectId('...'), 'i': 50} @@ -406,10 +407,10 @@ operator to set "key" to "value": >>> async def do_update(): ... coll = db.test_collection - ... result = await coll.update_one({'i': 51}, {'$set': {'key': 'value'}}) - ... print('updated %s document' % result.modified_count) - ... new_document = await coll.find_one({'i': 51}) - ... print('document is now %s' % pprint.pformat(new_document)) + ... result = await coll.update_one({"i": 51}, {"$set": {"key": "value"}}) + ... print("updated %s document" % result.modified_count) + ... new_document = await coll.find_one({"i": 51}) + ... print("document is now %s" % pprint.pformat(new_document)) ... >>> IOLoop.current().run_sync(do_update) updated 1 document @@ -437,9 +438,9 @@ Removing Documents >>> async def do_delete_one(): ... coll = db.test_collection ... n = await coll.count_documents({}) - ... print('%s documents before calling delete_one()' % n) - ... result = await db.test_collection.delete_one({'i': {'$gte': 1000}}) - ... print('%s documents after' % (await coll.count_documents({}))) + ... print("%s documents before calling delete_one()" % n) + ... result = await db.test_collection.delete_one({"i": {"$gte": 1000}}) + ... print("%s documents after" % (await coll.count_documents({}))) ... >>> IOLoop.current().run_sync(do_delete_one) 2000 documents before calling delete_one() @@ -454,9 +455,9 @@ Removing Documents >>> async def do_delete_many(): ... coll = db.test_collection ... n = await coll.count_documents({}) - ... print('%s documents before calling delete_many()' % n) - ... result = await db.test_collection.delete_many({'i': {'$gte': 1000}}) - ... print('%s documents after' % (await coll.count_documents({}))) + ... print("%s documents before calling delete_many()" % n) + ... result = await db.test_collection.delete_many({"i": {"$gte": 1000}}) + ... print("%s documents after" % (await coll.count_documents({}))) ... >>> IOLoop.current().run_sync(do_delete_many) 1999 documents before calling delete_many() @@ -474,8 +475,7 @@ the :meth:`~motor.motor_tornado.MotorDatabase.command` method on >>> from bson import SON >>> async def use_distinct_command(): - ... response = await db.command(SON([("distinct", "test_collection"), - ... ("key", "i")])) + ... response = await db.command(SON([("distinct", "test_collection"), ("key", "i")])) ... >>> IOLoop.current().run_sync(use_distinct_command) diff --git a/motor/aiohttp/__init__.py b/motor/aiohttp/__init__.py index 9566da7f..bde3b13e 100644 --- a/motor/aiohttp/__init__.py +++ b/motor/aiohttp/__init__.py @@ -133,9 +133,9 @@ class AIOHTTPGridFS: app = aiohttp.web.Application() # The GridFS URL pattern must have a "{filename}" variable. - resource = app.router.add_resource('/fs/{filename}') - resource.add_route('GET', gridfs_handler) - resource.add_route('HEAD', gridfs_handler) + resource = app.router.add_resource("/fs/{filename}") + resource.add_route("GET", gridfs_handler) + resource.add_route("HEAD", gridfs_handler) app_handler = app.make_handler() server = loop.create_server(app_handler, port=80) diff --git a/motor/core.py b/motor/core.py index adbcae65..3f2133c1 100644 --- a/motor/core.py +++ b/motor/core.py @@ -321,8 +321,8 @@ class AgnosticClientSession(AgnosticBase): async with await client.start_session() as s: async with s.start_transaction(): - await collection.delete_one({'x': 1}, session=s) - await collection.insert_one({'x': 2}, session=s) + await collection.delete_one({"x": 1}, session=s) + await collection.insert_one({"x": 2}, session=s) .. versionadded:: 2.0 """ @@ -388,7 +388,7 @@ class AgnosticClientSession(AgnosticBase): In the event of an exception, ``with_transaction`` may retry the commit or the entire transaction, therefore ``coro`` may be awaited multiple times by a single call to ``with_transaction``. Developers - should be mindful of this possiblity when writing a ``coro`` that + should be mindful of this possibility when writing a ``coro`` that modifies application state or has any other side-effects. Note that even when the ``coro`` is invoked multiple times, ``with_transaction`` ensures that the transaction will be committed @@ -500,8 +500,8 @@ class AgnosticClientSession(AgnosticBase): # Use "await" for start_session, but not for start_transaction. async with await client.start_session() as s: async with s.start_transaction(): - await collection.delete_one({'x': 1}, session=s) - await collection.insert_one({'x': 2}, session=s) + await collection.delete_one({"x": 1}, session=s) + await collection.insert_one({"x": 2}, session=s) """ self.delegate.start_transaction( @@ -1171,6 +1171,7 @@ class AgnosticCollection(AgnosticBaseProperties): change_stream = None + async def watch_collection(): global change_stream @@ -1181,17 +1182,20 @@ class AgnosticCollection(AgnosticBaseProperties): async for change in change_stream: print(change) + # Tornado from tornado.ioloop import IOLoop + def main(): loop = IOLoop.current() # Start watching collection for changes. - try: - loop.run_sync(watch_collection) - except KeyboardInterrupt: - if change_stream: - loop.run_sync(change_stream.close) + try: + loop.run_sync(watch_collection) + except KeyboardInterrupt: + if change_stream: + loop.run_sync(change_stream.close) + # asyncio try: @@ -1210,14 +1214,14 @@ class AgnosticCollection(AgnosticBaseProperties): .. code-block:: python3 try: - pipeline = [{'$match': {'operationType': 'insert'}}] + pipeline = [{"$match": {"operationType": "insert"}}] async with db.collection.watch(pipeline) as stream: async for change in stream: print(change) except pymongo.errors.PyMongoError: # The ChangeStream encountered an unrecoverable error or the # resume attempt failed to recreate the cursor. - logging.error('...') + logging.error("...") For a precise description of the resume process see the `change streams specification`_. @@ -1435,10 +1439,10 @@ class AgnosticBaseCursor(AgnosticBase): >>> async def f(): ... await collection.drop() - ... await collection.insert_many([{'_id': i} for i in range(5)]) + ... await collection.insert_many([{"_id": i} for i in range(5)]) ... async for doc in collection.find(): - ... sys.stdout.write(str(doc['_id']) + ', ') - ... print('done') + ... sys.stdout.write(str(doc["_id"]) + ", ") + ... print("done") ... >>> IOLoop.current().run_sync(f) 0, 1, 2, 3, 4, done @@ -1451,12 +1455,12 @@ class AgnosticBaseCursor(AgnosticBase): >>> async def f(): ... await collection.drop() - ... await collection.insert_many([{'_id': i} for i in range(5)]) - ... cursor = collection.find().sort([('_id', 1)]) - ... while (await cursor.fetch_next): + ... await collection.insert_many([{"_id": i} for i in range(5)]) + ... cursor = collection.find().sort([("_id", 1)]) + ... while await cursor.fetch_next: ... doc = cursor.next_object() - ... sys.stdout.write(str(doc['_id']) + ', ') - ... print('done') + ... sys.stdout.write(str(doc["_id"]) + ", ") + ... print("done") ... >>> IOLoop.current().run_sync(f) 0, 1, 2, 3, 4, done @@ -1524,9 +1528,9 @@ class AgnosticBaseCursor(AgnosticBase): .. testsetup:: each from tornado.ioloop import IOLoop + MongoClient().test.test_collection.delete_many({}) - MongoClient().test.test_collection.insert_many( - [{'_id': i} for i in range(5)]) + MongoClient().test.test_collection.insert_many([{"_id": i} for i in range(5)]) collection = MotorClient().test.test_collection @@ -1536,13 +1540,13 @@ class AgnosticBaseCursor(AgnosticBase): ... if error: ... raise error ... elif result: - ... sys.stdout.write(str(result['_id']) + ', ') + ... sys.stdout.write(str(result["_id"]) + ", ") ... else: ... # Iteration complete ... IOLoop.current().stop() - ... print('done') + ... print("done") ... - >>> cursor = collection.find().sort([('_id', 1)]) + >>> cursor = collection.find().sort([("_id", 1)]) >>> cursor.each(callback=each) >>> IOLoop.current().start() 0, 1, 2, 3, 4, done @@ -1594,7 +1598,7 @@ class AgnosticBaseCursor(AgnosticBase): .. testsetup:: to_list MongoClient().test.test_collection.delete_many({}) - MongoClient().test.test_collection.insert_many([{'_id': i} for i in range(4)]) + MongoClient().test.test_collection.insert_many([{"_id": i} for i in range(4)]) from tornado import ioloop @@ -1604,13 +1608,12 @@ class AgnosticBaseCursor(AgnosticBase): >>> collection = MotorClient().test.test_collection >>> >>> async def f(): - ... cursor = collection.find().sort([('_id', 1)]) + ... cursor = collection.find().sort([("_id", 1)]) ... docs = await cursor.to_list(length=2) ... while docs: ... print(docs) ... docs = await cursor.to_list(length=2) - ... - ... print('done') + ... print("done") ... >>> ioloop.IOLoop.current().run_sync(f) [{'_id': 0}, {'_id': 1}] diff --git a/motor/docstrings.py b/motor/docstrings.py index 4b2a4f98..54f50746 100644 --- a/motor/docstrings.py +++ b/motor/docstrings.py @@ -111,7 +111,7 @@ For example, to list all non-system collections:: - `comment` (optional): A user-provided comment to attach to this command. - `**kwargs` (optional): Optional parameters of the `listCollections - `_ comand. + `_ command. can be passed as keyword arguments to this method. The supported options differ by server version. @@ -1140,17 +1140,17 @@ Pass a field name and a direction, either .. testsetup:: sort MongoClient().test.test_collection.drop() - MongoClient().test.test_collection.insert_many([ - {'_id': i, 'field1': i % 2, 'field2': i} - for i in range(5)]) + MongoClient().test.test_collection.insert_many( + [{"_id": i, "field1": i % 2, "field2": i} for i in range(5)] + ) collection = MotorClient().test.test_collection .. doctest:: sort >>> async def f(): - ... cursor = collection.find().sort('_id', pymongo.DESCENDING) + ... cursor = collection.find().sort("_id", pymongo.DESCENDING) ... docs = await cursor.to_list(None) - ... print([d['_id'] for d in docs]) + ... print([d["_id"] for d in docs]) ... >>> IOLoop.current().run_sync(f) [4, 3, 2, 1, 0] @@ -1160,12 +1160,11 @@ To sort by multiple fields, pass a list of (key, direction) pairs: .. doctest:: sort >>> async def f(): - ... cursor = collection.find().sort([ - ... ('field1', pymongo.ASCENDING), - ... ('field2', pymongo.DESCENDING)]) - ... + ... cursor = collection.find().sort( + ... [("field1", pymongo.ASCENDING), ("field2", pymongo.DESCENDING)] + ... ) ... docs = await cursor.to_list(None) - ... print([(d['field1'], d['field2']) for d in docs]) + ... print([(d["field1"], d["field2"]) for d in docs]) ... >>> IOLoop.current().run_sync(f) [(0, 4), (0, 2), (0, 0), (1, 3), (1, 1)] @@ -1175,24 +1174,23 @@ Text search results can be sorted by relevance: .. testsetup:: sort_text MongoClient().test.test_collection.drop() - MongoClient().test.test_collection.insert_many([ - {'field': 'words'}, - {'field': 'words about some words'}]) + MongoClient().test.test_collection.insert_many( + [{"field": "words"}, {"field": "words about some words"}] + ) - MongoClient().test.test_collection.create_index([('field', 'text')]) + MongoClient().test.test_collection.create_index([("field", "text")]) collection = MotorClient().test.test_collection .. doctest:: sort_text >>> async def f(): - ... cursor = collection.find({ - ... '$text': {'$search': 'some words'}}, - ... {'score': {'$meta': 'textScore'}}) - ... + ... cursor = collection.find( + ... {"$text": {"$search": "some words"}}, {"score": {"$meta": "textScore"}} + ... ) ... # Sort by 'score' field. - ... cursor.sort([('score', {'$meta': 'textScore'})]) + ... cursor.sort([("score", {"$meta": "textScore"})]) ... async for doc in cursor: - ... print('%.1f %s' % (doc['score'], doc['field'])) + ... print("%.1f %s" % (doc["score"], doc["field"])) ... >>> IOLoop.current().run_sync(f) 1.5 words about some words @@ -1230,11 +1228,10 @@ to initialize it, or an ``async with`` statement. # Or, use an "async with" statement to end the session # automatically. async with await client.start_session() as s: - doc = {'_id': ObjectId(), 'x': 1} + doc = {"_id": ObjectId(), "x": 1} await collection.insert_one(doc, session=s) - secondary = collection.with_options( - read_preference=ReadPreference.SECONDARY) + secondary = collection.with_options(read_preference=ReadPreference.SECONDARY) # Sessions are causally consistent by default, so we can read # the doc we just inserted, even reading from a secondary. @@ -1245,8 +1242,8 @@ to initialize it, or an ``async with`` statement. async with await client.start_session() as s: # Note, start_transaction doesn't require "await". async with s.start_transaction(): - await collection.delete_one({'x': 1}, session=s) - await collection.insert_one({'x': 2}, session=s) + await collection.delete_one({"x": 1}, session=s) + await collection.insert_one({"x": 2}, session=s) # Exiting the "with s.start_transaction()" block while throwing an # exception automatically aborts the transaction, exiting the block @@ -1255,10 +1252,10 @@ to initialize it, or an ``async with`` statement. # You can run additional transactions in the same session, so long as # you run them one at a time. async with s.start_transaction(): - await collection.insert_one({'x': 3}, session=s) - await collection.insert_many({'x': {'$gte': 2}}, - {'$inc': {'x': 1}}, - session=s) + await collection.insert_one({"x": 3}, session=s) + await collection.insert_many( + {"x": {"$gte": 2}}, {"$inc": {"x": 1}}, session=s + ) Requires MongoDB 3.6. diff --git a/motor/motor_gridfs.py b/motor/motor_gridfs.py index 8131bff5..e810012c 100644 --- a/motor/motor_gridfs.py +++ b/motor/motor_gridfs.py @@ -179,7 +179,7 @@ class AgnosticGridOut: @tornado.web.asynchronous @gen.coroutine def get(self, filename): - db = self.settings['db'] + db = self.settings["db"] fs = await motor.MotorGridFSBucket(db()) try: gridout = await fs.open_download_stream_by_name(filename) diff --git a/motor/motor_gridfs.pyi b/motor/motor_gridfs.pyi index ad7306ba..ccd2469f 100644 --- a/motor/motor_gridfs.pyi +++ b/motor/motor_gridfs.pyi @@ -105,7 +105,7 @@ class AgnosticGridIn: root_collection: AgnosticCollection, delegate: Any = None, session: Optional[AgnosticClientSession] = None, - **kwargs: Any + **kwargs: Any, ) -> None: ... async def __aenter__(self) -> AgnosticGridIn: ... async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None: ... diff --git a/motor/web.py b/motor/web.py index d376825c..3626e8cb 100644 --- a/motor/web.py +++ b/motor/web.py @@ -40,9 +40,11 @@ class GridFSHandler(tornado.web.RequestHandler): .. code-block:: python db = motor.MotorClient().my_database - application = web.Application([ - (r"/static/(.*)", web.GridFSHandler, {"database": db}), - ]) + application = web.Application( + [ + (r"/static/(.*)", web.GridFSHandler, {"database": db}), + ] + ) By default, requests' If-Modified-Since headers are honored, but no specific cache-control timeout is sent to clients. Thus each request for diff --git a/pyproject.toml b/pyproject.toml index 543fceae..6a52d3ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,6 +85,8 @@ include = ["motor"] [tool.ruff] target-version = "py37" line-length = 100 + +[tool.ruff.lint] select = [ "E", "F", "W", # flake8 "B", # flake8-bugbear @@ -93,7 +95,6 @@ select = [ "C4", # flake8-comprehensions "EM", # flake8-errmsg "ICN", # flake8-import-conventions - "ISC", # flake8-implicit-str-concat "G", # flake8-logging-format "PGH", # pygrep-hooks "PIE", # flake8-pie @@ -108,7 +109,7 @@ select = [ "YTT", # flake8-2020 "EXE", # flake8-executable ] -extend-ignore = [ +ignore = [ "ARG001", # Unused function argument "UP007", # Use `X | Y` for type annotation "EM101", # Exception must not use a string literal, assign to variable first @@ -131,7 +132,7 @@ exclude = [] flake8-unused-arguments.ignore-variadic-names = true dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?)|dummy.*)$" -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "test/*.py" = ["PT009", "ARG", "E402", "PT027", "UP031", "B904", "C405", "SIM", "PLR", "PTH", "B018", "C4", "S", "E501", "T201", "E731", "F841", "F811", diff --git a/synchro/__init__.py b/synchro/__init__.py index 12fecb32..58d41796 100644 --- a/synchro/__init__.py +++ b/synchro/__init__.py @@ -460,9 +460,9 @@ class Database(Synchro): if self.delegate is None: self.delegate = motor.MotorDatabase(client.delegate, name, **kwargs) - assert isinstance( - self.delegate, motor.MotorDatabase - ), "synchro.Database delegate must be MotorDatabase, not %s" % repr(self.delegate) + assert isinstance(self.delegate, motor.MotorDatabase), ( + "synchro.Database delegate must be MotorDatabase, not %s" % repr(self.delegate) + ) @property def client(self): diff --git a/synchro/synchrotest.py b/synchro/synchrotest.py index e8772d5a..907839f1 100644 --- a/synchro/synchrotest.py +++ b/synchro/synchrotest.py @@ -198,7 +198,7 @@ excluded_tests = [ excluded_modules_matched = set() excluded_tests_matched = set() -# Valide the exclude lists. +# Validate the exclude lists. for item in excluded_modules: if not re.match(r"^test\.[a-zA-Z_]+$", item): raise ValueError(f"Improper excluded module {item}") diff --git a/test/asyncio_tests/__init__.py b/test/asyncio_tests/__init__.py index 54e23c53..62ab8a75 100644 --- a/test/asyncio_tests/__init__.py +++ b/test/asyncio_tests/__init__.py @@ -112,7 +112,7 @@ class AsyncIOTestCase(AssertLogsMixin, unittest.TestCase): return motor_asyncio.AsyncIOMotorClient( kwargs.pop("host", None) or uri or env.uri, *args, - **self.get_client_kwargs(**kwargs, set_loop=set_loop) + **self.get_client_kwargs(**kwargs, set_loop=set_loop), ) def asyncio_rsc(self, uri=None, *args, **kwargs): diff --git a/test/asyncio_tests/test_examples.py b/test/asyncio_tests/test_examples.py index 922bf3ea..5a8a3eb8 100644 --- a/test/asyncio_tests/test_examples.py +++ b/test/asyncio_tests/test_examples.py @@ -1414,7 +1414,6 @@ LOCAL_MASTER_KEY = base64.b64decode( class TestQueryableEncryptionDocsExample(AsyncIOTestCase): - # Queryable Encryption is not supported on Standalone topology. @env.require_version_min(7, 0, -1) diff --git a/test/tornado_tests/__init__.py b/test/tornado_tests/__init__.py index ac09397b..89e9c1dd 100644 --- a/test/tornado_tests/__init__.py +++ b/test/tornado_tests/__init__.py @@ -116,7 +116,6 @@ class MotorReplicaSetTestBase(MotorTest): class MotorMockServerTest(MotorTest): - executor = concurrent.futures.ThreadPoolExecutor(1) def server(self, *args, **kwargs):