From 29a42651d8577a33ca5567c45df66ccf879e4d7c Mon Sep 17 00:00:00 2001 From: Tin Tvrtkovic Date: Thu, 22 Apr 2021 01:06:33 +0200 Subject: [PATCH 01/11] Bump to 0.16.0 --- README.rst | 3 +++ pytest_asyncio/__init__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 2650c2fb..3b62d7eb 100644 --- a/README.rst +++ b/README.rst @@ -164,6 +164,9 @@ Only test coroutines will be affected (by default, coroutines prefixed by Changelog --------- +0.16.0 (UNRELEASED) +~~~~~~~~~~~~~~~~~~~ + 0.15.1 (2021-04-22) ~~~~~~~~~~~~~~~~~~~ - Hotfix for errors while closing event loops while replacing them. diff --git a/pytest_asyncio/__init__.py b/pytest_asyncio/__init__.py index c802163a..fddaf22f 100644 --- a/pytest_asyncio/__init__.py +++ b/pytest_asyncio/__init__.py @@ -1,2 +1,2 @@ """The main point for importing pytest-asyncio items.""" -__version__ = "0.15.1" +__version__ = "0.16.0dev0" From e3ec312c1d55b3688e4ce115df7791a0478582d1 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Mon, 17 May 2021 16:08:54 +0200 Subject: [PATCH 02/11] Adjusted Hypothesis integration test to use the same event loop initialization as in the plugin. The plugin code creates a new event loop from the current event loop policy, whereas the fixture in the Hypothesis test uses get_event_loop. In Python 3.10 the use of get_event_loop was deprecated and causes the Hypothesis tests to fail. Signed-off-by: Michael Seifert --- tests/test_hypothesis_integration.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_hypothesis_integration.py b/tests/test_hypothesis_integration.py index 9c97e06c..39cb6075 100644 --- a/tests/test_hypothesis_integration.py +++ b/tests/test_hypothesis_integration.py @@ -10,8 +10,9 @@ @pytest.fixture(scope="module") def event_loop(): - loop = asyncio.get_event_loop() + loop = asyncio.get_event_loop_policy().new_event_loop() yield loop + loop.close() @given(st.integers()) From b27abe8d138998a75cc4eb519be810439d3ed0d9 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Mon, 17 May 2021 16:54:11 +0200 Subject: [PATCH 03/11] refactor: Removed TestUnexistingLoop.remove_loop fixture, because it has no effect. Under Python 3.10, the remove_loop fixture raises: "DeprecationWarning: There is no current event loop" This means that the remove_loop fixture effectively does nothing. The test case is still kept, because it seemingly aims to test that the "asyncio" marker works inside test classes when no "event_loop" fixture is explicitly specified. Signed-off-by: Michael Seifert --- tests/test_simple.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/test_simple.py b/tests/test_simple.py index b5b57ed5..27a8184a 100644 --- a/tests/test_simple.py +++ b/tests/test_simple.py @@ -110,15 +110,8 @@ async def test_asyncio_marker_method(self, event_loop): class TestUnexistingLoop: - @pytest.fixture - def remove_loop(self): - old_loop = asyncio.get_event_loop() - asyncio.set_event_loop(None) - yield - asyncio.set_event_loop(old_loop) - @pytest.mark.asyncio - async def test_asyncio_marker_without_loop(self, remove_loop): + async def test_asyncio_marker_without_loop(self): """Test the asyncio pytest marker in a Test class.""" ret = await async_coro() assert ret == "ok" From 70989fd7b626a86db4f75acc40057f982f2c76dd Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Mon, 17 May 2021 17:00:26 +0200 Subject: [PATCH 04/11] refactor: Grouped test cases together that are related to the use of the asyncio marker in class-based tests. Rephrased test names and comments to make the test intention more clear. Signed-off-by: Michael Seifert --- tests/test_simple.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/test_simple.py b/tests/test_simple.py index 27a8184a..854faaf3 100644 --- a/tests/test_simple.py +++ b/tests/test_simple.py @@ -99,20 +99,18 @@ def mock_unused_tcp_port(): assert unused_tcp_port_factory() > 10000 -class Test: - """Test that asyncio marked functions work in test methods.""" +class TestMarkerInClassBasedTests: + """Test that asyncio marked functions work for methods of test classes.""" @pytest.mark.asyncio - async def test_asyncio_marker_method(self, event_loop): - """Test the asyncio pytest marker in a Test class.""" + async def test_asyncio_marker_with_explicit_loop_fixture(self, event_loop): + """Test the "asyncio" marker works on a method in a class-based test with explicit loop fixture.""" ret = await async_coro() assert ret == "ok" - -class TestUnexistingLoop: @pytest.mark.asyncio - async def test_asyncio_marker_without_loop(self): - """Test the asyncio pytest marker in a Test class.""" + async def test_asyncio_marker_with_implicit_loop_fixture(self): + """Test the "asyncio" marker works on a method in a class-based test with implicit loop fixture.""" ret = await async_coro() assert ret == "ok" From 2751982f3a84d55aad103ea039cc779537e90720 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Mon, 17 May 2021 19:43:53 +0200 Subject: [PATCH 05/11] refactor: Replaced tests asserting that the event loop is properly closed. Under Python 3.10, the tests raise: "DeprecationWarning: There is no current event loop" This means that the asyncio.get_event_loop does not return any existing loop. It creates a new loop as a side effect instead. Therefore, test_1 and test_3 will always be successful. However, it would be wrong to simply delete the tests without a replacement. Although, we cannot retrieve the default loop with get_event_loop, we can still retrieve it from the event loop policy. The new tests do exactly that and assert that the loop is a different object than in the tests before. Signed-off-by: Michael Seifert --- tests/test_event_loop_scope.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/test_event_loop_scope.py b/tests/test_event_loop_scope.py index ccfeffe6..8ae4eb1e 100644 --- a/tests/test_event_loop_scope.py +++ b/tests/test_event_loop_scope.py @@ -1,4 +1,4 @@ -"""Test the event loop fixture is properly disposed of. +"""Test the event loop fixture provides a separate loop for each test. These tests need to be run together. """ @@ -6,17 +6,26 @@ import pytest +loop: asyncio.AbstractEventLoop + def test_1(): - loop = asyncio.get_event_loop() - assert not loop.is_closed() + global loop + # The main thread should have a default event loop. + loop = asyncio.get_event_loop_policy().get_event_loop() @pytest.mark.asyncio async def test_2(): - pass + global loop + running_loop = asyncio.get_event_loop_policy().get_event_loop() + # Make sure this test case received a different loop + assert running_loop is not loop + loop = running_loop # Store the loop reference for later def test_3(): - loop = asyncio.get_event_loop() - assert not loop.is_closed() + global loop + current_loop = asyncio.get_event_loop_policy().get_event_loop() + # Now the event loop from test_2 should have been cleaned up + assert loop is not current_loop From 1c283bd821249ee3c695ae59bb022d31a1473ae2 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Fri, 21 May 2021 08:15:03 +0200 Subject: [PATCH 06/11] refactor: test_async_fixtures_with_finalizer no longer trigger a DeprecationWarning on Python 3.10. The code was adjusted to use asyncio.get_event_loop_policy().get_event_loop() rather than the deprecated asyncio.get_event_loop(). Some additional comments were added to clarify the circumstances under which the test can fail. Signed-off-by: Michael Seifert --- .../async_fixtures/test_async_fixtures_with_finalizer.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/async_fixtures/test_async_fixtures_with_finalizer.py b/tests/async_fixtures/test_async_fixtures_with_finalizer.py index c602d908..c90a0124 100644 --- a/tests/async_fixtures/test_async_fixtures_with_finalizer.py +++ b/tests/async_fixtures/test_async_fixtures_with_finalizer.py @@ -44,11 +44,14 @@ async def port_afinalizer(): async def port_with_get_event_loop_finalizer(request, event_loop): def port_finalizer(finalizer): async def port_afinalizer(): - # await task using loop provided by asyncio.get_event_loop() - # RuntimeError is raised if task is created on a different loop + # await task using current loop retrieved from the event loop policy + # RuntimeError is raised if task is created on a different loop. + # This can happen when pytest_fixture_setup does not set up the loop correctly, + # for example when policy.set_event_loop() is called with a wrong argument await finalizer - asyncio.get_event_loop().run_until_complete(port_afinalizer()) + current_loop = asyncio.get_event_loop_policy().get_event_loop() + current_loop.run_until_complete(port_afinalizer()) worker = asyncio.ensure_future(asyncio.sleep(0.2)) request.addfinalizer(functools.partial(port_finalizer, worker)) From be3b32777b32774c288b604f0d95eacb32a4d1a2 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Fri, 21 May 2021 08:16:19 +0200 Subject: [PATCH 07/11] build: Include Python 3.10 in Tox test runs. Signed-off-by: Michael Seifert --- tox.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 72cfafc2..ef60cba0 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] minversion = 3.14.0 -envlist = py36, py37, py38, py39, lint +envlist = py36, py37, py38, py39, py310, lint skip_missing_interpreters = true [testenv] @@ -30,4 +30,5 @@ python = 3.7: py37 3.8: py38 3.9: py39, lint + 3.10: py310 pypy3: pypy3 From 42ff5d176b2be5aa77a43f586179d563ae2196b5 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Fri, 21 May 2021 08:18:28 +0200 Subject: [PATCH 08/11] ci: Include Python 3.10 in the CI test run. Signed-off-by: Michael Seifert --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3d93214d..3b249ffb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,11 +13,11 @@ jobs: name: "Python ${{ matrix.python-version }}" runs-on: "ubuntu-latest" env: - USING_COVERAGE: "3.6,3.7,3.8,3.9" + USING_COVERAGE: "3.6,3.7,3.8,3.9,3.10" strategy: matrix: - python-version: ["3.6", "3.7", "3.8", "3.9"] + python-version: ["3.6", "3.7", "3.8", "3.9", "3.10-dev"] steps: - uses: "actions/checkout@v2" From 6ec76477061ea14394cadbf2cef673b04971ef4d Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Fri, 21 May 2021 08:21:13 +0200 Subject: [PATCH 09/11] feat: Add support for Python 3.10. Adjusted changelog and setup.py accordingly. Signed-off-by: Michael Seifert --- README.rst | 1 + setup.py | 1 + 2 files changed, 2 insertions(+) diff --git a/README.rst b/README.rst index 3b62d7eb..02e7b634 100644 --- a/README.rst +++ b/README.rst @@ -166,6 +166,7 @@ Changelog --------- 0.16.0 (UNRELEASED) ~~~~~~~~~~~~~~~~~~~ +- Add support for Python 3.10 0.15.1 (2021-04-22) ~~~~~~~~~~~~~~~~~~~ diff --git a/setup.py b/setup.py index 2df6faee..e15080fe 100644 --- a/setup.py +++ b/setup.py @@ -37,6 +37,7 @@ def find_version(): "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", "Topic :: Software Development :: Testing", "Framework :: Pytest", ], From 4e1df3191aee1a902c873901b35d82363e13b08c Mon Sep 17 00:00:00 2001 From: Tin Tvrtkovic Date: Sat, 16 Oct 2021 01:26:56 +0200 Subject: [PATCH 10/11] Remove obsolete test, add make test --- Makefile | 5 +++- .../async_fixtures/test_coroutine_fixtures.py | 29 ------------------- 2 files changed, 4 insertions(+), 30 deletions(-) delete mode 100644 tests/async_fixtures/test_coroutine_fixtures.py diff --git a/Makefile b/Makefile index 425015de..8cf88841 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: clean clean-build clean-pyc clean-test lint +.PHONY: clean clean-build clean-pyc clean-test lint test clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts @@ -23,3 +23,6 @@ clean-test: ## remove test and coverage artifacts lint: ## check style with flake8 flake8 pytest_asyncio tests black --check --verbose pytest_asyncio tests + +test: + pytest tests diff --git a/tests/async_fixtures/test_coroutine_fixtures.py b/tests/async_fixtures/test_coroutine_fixtures.py deleted file mode 100644 index 65dabab5..00000000 --- a/tests/async_fixtures/test_coroutine_fixtures.py +++ /dev/null @@ -1,29 +0,0 @@ -import asyncio -import unittest.mock - -import pytest - -START = object() -END = object() -RETVAL = object() - -pytestmark = pytest.mark.skip( - reason="@asyncio.coroutine fixtures are not supported yet" -) - - -@pytest.fixture -def mock(): - return unittest.mock.Mock(return_value=RETVAL) - - -@pytest.fixture -async def coroutine_fixture(mock): - await asyncio.sleep(0.1, result=mock(START)) - - -@pytest.mark.asyncio -async def test_coroutine_fixture(coroutine_fixture, mock): - assert mock.call_count == 1 - assert mock.call_args_list[-1] == unittest.mock.call(START) - assert coroutine_fixture is RETVAL From f2fe98e5cbc4a25e31c24f5932d66f9c903f0fe5 Mon Sep 17 00:00:00 2001 From: Tin Tvrtkovic Date: Sat, 16 Oct 2021 01:28:39 +0200 Subject: [PATCH 11/11] 0.16.0 --- README.rst | 2 +- pytest_asyncio/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 02e7b634..7e6c975d 100644 --- a/README.rst +++ b/README.rst @@ -164,7 +164,7 @@ Only test coroutines will be affected (by default, coroutines prefixed by Changelog --------- -0.16.0 (UNRELEASED) +0.16.0 (2021-10-16) ~~~~~~~~~~~~~~~~~~~ - Add support for Python 3.10 diff --git a/pytest_asyncio/__init__.py b/pytest_asyncio/__init__.py index fddaf22f..b16159e7 100644 --- a/pytest_asyncio/__init__.py +++ b/pytest_asyncio/__init__.py @@ -1,2 +1,2 @@ """The main point for importing pytest-asyncio items.""" -__version__ = "0.16.0dev0" +__version__ = "0.16.0"