MOTOR-902 [v2.5] Since Python 3.10 asyncio.get_event_loop() is deprecated (#159)

This commit is contained in:
Steven Silvester 2022-04-21 12:50:37 -05:00 committed by GitHub
parent 88119c849c
commit 0cbd45f581
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 59 additions and 48 deletions

View File

@ -39,8 +39,7 @@ async def page_handler(request):
# -- handler-end --
# -- main-start --
loop = asyncio.get_event_loop()
db = loop.run_until_complete(setup_db())
db = asyncio.run(setup_db())
app = web.Application()
app['db'] = db
# Route requests to the page_handler() coroutine.

View File

@ -33,7 +33,7 @@ async def put_gridfile():
metadata={'contentType': 'text',
'compressed': True})
asyncio.get_event_loop().run_until_complete(put_gridfile())
asyncio.run(put_gridfile())
# Add "Content-Encoding: gzip" header for compressed data.

View File

@ -101,5 +101,4 @@ async def main():
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
asyncio.run(main())

View File

@ -70,5 +70,4 @@ async def main():
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
asyncio.run(main())

View File

@ -65,5 +65,4 @@ async def main():
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
asyncio.run(main())

View File

@ -98,5 +98,4 @@ async def main():
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
asyncio.run(main())

View File

@ -12,14 +12,16 @@ Tutorial: Using Motor With :mod:`asyncio`
import pymongo
import motor.motor_asyncio
import asyncio
db = motor.motor_asyncio.AsyncIOMotorClient().test_database
client = motor.motor_asyncio.AsyncIOMotorClient()
db = client.test_database
.. testsetup:: after-inserting-2000-docs
import pymongo
import motor.motor_asyncio
import asyncio
db = motor.motor_asyncio.AsyncIOMotorClient().test_database
client = motor.motor_asyncio.AsyncIOMotorClient()
db = client.test_database
pymongo.MongoClient().test_database.test_collection.insert_many(
[{'i': i} for i in range(2000)])
@ -144,7 +146,7 @@ store a document in MongoDB, call :meth:`~AsyncIOMotorCollection.insert_one` in
...
>>>
>>> import asyncio
>>> loop = asyncio.get_event_loop()
>>> loop = client.get_io_loop()
>>> loop.run_until_complete(do_insert())
result ObjectId('...')
@ -166,7 +168,7 @@ Insert documents in large batches with :meth:`~AsyncIOMotorCollection.insert_man
... [{'i': i} for i in range(2000)])
... print('inserted %d docs' % (len(result.inserted_ids),))
...
>>> loop = asyncio.get_event_loop()
>>> loop = client.get_io_loop()
>>> loop.run_until_complete(do_insert())
inserted 2000 docs
@ -183,7 +185,7 @@ less than 1:
... document = await db.test_collection.find_one({'i': {'$lt': 1}})
... pprint.pprint(document)
...
>>> loop = asyncio.get_event_loop()
>>> loop = client.get_io_loop()
>>> loop.run_until_complete(do_find_one())
{'_id': ObjectId('...'), 'i': 0}
@ -211,7 +213,7 @@ To find all documents with "i" less than 5:
... for document in await cursor.to_list(length=100):
... pprint.pprint(document)
...
>>> loop = asyncio.get_event_loop()
>>> loop = client.get_io_loop()
>>> loop.run_until_complete(do_find())
{'_id': ObjectId('...'), 'i': 0}
{'_id': ObjectId('...'), 'i': 1}
@ -234,7 +236,7 @@ You can handle one document at a time in an ``async for`` loop:
... async for document in c.find({'i': {'$lt': 2}}):
... pprint.pprint(document)
...
>>> loop = asyncio.get_event_loop()
>>> loop = client.get_io_loop()
>>> loop.run_until_complete(do_find())
{'_id': ObjectId('...'), 'i': 0}
{'_id': ObjectId('...'), 'i': 1}
@ -250,7 +252,7 @@ You can apply a sort, limit, or skip to a query before you begin iterating:
... async for document in cursor:
... pprint.pprint(document)
...
>>> loop = asyncio.get_event_loop()
>>> loop = client.get_io_loop()
>>> loop.run_until_complete(do_find())
{'_id': ObjectId('...'), 'i': 2}
{'_id': ObjectId('...'), 'i': 1}
@ -274,7 +276,7 @@ that match a query:
... n = await db.test_collection.count_documents({'i': {'$gt': 1000}})
... print('%s documents where i > 1000' % n)
...
>>> loop = asyncio.get_event_loop()
>>> loop = client.get_io_loop()
>>> loop.run_until_complete(do_count())
2000 documents in collection
999 documents where i > 1000
@ -299,7 +301,7 @@ replacement document. The query follows the same syntax as for :meth:`find` or
... new_document = await coll.find_one({'_id': _id})
... print('document is now %s' % pprint.pformat(new_document))
...
>>> loop = asyncio.get_event_loop()
>>> loop = client.get_io_loop()
>>> loop.run_until_complete(do_replace())
found document: {'_id': ObjectId('...'), 'i': 50}
replaced 1 document
@ -322,7 +324,7 @@ operator to set "key" to "value":
... new_document = await coll.find_one({'i': 51})
... print('document is now %s' % pprint.pformat(new_document))
...
>>> loop = asyncio.get_event_loop()
>>> loop = client.get_io_loop()
>>> loop.run_until_complete(do_update())
updated 1 document
document is now {'_id': ObjectId('...'), 'i': 51, 'key': 'value'}
@ -353,7 +355,7 @@ Deleting Documents
... result = await db.test_collection.delete_many({'i': {'$gte': 1000}})
... print('%s documents after' % (await coll.count_documents({})))
...
>>> loop = asyncio.get_event_loop()
>>> loop = client.get_io_loop()
>>> loop.run_until_complete(do_delete_many())
2000 documents before calling delete_many()
1000 documents after
@ -373,7 +375,7 @@ the :meth:`~motor.motor_asyncio.AsyncIOMotorDatabase.command` method on
... response = await db.command(SON([("distinct", "test_collection"),
... ("key", "i")]))
...
>>> loop = asyncio.get_event_loop()
>>> loop = client.get_io_loop()
>>> loop.run_until_complete(use_distinct_command())
Since the order of command parameters matters, don't use a Python dict to pass

View File

@ -149,7 +149,8 @@ class AgnosticClient(AgnosticBaseProperties):
io_loop = kwargs.pop('io_loop')
self._framework.check_event_loop(io_loop)
else:
io_loop = self._framework.get_event_loop()
io_loop = None
self._io_loop = io_loop
kwargs.setdefault('connect', False)
kwargs.setdefault(
@ -158,7 +159,12 @@ class AgnosticClient(AgnosticBaseProperties):
delegate = self.__delegate_class__(*args, **kwargs)
super().__init__(delegate)
self.io_loop = io_loop
@property
def io_loop(self):
if self._io_loop is None:
self._io_loop = self._framework.get_event_loop()
return self._io_loop
def get_io_loop(self):
return self.io_loop
@ -985,22 +991,13 @@ class AgnosticCollection(AgnosticBaseProperties):
change_stream.close()
# asyncio
from asyncio import get_event_loop
def main():
loop = get_event_loop()
task = loop.create_task(watch_collection)
try:
loop.run_forever()
except KeyboardInterrupt:
try:
asyncio.run(watch_collection)
except KeyboardInterrupt:
pass
finally:
if change_stream is not None:
change_stream.close()
# Prevent "Task was destroyed but it is pending!"
loop.run_until_complete(task)
finally:
if change_stream is not None:
change_stream.close()
The :class:`~MotorChangeStream` async iterable blocks
until the next change document is returned or an error is raised. If
@ -1835,11 +1832,17 @@ class AgnosticClientEncryption(AgnosticBase):
if io_loop:
self._framework.check_event_loop(io_loop)
else:
io_loop = self._framework.get_event_loop()
io_loop = None
sync_client = key_vault_client.delegate
delegate = self.__delegate_class__(kms_providers, key_vault_namespace, sync_client, codec_options)
super().__init__(delegate)
self.io_loop = io_loop
self._io_loop = io_loop
@property
def io_loop(self):
if self._io_loop is None:
self._io_loop = self._framework.get_event_loop()
return self._io_loop
def get_io_loop(self):
return self.io_loop

View File

@ -39,7 +39,11 @@ CLASS_PREFIX = 'AsyncIO'
def get_event_loop():
return asyncio.get_event_loop()
try:
return asyncio.get_running_loop()
except RuntimeError:
# Workaround for bugs.python.org/issue39529.
return asyncio.get_event_loop_policy().get_event_loop()
def is_event_loop(loop):

View File

@ -1,6 +1,12 @@
import sys
from distutils.cmd import Command
from distutils.errors import DistutilsOptionError
if sys.version_info[:2] < (3, 10):
from distutils.cmd import Command
from distutils.errors import DistutilsOptionError as OptionError
else:
from setuptools import Command
from setuptools.errors import OptionError
from setuptools import setup
if sys.version_info[:2] < (3, 5):
@ -71,8 +77,7 @@ class test(Command):
if self.test_suite is None and self.test_module is None:
self.test_module = 'test'
elif self.test_module is not None and self.test_suite is not None:
raise DistutilsOptionError(
"You may specify a module or suite, but not both")
raise OptionError("You may specify a module or suite, but not both")
def run(self):
# Installing required packages, running egg_info and build_ext are

View File

@ -67,6 +67,8 @@ deps =
synchro37: tornado>=6,<7
synchro37: nose
setenv =
PYTHONWARNINGS="error,ignore:The distutils package is deprecated:DeprecationWarning"
commands =
python --version
python setup.py test --xunit-output=xunit-results {posargs}