Skip to content

Commit

Permalink
MOTOR-902 Since Python 3.10 asyncio.get_event_loop() is deprecated (#155
Browse files Browse the repository at this point in the history
)
  • Loading branch information
blink1073 committed Apr 21, 2022
1 parent c16a62d commit 0c562e9
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test-python.yml
Expand Up @@ -39,7 +39,7 @@ jobs:
mongod --fork --dbpath=$(pwd)/data --logpath=$PWD/mongo.log --setParameter enableTestCommands=1
- name: Install Python dependencies
run: |
python -m pip install -U pip tox tox-gh-actions
python -m pip install -U pip tox tox-gh-actions setuptools
- name: Run tests
run: |
tox
Expand Down
3 changes: 1 addition & 2 deletions doc/examples/aiohttp_example.py
Expand Up @@ -41,8 +41,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.
Expand Down
2 changes: 1 addition & 1 deletion doc/examples/aiohttp_gridfs_example.py
Expand Up @@ -33,7 +33,7 @@ async def put_gridfile():
)


asyncio.get_event_loop().run_until_complete(put_gridfile())
asyncio.run(put_gridfile())


# Add "Content-Encoding: gzip" header for compressed data.
Expand Down
3 changes: 1 addition & 2 deletions doc/examples/auto_csfle_example.py
Expand Up @@ -98,5 +98,4 @@ async def main():


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


if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
asyncio.run(main())
3 changes: 1 addition & 2 deletions doc/examples/explicit_encryption_example.py
Expand Up @@ -65,5 +65,4 @@ async def main():


if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
asyncio.run(main())
3 changes: 1 addition & 2 deletions doc/examples/server_fle_enforcement_example.py
Expand Up @@ -97,5 +97,4 @@ async def main():


if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
asyncio.run(main())
28 changes: 15 additions & 13 deletions doc/tutorial-asyncio.rst
Expand Up @@ -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)])

Expand Down Expand Up @@ -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('...')

Expand All @@ -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

Expand All @@ -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}

Expand Down Expand Up @@ -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}
Expand All @@ -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}
Expand All @@ -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}
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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'}
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
41 changes: 22 additions & 19 deletions motor/core.py
Expand Up @@ -137,7 +137,8 @@ def __init__(self, *args, **kwargs):
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(
Expand All @@ -146,7 +147,12 @@ def __init__(self, *args, **kwargs):

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
Expand Down Expand Up @@ -1069,22 +1075,13 @@ def main():
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
Expand Down Expand Up @@ -1946,13 +1943,19 @@ def __init__(
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
Expand Down
6 changes: 5 additions & 1 deletion motor/frameworks/asyncio/__init__.py
Expand Up @@ -37,7 +37,11 @@


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):
Expand Down
12 changes: 9 additions & 3 deletions setup.py
@@ -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

Expand Down Expand Up @@ -69,7 +75,7 @@ def finalize_options(self):
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
Expand Down
2 changes: 2 additions & 0 deletions tox.ini
Expand Up @@ -70,6 +70,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}
Expand Down

0 comments on commit 0c562e9

Please sign in to comment.