From: Mike Bayer Date: Wed, 26 May 2021 17:46:36 +0000 (-0400) Subject: get tests to pass on python 3.10 X-Git-Tag: rel_1_4_16~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ff1d989c1433c96ac1a50c3662e77ec1025c57cb;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git get tests to pass on python 3.10 Resolved various deprecation warnings which were appearing as of Python version 3.10.0b1. block aiomysql on python 3.10 as they are using the "loop" argument that's removed sqlcipher-binary has no builds on 3.10, block it for 3.10 Fixes: #6540 Fixes: #6543 Change-Id: Iec1e3881fb289878881ae043b1a18c3ecdf5f077 --- diff --git a/doc/build/changelog/unreleased_14/py310.rst b/doc/build/changelog/unreleased_14/py310.rst new file mode 100644 index 0000000000..5ade161c31 --- /dev/null +++ b/doc/build/changelog/unreleased_14/py310.rst @@ -0,0 +1,6 @@ +.. change:: + :tags: bug, general + :tickets: 6540, 6543 + + Resolved various deprecation warnings which were appearing as of Python + version 3.10.0b1. diff --git a/lib/sqlalchemy/testing/warnings.py b/lib/sqlalchemy/testing/warnings.py index 3236ecf893..89ee861cb5 100644 --- a/lib/sqlalchemy/testing/warnings.py +++ b/lib/sqlalchemy/testing/warnings.py @@ -25,10 +25,19 @@ def setup_filters(): # some selected deprecations... warnings.filterwarnings("error", category=DeprecationWarning) warnings.filterwarnings( - "ignore", category=DeprecationWarning, message=".*StopIteration" + "ignore", category=DeprecationWarning, message=r".*StopIteration" ) warnings.filterwarnings( - "ignore", category=DeprecationWarning, message=".*inspect.get.*argspec" + "ignore", + category=DeprecationWarning, + message=r".*inspect.get.*argspec", + ) + + # used by pytest-xdist + warnings.filterwarnings( + "ignore", + category=DeprecationWarning, + message=r".*isSet\(\) is deprecated, use is_set\(\).*", ) warnings.filterwarnings( "ignore", diff --git a/lib/sqlalchemy/util/_concurrency_py3k.py b/lib/sqlalchemy/util/_concurrency_py3k.py index 5f03972b2a..3b60e6584a 100644 --- a/lib/sqlalchemy/util/_concurrency_py3k.py +++ b/lib/sqlalchemy/util/_concurrency_py3k.py @@ -74,7 +74,7 @@ def await_fallback(awaitable: Coroutine) -> Any: # this is called in the context greenlet while running fn current = greenlet.getcurrent() if not isinstance(current, _AsyncIoGreenlet): - loop = asyncio.get_event_loop() + loop = get_event_loop() if loop.is_running(): raise exc.MissingGreenlet( "greenlet_spawn has not been called and asyncio event " @@ -152,7 +152,7 @@ class AsyncAdaptedLock: def _util_async_run_coroutine_function(fn, *args, **kwargs): """for test suite/ util only""" - loop = asyncio.get_event_loop() + loop = get_event_loop() if loop.is_running(): raise Exception( "for async run coroutine we expect that no greenlet or event " @@ -164,10 +164,25 @@ def _util_async_run_coroutine_function(fn, *args, **kwargs): def _util_async_run(fn, *args, **kwargs): """for test suite/ util only""" - loop = asyncio.get_event_loop() + loop = get_event_loop() if not loop.is_running(): return loop.run_until_complete(greenlet_spawn(fn, *args, **kwargs)) else: # allow for a wrapped test function to call another assert isinstance(greenlet.getcurrent(), _AsyncIoGreenlet) return fn(*args, **kwargs) + + +def get_event_loop(): + """vendor asyncio.get_event_loop() for python 3.7 and above. + + Python 3.10 deprecates get_event_loop() as a standalone. + + """ + if compat.py37: + try: + return asyncio.get_running_loop() + except RuntimeError: + return asyncio.get_event_loop_policy().get_event_loop() + else: + return asyncio.get_event_loop() diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index 727b77f7e7..620d059c3e 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -14,7 +14,7 @@ import operator import platform import sys - +py310 = sys.version_info >= (3, 10) py38 = sys.version_info >= (3, 8) py37 = sys.version_info >= (3, 7) py3k = sys.version_info >= (3, 0) @@ -111,20 +111,16 @@ def inspect_getfullargspec(func): if py38: from importlib import metadata as importlib_metadata - - def importlib_metadata_get(group): - return importlib_metadata.entry_points().get(group, ()) - - else: import importlib_metadata # noqa - def importlib_metadata_get(group): - ep = importlib_metadata.entry_points() - if hasattr(ep, "select"): - return ep.select(group=group) - else: - return ep.get(group, ()) + +def importlib_metadata_get(group): + ep = importlib_metadata.entry_points() + if hasattr(ep, "select"): + return ep.select(group=group) + else: + return ep.get(group, ()) if py3k: diff --git a/test/base/test_concurrency_py3k.py b/test/base/test_concurrency_py3k.py index 08c18b43e3..9eba6b82f8 100644 --- a/test/base/test_concurrency_py3k.py +++ b/test/base/test_concurrency_py3k.py @@ -11,6 +11,7 @@ from sqlalchemy.testing import is_true from sqlalchemy.util import asyncio from sqlalchemy.util import await_fallback from sqlalchemy.util import await_only +from sqlalchemy.util import compat from sqlalchemy.util import greenlet_spawn from sqlalchemy.util import queue @@ -192,10 +193,15 @@ class TestAsyncAdaptedQueue(fixtures.TestBase): eq_(q.get(block=False), 1) q.get(timeout=0.1) - with expect_raises_message( - RuntimeError, "Task .* attached to a different loop" - ): - asyncio.run(greenlet_spawn(go)) + if compat.py310: + # TODO: I don't really know what this means in 3.10 + with expect_raises(queue.Empty): + asyncio.run(greenlet_spawn(go)) + else: + with expect_raises_message( + RuntimeError, "Task .* attached to a different loop" + ): + asyncio.run(greenlet_spawn(go)) run[0] = True diff --git a/tox.ini b/tox.ini index 625b007289..6c77ab95c8 100644 --- a/tox.ini +++ b/tox.ini @@ -25,7 +25,7 @@ deps= sqlite: .[aiosqlite] sqlite_file: .[aiosqlite] - sqlite_file: .[sqlcipher]; python_version >= '3' + sqlite_file: .[sqlcipher]; python_version >= '3' and python_version < '3.10' postgresql: .[postgresql] postgresql: .[postgresql_asyncpg]; python_version >= '3' postgresql: .[postgresql_pg8000]; python_version >= '3' @@ -92,7 +92,9 @@ setenv= sqlite: SQLITE={env:TOX_SQLITE:--db sqlite} sqlite_file: SQLITE={env:TOX_SQLITE_FILE:--db sqlite_file} py3{,5,6,7,8,9,10,11}-sqlite: EXTRA_SQLITE_DRIVERS={env:EXTRA_SQLITE_DRIVERS:--dbdriver sqlite --dbdriver aiosqlite} - py3{,5,6,7,8,9,10,11}-sqlite_file: EXTRA_SQLITE_DRIVERS={env:EXTRA_SQLITE_DRIVERS:--dbdriver sqlite --dbdriver aiosqlite --dbdriver pysqlcipher} + py3{,5,6,7,8,9}-sqlite_file: EXTRA_SQLITE_DRIVERS={env:EXTRA_SQLITE_DRIVERS:--dbdriver sqlite --dbdriver aiosqlite --dbdriver pysqlcipher} + # omit pysqlcipher for Python 3.10 + py3{,10,11}-sqlite_file: EXTRA_SQLITE_DRIVERS={env:EXTRA_SQLITE_DRIVERS:--dbdriver sqlite --dbdriver aiosqlite} postgresql: POSTGRESQL={env:TOX_POSTGRESQL:--db postgresql} py2{,7}-postgresql: POSTGRESQL={env:TOX_POSTGRESQL_PY2K:{env:TOX_POSTGRESQL:--db postgresql}} @@ -101,7 +103,10 @@ setenv= mysql: MYSQL={env:TOX_MYSQL:--db mysql} py2{,7}-mysql: MYSQL={env:TOX_MYSQL_PY2K:{env:TOX_MYSQL:--db mysql}} mysql: EXTRA_MYSQL_DRIVERS={env:EXTRA_MYSQL_DRIVERS:--dbdriver mysqldb --dbdriver pymysql} - py3{,5,6,7,8,9,10,11}-mysql: EXTRA_MYSQL_DRIVERS={env:EXTRA_MYSQL_DRIVERS:--dbdriver mysqldb --dbdriver pymysql --dbdriver mariadbconnector --dbdriver aiomysql} + + py3{,5,6,7,8,9}-mysql: EXTRA_MYSQL_DRIVERS={env:EXTRA_MYSQL_DRIVERS:--dbdriver mysqldb --dbdriver pymysql --dbdriver mariadbconnector --dbdriver aiomysql} + # omit aiomysql for Python 3.10 + py3{,10,11}-mysql: EXTRA_MYSQL_DRIVERS={env:EXTRA_MYSQL_DRIVERS:--dbdriver mysqldb --dbdriver pymysql --dbdriver mariadbconnector} mssql: MSSQL={env:TOX_MSSQL:--db mssql}