From db6dd29aabba2161cf9f9b94a884c283aa5b5c86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Dec 2022 16:12:19 +0100 Subject: [PATCH 01/47] Build(deps): Bump pypa/gh-action-pypi-publish from 1.5.2 to 1.6.4 (#459) Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.5.2 to 1.6.4. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.5.2...v1.6.4) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 80d181ef..d59349b1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -118,7 +118,7 @@ jobs: run: | pandoc -s -o README.md README.rst - name: PyPI upload - uses: pypa/gh-action-pypi-publish@v1.5.2 + uses: pypa/gh-action-pypi-publish@v1.6.4 with: packages_dir: dist password: ${{ secrets.PYPI_API_TOKEN }} From 3481bb41159c88cf873b98ffe2d0f43ffcf5e7e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Dec 2022 16:15:36 +0100 Subject: [PATCH 02/47] Build(deps): Bump hypothesis in /dependencies/default (#458) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.58.1 to 6.60.0. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.58.1...hypothesis-python-6.60.0) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index c89233f0..f3be85b0 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -3,7 +3,7 @@ attrs==22.1.0 coverage==6.5.0 exceptiongroup==1.0.4 flaky==3.7.0 -hypothesis==6.58.1 +hypothesis==6.60.0 idna==3.4 importlib-metadata==5.1.0 iniconfig==1.1.1 From 25d9592286682bc6dbfbf291028ff7a9594cf283 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Fri, 9 Dec 2022 12:46:39 +0100 Subject: [PATCH 03/47] [build]: Update Python 3.11 CI environment. (#462) Python 3.11 has been released. Using the 3.11-dev environment causes the CI build for this environment to be skipped. Signed-off-by: Michael Seifert Signed-off-by: Michael Seifert --- .github/workflows/main.yml | 2 +- tox.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d59349b1..ca541e43 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -55,7 +55,7 @@ jobs: strategy: matrix: - python-version: ['3.7', '3.8', '3.9', '3.10', 3.11-dev] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] steps: - uses: actions/checkout@v3 diff --git a/tox.ini b/tox.ini index 1d8994ae..c2d9789d 100644 --- a/tox.ini +++ b/tox.ini @@ -52,5 +52,5 @@ python = 3.8: py38 3.9: py39 3.10: py310 - 3.11-dev: py311 + 3.11: py311 pypy3: pypy3 From 7535466eae1bb9552f0b8f65e6a8a90d8a41e6e6 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Tue, 13 Dec 2022 07:13:41 +0100 Subject: [PATCH 04/47] Combine coverage data for all interpreter versions (#463) * [build] Removed unused tox environment "coverage-report". Coverage information is created as part of "make test". Signed-off-by: Michael Seifert * [build] Removed "--show-error-codes" option from mypy command. Showing error codes is the default behavior. It doesn't need to be enabled explicitly. Signed-off-by: Michael Seifert * [ci] Report combined coverage across all interpreter versions. Some codein pytest-asyncio is specific to certain versions of the Python interpreter. Therefore, the code coverage can be different for tests runs with different interpreters. Currently, the CI pipeline does not accommodate this fact. This commit changes coverage data to be generated by each CI environment during the test runs. The different coverage results are combined in the check step just before uploading them to codecov. Signed-off-by: Michael Seifert * [build] Exclude the auto generated "_version.py" from coverage measurements. Signed-off-by: Michael Seifert Signed-off-by: Michael Seifert --- .github/workflows/main.yml | 30 ++++++++++++++++++++++++++---- Makefile | 6 ++---- tox.ini | 7 ------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ca541e43..4132cdc6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -74,9 +74,12 @@ jobs: - name: Run tox targets for ${{ matrix.python-version }} run: python -m tox - - name: Prepare coverage artifact + - name: Store coverage data + uses: actions/upload-artifact@v3 + with: + name: coverage-per-interpreter + path: .coverage.* if: ${{ contains(env.USING_COVERAGE, matrix.python-version) }} - uses: aio-libs/prepare-coverage@v21.9.1 check: name: Check @@ -88,8 +91,27 @@ jobs: uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }} - - name: Upload coverage - uses: aio-libs/upload-coverage@v21.9.4 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: 3.11 + - name: Install Coverage.py + run: | + set -xe + python -m pip install --upgrade coverage[toml] + - name: Download coverage data for all test runs + uses: actions/download-artifact@v3 + with: + name: coverage-per-interpreter + - name: Combine coverage data and create report + run: | + coverage combine + coverage xml + - name: Upload coverage report + uses: codecov/codecov-action@v3 + with: + files: coverage.xml + fail_ci_if_error: true deploy: name: Deploy diff --git a/Makefile b/Makefile index 2b0216f9..c5d9fac1 100644 --- a/Makefile +++ b/Makefile @@ -27,12 +27,10 @@ ifdef CI else python -m pre_commit run --all-files endif - python -m mypy pytest_asyncio --show-error-codes + python -m mypy pytest_asyncio test: - coverage run -m pytest tests - coverage xml - coverage report + coverage run --parallel-mode --omit */_version.py -m pytest tests install: pip install -U pre-commit diff --git a/tox.ini b/tox.ini index c2d9789d..e705d9a6 100644 --- a/tox.ini +++ b/tox.ini @@ -33,13 +33,6 @@ commands = allowlist_externals = make -[testenv:coverage-report] -deps = coverage -skip_install = true -commands = - coverage combine - coverage report - [testenv:version-info] deps = packaging == 21.3 From 4b4dee491ef6ccffe5eabbd490c5664315d4a49a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Dec 2022 07:14:05 +0100 Subject: [PATCH 05/47] Build(deps): Bump packaging from 21.3 to 22.0 in /dependencies/default (#464) Bumps [packaging](https://github.com/pypa/packaging) from 21.3 to 22.0. - [Release notes](https://github.com/pypa/packaging/releases) - [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/packaging/compare/21.3...22.0) --- updated-dependencies: - dependency-name: packaging dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index f3be85b0..b6cafbe9 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -10,7 +10,7 @@ iniconfig==1.1.1 mypy==0.991 mypy-extensions==0.4.3 outcome==1.2.0 -packaging==21.3 +packaging==22.0 pluggy==1.0.0 pyparsing==3.0.9 pytest==7.2.0 From bc00c2bba82e973f39dfb85bf02bf154fc34a963 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Dec 2022 07:14:39 +0100 Subject: [PATCH 06/47] Build(deps): Bump hypothesis in /dependencies/default (#465) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.60.0 to 6.61.0. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.60.0...hypothesis-python-6.61.0) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index b6cafbe9..a164af3f 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -3,7 +3,7 @@ attrs==22.1.0 coverage==6.5.0 exceptiongroup==1.0.4 flaky==3.7.0 -hypothesis==6.60.0 +hypothesis==6.61.0 idna==3.4 importlib-metadata==5.1.0 iniconfig==1.1.1 From 57c70d8423b7bef93b12cbbd6c2a8ac55ea56b7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 16:57:48 +0100 Subject: [PATCH 07/47] Build(deps): Bump importlib-metadata in /dependencies/default (#468) Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 5.1.0 to 5.2.0. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/CHANGES.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v5.1.0...v5.2.0) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index a164af3f..3d66135d 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -5,7 +5,7 @@ exceptiongroup==1.0.4 flaky==3.7.0 hypothesis==6.61.0 idna==3.4 -importlib-metadata==5.1.0 +importlib-metadata==5.2.0 iniconfig==1.1.1 mypy==0.991 mypy-extensions==0.4.3 From 99cfd71e40e97ae51771ae66bd18612234bd8eff Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Thu, 22 Dec 2022 16:58:15 +0100 Subject: [PATCH 08/47] Remove use of deprecated ::set-output GitHub command (#466) * [ci] Remove use of deprecated ::set-output GitHub command. The ::set-output command has been deprecated in favor of redirecting the output to a file. [0] This patch adjusts get-version.py to the new output syntax and silences tox output to avoid writing excess information to the file. [0] https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ Closes #429 Signed-off-by: Michael Seifert * [ci] Invoke get-version script directly, instead of starting it in a tox environment. This requires pytest-asyncio being installed. Signed-off-by: Michael Seifert * [refactor] Removed obsolete "version-info" tox environment. Signed-off-by: Michael Seifert Signed-off-by: Michael Seifert --- .github/workflows/main.yml | 4 +++- tools/get-version.py | 4 ++-- tox.ini | 8 +------- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4132cdc6..7fd0e689 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,9 +38,11 @@ jobs: run: check-wheel-contents dist/*.whl - name: Check long_description run: python -m twine check dist/* + - name: Install pytest-asyncio + run: pip install . - name: Get version info id: version - run: tox -e version-info + run: python ./tools/get-version.py >> $GITHUB_OUTPUT - name: Upload artifacts uses: actions/upload-artifact@v3 with: diff --git a/tools/get-version.py b/tools/get-version.py index e988a32c..c29081b9 100644 --- a/tools/get-version.py +++ b/tools/get-version.py @@ -8,9 +8,9 @@ def main(): version_string = metadata.version("pytest-asyncio") version = parse_version(version_string) - print(f"::set-output name=version::{version}") + print(f"version={version}") prerelease = json.dumps(version.is_prerelease) - print(f"::set-output name=prerelease::{prerelease}") + print(f"prerelease={prerelease}") if __name__ == "__main__": diff --git a/tox.ini b/tox.ini index e705d9a6..97c19143 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] minversion = 3.14.0 -envlist = py37, py38, py39, py310, py311, lint, version-info, pytest-min +envlist = py37, py38, py39, py310, py311, lint, pytest-min isolated_build = true passenv = CI @@ -33,12 +33,6 @@ commands = allowlist_externals = make -[testenv:version-info] -deps = - packaging == 21.3 -commands = - python ./tools/get-version.py - [gh-actions] python = 3.7: py37, pytest-min From 591eeba10f2652f96220bd288e5e463746c3abb1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 16:58:40 +0100 Subject: [PATCH 09/47] Build(deps): Bump coverage from 6.5.0 to 7.0.0 in /dependencies/default (#469) Bumps [coverage](https://github.com/nedbat/coveragepy) from 6.5.0 to 7.0.0. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/6.5.0...7.0.0) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 3d66135d..cd75c2f9 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -1,6 +1,6 @@ async-generator==1.10 attrs==22.1.0 -coverage==6.5.0 +coverage==7.0.0 exceptiongroup==1.0.4 flaky==3.7.0 hypothesis==6.61.0 From bb853b00664e0002bc403697ecff7d50420567d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 17:20:43 +0100 Subject: [PATCH 10/47] Build(deps): Bump coverage from 7.0.0 to 7.0.1 in /dependencies/default (#471) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.0.0 to 7.0.1. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.0.0...7.0.1) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index cd75c2f9..2d61239f 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -1,6 +1,6 @@ async-generator==1.10 attrs==22.1.0 -coverage==7.0.0 +coverage==7.0.1 exceptiongroup==1.0.4 flaky==3.7.0 hypothesis==6.61.0 From d3241ddff5f5c7786c2c47e7356aed3642979329 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 17:22:21 +0100 Subject: [PATCH 11/47] Build(deps): Bump importlib-metadata in /dependencies/default (#474) Bumps [importlib-metadata](https://github.com/python/importlib_metadata) from 5.2.0 to 6.0.0. - [Release notes](https://github.com/python/importlib_metadata/releases) - [Changelog](https://github.com/python/importlib_metadata/blob/main/CHANGES.rst) - [Commits](https://github.com/python/importlib_metadata/compare/v5.2.0...v6.0.0) --- updated-dependencies: - dependency-name: importlib-metadata dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 2d61239f..ad1152df 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -5,7 +5,7 @@ exceptiongroup==1.0.4 flaky==3.7.0 hypothesis==6.61.0 idna==3.4 -importlib-metadata==5.2.0 +importlib-metadata==6.0.0 iniconfig==1.1.1 mypy==0.991 mypy-extensions==0.4.3 From 5711cdf8d4f299356de6c58ba1ee042170704ea6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 17:24:02 +0100 Subject: [PATCH 12/47] Build(deps): Bump attrs from 22.1.0 to 22.2.0 in /dependencies/default (#472) Bumps [attrs](https://github.com/python-attrs/attrs) from 22.1.0 to 22.2.0. - [Release notes](https://github.com/python-attrs/attrs/releases) - [Changelog](https://github.com/python-attrs/attrs/blob/main/CHANGELOG.md) - [Commits](https://github.com/python-attrs/attrs/compare/22.1.0...22.2.0) --- updated-dependencies: - dependency-name: attrs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index ad1152df..f561d887 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -1,5 +1,5 @@ async-generator==1.10 -attrs==22.1.0 +attrs==22.2.0 coverage==7.0.1 exceptiongroup==1.0.4 flaky==3.7.0 From 325007836ec4fac7e935313f200d6034aa359729 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 17:27:24 +0100 Subject: [PATCH 13/47] Build(deps): Bump exceptiongroup in /dependencies/default (#473) Bumps [exceptiongroup](https://github.com/agronholm/exceptiongroup) from 1.0.4 to 1.1.0. - [Release notes](https://github.com/agronholm/exceptiongroup/releases) - [Changelog](https://github.com/agronholm/exceptiongroup/blob/main/CHANGES.rst) - [Commits](https://github.com/agronholm/exceptiongroup/compare/1.0.4...1.1.0) --- updated-dependencies: - dependency-name: exceptiongroup dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index f561d887..1a1a4c80 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -1,7 +1,7 @@ async-generator==1.10 attrs==22.2.0 coverage==7.0.1 -exceptiongroup==1.0.4 +exceptiongroup==1.1.0 flaky==3.7.0 hypothesis==6.61.0 idna==3.4 From e28a110ceaa9f416fa40eaad72d2b3a09e3b126c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 10:45:02 +0100 Subject: [PATCH 14/47] Build(deps): Bump iniconfig from 1.1.1 to 2.0.0 in /dependencies/default (#478) Bumps [iniconfig](https://github.com/pytest-dev/iniconfig) from 1.1.1 to 2.0.0. - [Release notes](https://github.com/pytest-dev/iniconfig/releases) - [Changelog](https://github.com/pytest-dev/iniconfig/blob/main/CHANGELOG) - [Commits](https://github.com/pytest-dev/iniconfig/compare/v1.1.1...v2.0.0) --- updated-dependencies: - dependency-name: iniconfig dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 1a1a4c80..4fdc0a29 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -6,7 +6,7 @@ flaky==3.7.0 hypothesis==6.61.0 idna==3.4 importlib-metadata==6.0.0 -iniconfig==1.1.1 +iniconfig==2.0.0 mypy==0.991 mypy-extensions==0.4.3 outcome==1.2.0 From 00435398885c35553f388be2c082ec69b756c460 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 10:46:26 +0100 Subject: [PATCH 15/47] Build(deps): Bump coverage from 7.0.1 to 7.0.4 in /dependencies/default (#475) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.0.1 to 7.0.4. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.0.1...7.0.4) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 4fdc0a29..34a29eff 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -1,6 +1,6 @@ async-generator==1.10 attrs==22.2.0 -coverage==7.0.1 +coverage==7.0.4 exceptiongroup==1.1.0 flaky==3.7.0 hypothesis==6.61.0 From 8458df026d8be0d3f5ae4ae012729d3d535a6945 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 10:49:18 +0100 Subject: [PATCH 16/47] Build(deps): Bump hypothesis in /dependencies/default (#479) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.61.0 to 6.62.1. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.61.0...hypothesis-python-6.62.1) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 34a29eff..e6ebfa3f 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -3,7 +3,7 @@ attrs==22.2.0 coverage==7.0.4 exceptiongroup==1.1.0 flaky==3.7.0 -hypothesis==6.61.0 +hypothesis==6.62.1 idna==3.4 importlib-metadata==6.0.0 iniconfig==2.0.0 From ed0666c266f88064bb32a128c222b13ae153af2a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 15 Jan 2023 10:51:04 +0100 Subject: [PATCH 17/47] Build(deps): Bump packaging from 22.0 to 23.0 in /dependencies/default (#477) Bumps [packaging](https://github.com/pypa/packaging) from 22.0 to 23.0. - [Release notes](https://github.com/pypa/packaging/releases) - [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/packaging/compare/22.0...23.0) --- updated-dependencies: - dependency-name: packaging dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index e6ebfa3f..f7c1c673 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -10,7 +10,7 @@ iniconfig==2.0.0 mypy==0.991 mypy-extensions==0.4.3 outcome==1.2.0 -packaging==22.0 +packaging==23.0 pluggy==1.0.0 pyparsing==3.0.9 pytest==7.2.0 From 6adce31fc73df9e74b914465821b15da9bc27701 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Sun, 15 Jan 2023 11:01:53 +0100 Subject: [PATCH 18/47] Add mypy as pre-commit hook (#467) * [refactor] Run mypy as part of the pre-commit hooks. Signed-off-by: Michael Seifert * [ci] Use pre-commit directly, instead of starting it via a tox environment. Signed-off-by: Michael Seifert * [refactor] Removed obsolete "lint" tox environment. Signed-off-by: Michael Seifert * [ci] Run lint step with Python 3.11. Signed-off-by: Michael Seifert * [ci] Extracted environment variable for the latest Python version. Signed-off-by: Michael Seifert * [ci] Avoid checking out unnecessary Git history during deployment step. Signed-off-by: Michael Seifert * [ci] Avoid checking out unnecessary Git history during test step. Signed-off-by: Michael Seifert * [ci] Removed obsolete USING_COVERAGE env variable. We record coverage for all interpreters and merge them afterwards. There is no longer a need to specify the environment we want to use for measuring coverage. Signed-off-by: Michael Seifert Signed-off-by: Michael Seifert --- .github/workflows/main.yml | 20 +++++++++----------- .pre-commit-config.yaml | 5 +++++ Makefile | 9 --------- tox.ini | 12 +----------- 4 files changed, 15 insertions(+), 31 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7fd0e689..da8dd51a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,6 +9,9 @@ on: branches: [master] workflow_dispatch: +env: + PYTHON_LATEST: 3.11 + jobs: lint: name: Run linters @@ -22,16 +25,18 @@ jobs: fetch-depth: 0 - uses: actions/setup-python@v4 with: - python-version: '3.10' + python-version: ${{ env.PYTHON_LATEST }} - name: Install GitHub matcher for ActionLint checker run: | echo "::add-matcher::.github/actionlint-matcher.json" + - name: Install pre-commit + run: python -m pip install pre-commit + - name: Run pre-commit checks + run: pre-commit run --all-files --show-diff-on-failure - name: Install check-wheel-content, and twine run: python -m pip install build check-wheel-contents tox twine - name: Build package run: python -m build - - name: Run tox for linter - run: python -m tox -e lint - name: List result run: ls -l dist - name: Check wheel contents @@ -52,8 +57,6 @@ jobs: test: name: Python ${{ matrix.python-version }} runs-on: ubuntu-latest - env: - USING_COVERAGE: 3.7,3.8,3.9,3.10,3.11 strategy: matrix: @@ -61,8 +64,6 @@ jobs: steps: - uses: actions/checkout@v3 - with: - fetch-depth: 0 - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} @@ -81,7 +82,6 @@ jobs: with: name: coverage-per-interpreter path: .coverage.* - if: ${{ contains(env.USING_COVERAGE, matrix.python-version) }} check: name: Check @@ -96,7 +96,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: 3.11 + python-version: ${{ env.PYTHON_LATEST }} - name: Install Coverage.py run: | set -xe @@ -128,8 +128,6 @@ jobs: sudo apt-get install -y pandoc - name: Checkout uses: actions/checkout@v3 - with: - fetch-depth: 0 - name: Download distributions uses: actions/download-artifact@v3 with: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d8ee693e..fc81f2f5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,6 +36,11 @@ repos: - id: check-xml - id: check-yaml - id: debug-statements +- repo: https://github.com/pre-commit/mirrors-mypy + rev: v0.991 + hooks: + - id: mypy + exclude: ^(docs|tests)/.* - repo: https://github.com/pycqa/flake8 rev: 5.0.4 hooks: diff --git a/Makefile b/Makefile index c5d9fac1..8bc58c49 100644 --- a/Makefile +++ b/Makefile @@ -20,15 +20,6 @@ clean-test: ## remove test and coverage artifacts rm -f .coverage rm -fr htmlcov/ -lint: -# CI env-var is set by GitHub actions -ifdef CI - python -m pre_commit run --all-files --show-diff-on-failure -else - python -m pre_commit run --all-files -endif - python -m mypy pytest_asyncio - test: coverage run --parallel-mode --omit */_version.py -m pytest tests diff --git a/tox.ini b/tox.ini index 97c19143..ceaccb39 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] minversion = 3.14.0 -envlist = py37, py38, py39, py310, py311, lint, pytest-min +envlist = py37, py38, py39, py310, py311, pytest-min isolated_build = true passenv = CI @@ -23,16 +23,6 @@ commands = make test allowlist_externals = make -[testenv:lint] -basepython = python3.10 -extras = testing -deps = - pre-commit == 2.16.0 -commands = - make lint -allowlist_externals = - make - [gh-actions] python = 3.7: py37, pytest-min From 97ece5551f8a060807405bf649392fc1cf1d7f18 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Fri, 20 Jan 2023 08:51:07 +0100 Subject: [PATCH 19/47] Include changelog in user docs (#481) * [docs] Split up the reference section into different documents, one for each topic. Signed-off-by: Michael Seifert * [docs] Move CHANGELOG from project root to user documentation. Signed-off-by: Michael Seifert * [build] Add links to documentation, changelog, and bug tracker to the project URLs. Signed-off-by: Michael Seifert Signed-off-by: Michael Seifert --- MANIFEST.in | 2 - docs/source/index.rst | 2 +- docs/source/reference.rst | 145 ------------------ .../source/reference/changelog.rst | 0 docs/source/reference/configuration.rst | 21 +++ docs/source/reference/decorators.rst | 27 ++++ docs/source/reference/fixtures.rst | 58 +++++++ docs/source/reference/index.rst | 15 ++ docs/source/reference/markers.rst | 34 ++++ setup.cfg | 5 +- 10 files changed, 160 insertions(+), 149 deletions(-) delete mode 100644 docs/source/reference.rst rename CHANGELOG.rst => docs/source/reference/changelog.rst (100%) create mode 100644 docs/source/reference/configuration.rst create mode 100644 docs/source/reference/decorators.rst create mode 100644 docs/source/reference/fixtures.rst create mode 100644 docs/source/reference/index.rst create mode 100644 docs/source/reference/markers.rst diff --git a/MANIFEST.in b/MANIFEST.in index fdf813e9..6bd245e1 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,3 @@ -include CHANGELOG.rst - recursive-exclude .github * exclude .gitignore exclude .pre-commit-config.yaml diff --git a/docs/source/index.rst b/docs/source/index.rst index 153fe9e8..618e6e6f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -7,7 +7,7 @@ Welcome to pytest-asyncio! :hidden: concepts - reference + reference/index support pytest-asyncio is a `pytest `_ plugin. It facilitates testing of code that uses the `asyncio `_ library. diff --git a/docs/source/reference.rst b/docs/source/reference.rst deleted file mode 100644 index 2fa77ff4..00000000 --- a/docs/source/reference.rst +++ /dev/null @@ -1,145 +0,0 @@ -========= -Reference -========= - -Configuration -============= - -The pytest-asyncio mode can be set by the ``asyncio_mode`` configuration option in the `configuration file -`_: - -.. code-block:: ini - - # pytest.ini - [pytest] - asyncio_mode = auto - -The value can also be set via the ``--asyncio-mode`` command-line option: - -.. code-block:: bash - - $ pytest tests --asyncio-mode=strict - - -If the asyncio mode is set in both the pytest configuration file and the command-line option, the command-line option takes precedence. If no asyncio mode is specified, the mode defaults to `strict`. - -Fixtures -======== - -``event_loop`` --------------- -Creates a new asyncio event loop based on the current event loop policy. The new loop -is available as the return value of this fixture or via `asyncio.get_running_loop `__. -The event loop is closed when the fixture scope ends. The fixture scope defaults -to ``function`` scope. - -.. code-block:: python - - def test_http_client(event_loop): - url = "http://httpbin.org/get" - resp = event_loop.run_until_complete(http_client(url)) - assert b"HTTP/1.1 200 OK" in resp - -Note that, when using the ``event_loop`` fixture, you need to interact with the event loop using methods like ``event_loop.run_until_complete``. If you want to *await* code inside your test function, you need to write a coroutine and use it as a test function. The `asyncio <#pytest-mark-asyncio>`__ marker -is used to mark coroutines that should be treated as test functions. - -The ``event_loop`` fixture can be overridden in any of the standard pytest locations, -e.g. directly in the test file, or in ``conftest.py``. This allows redefining the -fixture scope, for example: - -.. code-block:: python - - @pytest.fixture(scope="session") - def event_loop(): - policy = asyncio.get_event_loop_policy() - loop = policy.new_event_loop() - yield loop - loop.close() - -If you need to change the type of the event loop, prefer setting a custom event loop policy over redefining the ``event_loop`` fixture. - -If the ``pytest.mark.asyncio`` decorator is applied to a test function, the ``event_loop`` -fixture will be requested automatically by the test function. - -``unused_tcp_port`` -------------------- -Finds and yields a single unused TCP port on the localhost interface. Useful for -binding temporary test servers. - -``unused_tcp_port_factory`` ---------------------------- -A callable which returns a different unused TCP port each invocation. Useful -when several unused TCP ports are required in a test. - -.. code-block:: python - - def a_test(unused_tcp_port_factory): - port1, port2 = unused_tcp_port_factory(), unused_tcp_port_factory() - ... - -``unused_udp_port`` and ``unused_udp_port_factory`` ---------------------------------------------------- -Works just like their TCP counterparts but returns unused UDP ports. - - -Markers -======= - -``pytest.mark.asyncio`` ------------------------ -A coroutine or async generator with this marker will be treated as a test function by pytest. The marked function will be executed as an -asyncio task in the event loop provided by the ``event_loop`` fixture. - -In order to make your test code a little more concise, the pytest |pytestmark|_ -feature can be used to mark entire modules or classes with this marker. -Only test coroutines will be affected (by default, coroutines prefixed by -``test_``), so, for example, fixtures are safe to define. - -.. code-block:: python - - import asyncio - - import pytest - - # All test coroutines will be treated as marked. - pytestmark = pytest.mark.asyncio - - - async def test_example(event_loop): - """No marker!""" - await asyncio.sleep(0, loop=event_loop) - -In *auto* mode, the ``pytest.mark.asyncio`` marker can be omitted, the marker is added -automatically to *async* test functions. - - -.. |pytestmark| replace:: ``pytestmark`` -.. _pytestmark: http://doc.pytest.org/en/latest/example/markers.html#marking-whole-classes-or-modules - - -Decorators -========== -Asynchronous fixtures are defined just like ordinary pytest fixtures, except they should be decorated with ``@pytest_asyncio.fixture``. - -.. code-block:: python3 - - import pytest_asyncio - - - @pytest_asyncio.fixture - async def async_gen_fixture(): - await asyncio.sleep(0.1) - yield "a value" - - - @pytest_asyncio.fixture(scope="module") - async def async_fixture(): - return await asyncio.sleep(0.1) - -All scopes are supported, but if you use a non-function scope you will need -to redefine the ``event_loop`` fixture to have the same or broader scope. -Async fixtures need the event loop, and so must have the same or narrower scope -than the ``event_loop`` fixture. - -*auto* mode automatically converts async fixtures declared with the -standard ``@pytest.fixture`` decorator to *asyncio-driven* versions. diff --git a/CHANGELOG.rst b/docs/source/reference/changelog.rst similarity index 100% rename from CHANGELOG.rst rename to docs/source/reference/changelog.rst diff --git a/docs/source/reference/configuration.rst b/docs/source/reference/configuration.rst new file mode 100644 index 00000000..5d840c47 --- /dev/null +++ b/docs/source/reference/configuration.rst @@ -0,0 +1,21 @@ +============= +Configuration +============= + +The pytest-asyncio mode can be set by the ``asyncio_mode`` configuration option in the `configuration file +`_: + +.. code-block:: ini + + # pytest.ini + [pytest] + asyncio_mode = auto + +The value can also be set via the ``--asyncio-mode`` command-line option: + +.. code-block:: bash + + $ pytest tests --asyncio-mode=strict + + +If the asyncio mode is set in both the pytest configuration file and the command-line option, the command-line option takes precedence. If no asyncio mode is specified, the mode defaults to `strict`. diff --git a/docs/source/reference/decorators.rst b/docs/source/reference/decorators.rst new file mode 100644 index 00000000..977ed6b8 --- /dev/null +++ b/docs/source/reference/decorators.rst @@ -0,0 +1,27 @@ +========== +Decorators +========== +Asynchronous fixtures are defined just like ordinary pytest fixtures, except they should be decorated with ``@pytest_asyncio.fixture``. + +.. code-block:: python3 + + import pytest_asyncio + + + @pytest_asyncio.fixture + async def async_gen_fixture(): + await asyncio.sleep(0.1) + yield "a value" + + + @pytest_asyncio.fixture(scope="module") + async def async_fixture(): + return await asyncio.sleep(0.1) + +All scopes are supported, but if you use a non-function scope you will need +to redefine the ``event_loop`` fixture to have the same or broader scope. +Async fixtures need the event loop, and so must have the same or narrower scope +than the ``event_loop`` fixture. + +*auto* mode automatically converts async fixtures declared with the +standard ``@pytest.fixture`` decorator to *asyncio-driven* versions. diff --git a/docs/source/reference/fixtures.rst b/docs/source/reference/fixtures.rst new file mode 100644 index 00000000..fdd3e034 --- /dev/null +++ b/docs/source/reference/fixtures.rst @@ -0,0 +1,58 @@ +======== +Fixtures +======== + +``event_loop`` +============== +Creates a new asyncio event loop based on the current event loop policy. The new loop +is available as the return value of this fixture or via `asyncio.get_running_loop `__. +The event loop is closed when the fixture scope ends. The fixture scope defaults +to ``function`` scope. + +.. code-block:: python + + def test_http_client(event_loop): + url = "http://httpbin.org/get" + resp = event_loop.run_until_complete(http_client(url)) + assert b"HTTP/1.1 200 OK" in resp + +Note that, when using the ``event_loop`` fixture, you need to interact with the event loop using methods like ``event_loop.run_until_complete``. If you want to *await* code inside your test function, you need to write a coroutine and use it as a test function. The `asyncio <#pytest-mark-asyncio>`__ marker +is used to mark coroutines that should be treated as test functions. + +The ``event_loop`` fixture can be overridden in any of the standard pytest locations, +e.g. directly in the test file, or in ``conftest.py``. This allows redefining the +fixture scope, for example: + +.. code-block:: python + + @pytest.fixture(scope="session") + def event_loop(): + policy = asyncio.get_event_loop_policy() + loop = policy.new_event_loop() + yield loop + loop.close() + +If you need to change the type of the event loop, prefer setting a custom event loop policy over redefining the ``event_loop`` fixture. + +If the ``pytest.mark.asyncio`` decorator is applied to a test function, the ``event_loop`` +fixture will be requested automatically by the test function. + +``unused_tcp_port`` +=================== +Finds and yields a single unused TCP port on the localhost interface. Useful for +binding temporary test servers. + +``unused_tcp_port_factory`` +=========================== +A callable which returns a different unused TCP port each invocation. Useful +when several unused TCP ports are required in a test. + +.. code-block:: python + + def a_test(unused_tcp_port_factory): + port1, port2 = unused_tcp_port_factory(), unused_tcp_port_factory() + ... + +``unused_udp_port`` and ``unused_udp_port_factory`` +=================================================== +Works just like their TCP counterparts but returns unused UDP ports. diff --git a/docs/source/reference/index.rst b/docs/source/reference/index.rst new file mode 100644 index 00000000..c07d0e19 --- /dev/null +++ b/docs/source/reference/index.rst @@ -0,0 +1,15 @@ +========= +Reference +========= + +.. toctree:: + :hidden: + + configuration + fixtures + markers + decorators + changelog + +This section of the documentation provides descriptions of the individual parts provided by pytest-asyncio. +The reference section also provides a chronological list of changes for each release. diff --git a/docs/source/reference/markers.rst b/docs/source/reference/markers.rst new file mode 100644 index 00000000..eb89592c --- /dev/null +++ b/docs/source/reference/markers.rst @@ -0,0 +1,34 @@ +======= +Markers +======= + +``pytest.mark.asyncio`` +======================= +A coroutine or async generator with this marker will be treated as a test function by pytest. The marked function will be executed as an +asyncio task in the event loop provided by the ``event_loop`` fixture. + +In order to make your test code a little more concise, the pytest |pytestmark|_ +feature can be used to mark entire modules or classes with this marker. +Only test coroutines will be affected (by default, coroutines prefixed by +``test_``), so, for example, fixtures are safe to define. + +.. code-block:: python + + import asyncio + + import pytest + + # All test coroutines will be treated as marked. + pytestmark = pytest.mark.asyncio + + + async def test_example(event_loop): + """No marker!""" + await asyncio.sleep(0, loop=event_loop) + +In *auto* mode, the ``pytest.mark.asyncio`` marker can be omitted, the marker is added +automatically to *async* test functions. + + +.. |pytestmark| replace:: ``pytestmark`` +.. _pytestmark: http://doc.pytest.org/en/latest/example/markers.html#marking-whole-classes-or-modules diff --git a/setup.cfg b/setup.cfg index 04ea3d90..a82c57e1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,7 +3,10 @@ name = pytest-asyncio version = attr: pytest_asyncio.__version__ url = https://github.com/pytest-dev/pytest-asyncio project_urls = - GitHub = https://github.com/pytest-dev/pytest-asyncio + Documentation = https://pytest-asyncio.readthedocs.io + Changelog = https://pytest-asyncio.readthedocs.io/en/latest/reference/changelog.html + Source Code = https://github.com/pytest-dev/pytest-asyncio + Bug Tracker = https://github.com/pytest-dev/pytest-asyncio/issues description = Pytest support for asyncio long_description = file: README.rst long_description_content_type = text/x-rst From cafa26cdad8400b4fcedc080f3e69aa9fb0c3982 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Fri, 20 Jan 2023 09:01:31 +0100 Subject: [PATCH 20/47] Drop pytest 6.1 compatibility (#482) * [build] Drop compatibility with pytest 6.1. Pytest 7 was released on 2022-02-03, roughly one year ago. It is time to bump the minimum version requirement on pytest. Signed-off-by: Michael Seifert * [refactor] Replace custom type aliases for with pytest types. The types Config, PytestPluginManager, and Parser are available as part of the public pytest API starting from pytest 7. Signed-off-by: Michael Seifert * [refactor] Remove deprecation warning when using a pytest version lower than 7. The minimum pytest version was bumped to v7, so this deprecation warning should never be triggered. Signed-off-by: Michael Seifert * [refactor] Replace forward reference in event_loop fixture with actual type. Signed-off-by: Michael Seifert * [refactor] Link to Pull Request for exposing FixtureDef and SubRequest in pytest. Signed-off-by: Michael Seifert Signed-off-by: Michael Seifert --- dependencies/default/requirements.txt | 2 +- dependencies/pytest-min/constraints.txt | 34 ++++++++++++------------ dependencies/pytest-min/requirements.txt | 2 +- docs/source/reference/changelog.rst | 4 +++ pytest_asyncio/plugin.py | 28 +++++++++---------- setup.cfg | 2 +- tests/test_pytest_min_version_warning.py | 26 ------------------ 7 files changed, 37 insertions(+), 61 deletions(-) delete mode 100644 tests/test_pytest_min_version_warning.py diff --git a/dependencies/default/requirements.txt b/dependencies/default/requirements.txt index 01b2484e..a0009a85 100644 --- a/dependencies/default/requirements.txt +++ b/dependencies/default/requirements.txt @@ -1,4 +1,4 @@ # Always adjust install_requires in setup.cfg and pytest-min-requirements.txt # when changing runtime dependencies -pytest >= 6.1.0 +pytest >= 7.0.0 typing-extensions >= 3.7.2; python_version < "3.8" diff --git a/dependencies/pytest-min/constraints.txt b/dependencies/pytest-min/constraints.txt index 33f7948f..1f82dbaf 100644 --- a/dependencies/pytest-min/constraints.txt +++ b/dependencies/pytest-min/constraints.txt @@ -1,22 +1,22 @@ -async-generator==1.10 -attrs==21.4.0 -coverage==6.3.2 -flaky==3.7.0 -hypothesis==6.43.3 -idna==3.3 +argcomplete==2.0.0 +attrs==22.1.0 +certifi==2022.9.24 +charset-normalizer==2.1.1 +elementpath==3.0.2 +exceptiongroup==1.0.0rc9 +hypothesis==6.56.3 +idna==3.4 iniconfig==1.1.1 -mypy==0.942 -mypy-extensions==0.4.3 -outcome==1.1.0 +mock==4.0.3 +nose==1.3.7 packaging==21.3 -pluggy==0.13.1 +pluggy==1.0.0 py==1.11.0 -pyparsing==3.0.8 -pytest==6.1.0 -pytest-trio==0.7.0 -sniffio==1.2.0 +Pygments==2.13.0 +pyparsing==3.0.9 +pytest==7.0.0 +requests==2.28.1 sortedcontainers==2.4.0 -toml==0.10.2 tomli==2.0.1 -trio==0.20.0 -typing_extensions==4.2.0 +urllib3==1.26.12 +xmlschema==2.1.1 diff --git a/dependencies/pytest-min/requirements.txt b/dependencies/pytest-min/requirements.txt index 4fc6ef2f..4152d2f8 100644 --- a/dependencies/pytest-min/requirements.txt +++ b/dependencies/pytest-min/requirements.txt @@ -1,4 +1,4 @@ # Always adjust install_requires in setup.cfg and requirements.txt # when changing minimum version dependencies -pytest == 6.1.0 +pytest[testing] == 7.0.0 typing-extensions >= 3.7.2; python_version < "3.8" diff --git a/docs/source/reference/changelog.rst b/docs/source/reference/changelog.rst index e6f80383..af4eb7bf 100644 --- a/docs/source/reference/changelog.rst +++ b/docs/source/reference/changelog.rst @@ -2,6 +2,10 @@ Changelog ========= +UNRELEASED +================= +- Drop compatibility with pytest 6.1. Pytest-asyncio now depends on pytest 7.0 or newer. + 0.20.3 (22-12-08) ================= - Prevent DeprecationWarning to bubble up on CPython 3.10.9 and 3.11.1. diff --git a/pytest_asyncio/plugin.py b/pytest_asyncio/plugin.py index 403d814f..f663ff68 100644 --- a/pytest_asyncio/plugin.py +++ b/pytest_asyncio/plugin.py @@ -25,7 +25,15 @@ ) import pytest -from pytest import Function, Item, Session +from pytest import ( + Config, + FixtureRequest, + Function, + Item, + Parser, + PytestPluginManager, + Session, +) if sys.version_info >= (3, 8): from typing import Literal @@ -46,11 +54,9 @@ FixtureFunction = Union[SimpleFixtureFunction, FactoryFixtureFunction] FixtureFunctionMarker = Callable[[FixtureFunction], FixtureFunction] -Config = Any # pytest < 7.0 -PytestPluginManager = Any # pytest < 7.0 -FixtureDef = Any # pytest < 7.0 -Parser = Any # pytest < 7.0 -SubRequest = Any # pytest < 7.0 +# https://github.com/pytest-dev/pytest/pull/9510 +FixtureDef = Any +SubRequest = Any class Mode(str, enum.Enum): @@ -169,14 +175,6 @@ def pytest_configure(config: Config) -> None: "run using an asyncio event loop", ) - if getattr(pytest, "version_tuple", (0, 0, 0)) < (7,): - warnings.warn( - "You're using an outdated version of pytest. Newer releases of " - "pytest-asyncio will not be compatible with this pytest version. " - "Please update pytest to version 7 or later.", - DeprecationWarning, - ) - @pytest.hookimpl(tryfirst=True) def pytest_report_header(config: Config) -> List[str]: @@ -508,7 +506,7 @@ def pytest_runtest_setup(item: pytest.Item) -> None: @pytest.fixture -def event_loop(request: "pytest.FixtureRequest") -> Iterator[asyncio.AbstractEventLoop]: +def event_loop(request: FixtureRequest) -> Iterator[asyncio.AbstractEventLoop]: """Create an instance of the default event loop for each test case.""" loop = asyncio.get_event_loop_policy().new_event_loop() yield loop diff --git a/setup.cfg b/setup.cfg index a82c57e1..ee57438c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,7 +40,7 @@ include_package_data = True # Always adjust requirements.txt and pytest-min-requirements.txt when changing runtime dependencies install_requires = - pytest >= 6.1.0 + pytest >= 7.0.0 typing-extensions >= 3.7.2; python_version < "3.8" [options.extras_require] diff --git a/tests/test_pytest_min_version_warning.py b/tests/test_pytest_min_version_warning.py deleted file mode 100644 index 5f7bd72f..00000000 --- a/tests/test_pytest_min_version_warning.py +++ /dev/null @@ -1,26 +0,0 @@ -from textwrap import dedent - -import pytest - - -@pytest.mark.skipif( - pytest.__version__ < "7.0.0", - reason="The warning shouldn't be present when run with recent pytest versions", -) -@pytest.mark.parametrize("mode", ("auto", "strict")) -def test_pytest_min_version_warning_is_not_triggered_for_pytest_7(testdir, mode): - testdir.makepyfile( - dedent( - """\ - import pytest - - pytest_plugins = 'pytest_asyncio' - - @pytest.mark.asyncio - async def test_triggers_pytest_warning(): - pass - """ - ) - ) - result = testdir.runpytest(f"--asyncio-mode={mode}") - result.assert_outcomes(passed=1, warnings=0) From 6c2c11d6cb017d94a415bac91be53ac38919e52f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Jan 2023 09:01:44 +0100 Subject: [PATCH 21/47] Build(deps): Bump pytest from 7.2.0 to 7.2.1 in /dependencies/default (#483) Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.0 to 7.2.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.2.0...7.2.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index f7c1c673..75845f7c 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -13,7 +13,7 @@ outcome==1.2.0 packaging==23.0 pluggy==1.0.0 pyparsing==3.0.9 -pytest==7.2.0 +pytest==7.2.1 pytest-trio==0.8.0 sniffio==1.3.0 sortedcontainers==2.4.0 From c4e082d4387fa39490f5422fdd4a45a37ce05367 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Jan 2023 09:01:58 +0100 Subject: [PATCH 22/47] Build(deps): Bump coverage from 7.0.4 to 7.0.5 in /dependencies/default (#484) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.0.4 to 7.0.5. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.0.4...7.0.5) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 75845f7c..51a1da1b 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -1,6 +1,6 @@ async-generator==1.10 attrs==22.2.0 -coverage==7.0.4 +coverage==7.0.5 exceptiongroup==1.1.0 flaky==3.7.0 hypothesis==6.62.1 From 174bddb031ceb5eac0611f9e291f006bd35cb5ce Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Wed, 1 Feb 2023 11:21:02 +0100 Subject: [PATCH 23/47] Explain new event loop in fixture finalizer (#486) * [docs] Explain why a new event loop needs to be created after finalizing the event_loop fixture. Signed-off-by: Michael Seifert * [refactor] Restructured tests for event_loop fixture finalizer. The tests were split up so that the name of the test case reflects the test purpose. Signed-off-by: Michael Seifert * [test] Added more variations to test which asserts that the event loop can be set to None. Signed-off-by: Michael Seifert * [refactor] Renamed test_event_loop_scope.py to test_event_loop_fixture_finalizer.py. Signed-off-by: Michael Seifert * [docs] Documented that pytest_fixture_post_finalizer may be called multiple times for any specific fixture. Signed-off-by: Michael Seifert --------- Signed-off-by: Michael Seifert --- pytest_asyncio/plugin.py | 16 +++- tests/test_event_loop_fixture_finalizer.py | 88 ++++++++++++++++++++++ tests/test_event_loop_scope.py | 37 --------- 3 files changed, 101 insertions(+), 40 deletions(-) create mode 100644 tests/test_event_loop_fixture_finalizer.py delete mode 100644 tests/test_event_loop_scope.py diff --git a/pytest_asyncio/plugin.py b/pytest_asyncio/plugin.py index f663ff68..21809b6d 100644 --- a/pytest_asyncio/plugin.py +++ b/pytest_asyncio/plugin.py @@ -372,7 +372,12 @@ def _hypothesis_test_wraps_coroutine(function: Any) -> bool: @pytest.hookimpl(trylast=True) def pytest_fixture_post_finalizer(fixturedef: FixtureDef, request: SubRequest) -> None: - """Called after fixture teardown""" + """ + Called after fixture teardown. + + Note that this function may be called multiple times for any specific fixture. + see https://github.com/pytest-dev/pytest/issues/5848 + """ if fixturedef.argname == "event_loop": policy = asyncio.get_event_loop_policy() try: @@ -382,8 +387,13 @@ def pytest_fixture_post_finalizer(fixturedef: FixtureDef, request: SubRequest) - if loop is not None: # Clean up existing loop to avoid ResourceWarnings loop.close() - new_loop = policy.new_event_loop() # Replace existing event loop - # Ensure subsequent calls to get_event_loop() succeed + # At this point, the event loop for the current thread is closed. + # When a user calls asyncio.get_event_loop(), they will get a closed loop. + # In order to avoid this side effect from pytest-asyncio, we need to replace + # the current loop with a fresh one. + # Note that we cannot set the loop to None, because get_event_loop only creates + # a new loop, when set_event_loop has not been called. + new_loop = policy.new_event_loop() policy.set_event_loop(new_loop) diff --git a/tests/test_event_loop_fixture_finalizer.py b/tests/test_event_loop_fixture_finalizer.py new file mode 100644 index 00000000..d3622a08 --- /dev/null +++ b/tests/test_event_loop_fixture_finalizer.py @@ -0,0 +1,88 @@ +from textwrap import dedent + +from pytest import Pytester + + +def test_event_loop_fixture_finalizer_returns_fresh_loop_after_test(pytester: Pytester): + pytester.makepyfile( + dedent( + """\ + import asyncio + + import pytest + + loop = asyncio.get_event_loop_policy().get_event_loop() + + @pytest.mark.asyncio + async def test_1(): + # This async test runs in its own event loop + 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 + + def test_2(): + # Code outside of pytest-asyncio should not receive a "used" event loop + current_loop = asyncio.get_event_loop_policy().get_event_loop() + assert not current_loop.is_running() + assert not current_loop.is_closed() + """ + ) + ) + result = pytester.runpytest("--asyncio-mode=strict") + result.assert_outcomes(passed=2) + + +def test_event_loop_fixture_finalizer_handles_loop_set_to_none_sync( + pytester: Pytester, +): + pytester.makepyfile( + dedent( + """\ + import asyncio + + def test_sync(event_loop): + asyncio.get_event_loop_policy().set_event_loop(None) + """ + ) + ) + result = pytester.runpytest("--asyncio-mode=strict") + result.assert_outcomes(passed=1) + + +def test_event_loop_fixture_finalizer_handles_loop_set_to_none_async_without_fixture( + pytester: Pytester, +): + pytester.makepyfile( + dedent( + """\ + import asyncio + import pytest + + @pytest.mark.asyncio + async def test_async_without_explicit_fixture_request(): + asyncio.get_event_loop_policy().set_event_loop(None) + """ + ) + ) + result = pytester.runpytest("--asyncio-mode=strict") + result.assert_outcomes(passed=1) + + +def test_event_loop_fixture_finalizer_handles_loop_set_to_none_async_with_fixture( + pytester: Pytester, +): + pytester.makepyfile( + dedent( + """\ + import asyncio + import pytest + + @pytest.mark.asyncio + async def test_async_with_explicit_fixture_request(event_loop): + asyncio.get_event_loop_policy().set_event_loop(None) + """ + ) + ) + result = pytester.runpytest("--asyncio-mode=strict") + result.assert_outcomes(passed=1) diff --git a/tests/test_event_loop_scope.py b/tests/test_event_loop_scope.py deleted file mode 100644 index 21fd6415..00000000 --- a/tests/test_event_loop_scope.py +++ /dev/null @@ -1,37 +0,0 @@ -"""Test the event loop fixture provides a separate loop for each test. - -These tests need to be run together. -""" -import asyncio - -import pytest - -loop: asyncio.AbstractEventLoop - - -def test_1(): - 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(): - 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(): - 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 - - -def test_4(event_loop): - # If a test sets the loop to None -- pytest_fixture_post_finalizer() - # still should work - asyncio.get_event_loop_policy().set_event_loop(None) From 6170025435bbf5a2b6e234cb08a67dcbd9162d7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 11:21:21 +0100 Subject: [PATCH 24/47] Build(deps): Bump zipp from 3.11.0 to 3.12.0 in /dependencies/default (#490) Bumps [zipp](https://github.com/jaraco/zipp) from 3.11.0 to 3.12.0. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.11.0...v3.12.0) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 51a1da1b..f3450d0a 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -21,4 +21,4 @@ tomli==2.0.1 trio==0.22.0 typed-ast==1.5.4 typing_extensions==4.4.0 -zipp==3.11.0 +zipp==3.12.0 From 6d287678127ee14140beef42ca345a1535521586 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 11:21:47 +0100 Subject: [PATCH 25/47] Build(deps): Bump coverage from 7.0.5 to 7.1.0 in /dependencies/default (#489) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.0.5 to 7.1.0. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.0.5...7.1.0) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index f3450d0a..79a944a9 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -1,6 +1,6 @@ async-generator==1.10 attrs==22.2.0 -coverage==7.0.5 +coverage==7.1.0 exceptiongroup==1.1.0 flaky==3.7.0 hypothesis==6.62.1 From 1bc34f19aecdcbe13ab108bc4e44306e909e29b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 11:22:41 +0100 Subject: [PATCH 26/47] Build(deps): Bump hypothesis in /dependencies/default (#488) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.62.1 to 6.65.2. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.62.1...hypothesis-python-6.65.2) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 79a944a9..e4ae7883 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -3,7 +3,7 @@ attrs==22.2.0 coverage==7.1.0 exceptiongroup==1.1.0 flaky==3.7.0 -hypothesis==6.62.1 +hypothesis==6.65.2 idna==3.4 importlib-metadata==6.0.0 iniconfig==2.0.0 From 1bd5252399cd6eb269c98217f5b1feb292788207 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Feb 2023 16:26:55 +0100 Subject: [PATCH 27/47] Build(deps): Bump mypy-extensions in /dependencies/default (#495) Bumps [mypy-extensions](https://github.com/python/mypy_extensions) from 0.4.3 to 1.0.0. - [Release notes](https://github.com/python/mypy_extensions/releases) - [Commits](https://github.com/python/mypy_extensions/compare/0.4.3...1.0.0) --- updated-dependencies: - dependency-name: mypy-extensions dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index e4ae7883..84b85148 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -8,7 +8,7 @@ idna==3.4 importlib-metadata==6.0.0 iniconfig==2.0.0 mypy==0.991 -mypy-extensions==0.4.3 +mypy-extensions==1.0.0 outcome==1.2.0 packaging==23.0 pluggy==1.0.0 From 292bcb54cc6f06e60ba55ef505255daa10da07aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Feb 2023 16:27:13 +0100 Subject: [PATCH 28/47] Build(deps): Bump zipp from 3.12.0 to 3.12.1 in /dependencies/default (#494) Bumps [zipp](https://github.com/jaraco/zipp) from 3.12.0 to 3.12.1. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.12.0...v3.12.1) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 84b85148..ec3ce567 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -21,4 +21,4 @@ tomli==2.0.1 trio==0.22.0 typed-ast==1.5.4 typing_extensions==4.4.0 -zipp==3.12.0 +zipp==3.12.1 From ca8b890f55b6d447ee30758c1331c8109ec67a46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Feb 2023 16:27:22 +0100 Subject: [PATCH 29/47] Build(deps): Bump hypothesis in /dependencies/default (#493) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.65.2 to 6.67.1. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.65.2...hypothesis-python-6.67.1) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index ec3ce567..75c1cc62 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -3,7 +3,7 @@ attrs==22.2.0 coverage==7.1.0 exceptiongroup==1.1.0 flaky==3.7.0 -hypothesis==6.65.2 +hypothesis==6.67.1 idna==3.4 importlib-metadata==6.0.0 iniconfig==2.0.0 From d6970880a2c7f69151b292a923d7880a1e75a9ce Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Thu, 9 Feb 2023 16:27:31 +0100 Subject: [PATCH 30/47] Emit ResourceWarning on event_loop teardown when loop is unclosed (#492) * [tests] Run tests for event loop policy inside Pytester to avoid pollution of other tests with a custom event loop. Signed-off-by: Michael Seifert * [tests] test_async_fixtures_scope closes the event loop on fixture teardown Signed-off-by: Michael Seifert * [refactor] Substituted use of pytest_fixture_post_finalizer hook with fixture finalizer. The fixture finalizer is invoked once for each fixture, whereas the hook may be invoked multiple times for any specific fixture. Signed-off-by: Michael Seifert * [refactor] Replaced use of the testdir fixture with pytester in hypothesis/test_base Signed-off-by: Michael Seifert * [refactor] Isolate module-scoped event loop fixture in hypothesis/test_base using pytester. Signed-off-by: Michael Seifert * [feat] Emit ResourceWarning when event_loop is torn down and the current event loop has not been closed. Signed-off-by: Michael Seifert * [refactor] Split up event_loop fixture finalizer into a finalizer for closing the loop and a finalizer for providing a new loop. Signed-off-by: Michael Seifert * [refactor] Created convenience function to add multiple finalizers to a single fixture. Signed-off-by: Michael Seifert * [refactor] Created convenience function to add multiple finalizers to a single fixture. Signed-off-by: Michael Seifert --------- Signed-off-by: Michael Seifert --- docs/source/reference/changelog.rst | 1 + pytest_asyncio/plugin.py | 93 +++++++++++++------ .../test_async_fixtures_scope.py | 4 +- tests/hypothesis/test_base.py | 55 +++++++---- tests/respect_event_loop_policy/conftest.py | 16 ---- .../test_respects_event_loop_policy.py | 17 ---- tests/test_event_loop_fixture.py | 53 +++++++++++ tests/test_event_loop_fixture_finalizer.py | 28 ++++++ 8 files changed, 186 insertions(+), 81 deletions(-) delete mode 100644 tests/respect_event_loop_policy/conftest.py delete mode 100644 tests/respect_event_loop_policy/test_respects_event_loop_policy.py create mode 100644 tests/test_event_loop_fixture.py diff --git a/docs/source/reference/changelog.rst b/docs/source/reference/changelog.rst index af4eb7bf..851bbea0 100644 --- a/docs/source/reference/changelog.rst +++ b/docs/source/reference/changelog.rst @@ -5,6 +5,7 @@ Changelog UNRELEASED ================= - Drop compatibility with pytest 6.1. Pytest-asyncio now depends on pytest 7.0 or newer. +- event_loop fixture teardown emits a ResourceWarning when the current event loop has not been closed. 0.20.3 (22-12-08) ================= diff --git a/pytest_asyncio/plugin.py b/pytest_asyncio/plugin.py index 21809b6d..0b6fa9db 100644 --- a/pytest_asyncio/plugin.py +++ b/pytest_asyncio/plugin.py @@ -7,6 +7,7 @@ import socket import sys import warnings +from textwrap import dedent from typing import ( Any, AsyncIterator, @@ -370,39 +371,22 @@ def _hypothesis_test_wraps_coroutine(function: Any) -> bool: return _is_coroutine(function.hypothesis.inner_test) -@pytest.hookimpl(trylast=True) -def pytest_fixture_post_finalizer(fixturedef: FixtureDef, request: SubRequest) -> None: - """ - Called after fixture teardown. - - Note that this function may be called multiple times for any specific fixture. - see https://github.com/pytest-dev/pytest/issues/5848 - """ - if fixturedef.argname == "event_loop": - policy = asyncio.get_event_loop_policy() - try: - loop = policy.get_event_loop() - except RuntimeError: - loop = None - if loop is not None: - # Clean up existing loop to avoid ResourceWarnings - loop.close() - # At this point, the event loop for the current thread is closed. - # When a user calls asyncio.get_event_loop(), they will get a closed loop. - # In order to avoid this side effect from pytest-asyncio, we need to replace - # the current loop with a fresh one. - # Note that we cannot set the loop to None, because get_event_loop only creates - # a new loop, when set_event_loop has not been called. - new_loop = policy.new_event_loop() - policy.set_event_loop(new_loop) - - @pytest.hookimpl(hookwrapper=True) def pytest_fixture_setup( fixturedef: FixtureDef, request: SubRequest ) -> Optional[object]: """Adjust the event loop policy when an event loop is produced.""" if fixturedef.argname == "event_loop": + # The use of a fixture finalizer is preferred over the + # pytest_fixture_post_finalizer hook. The fixture finalizer is invoked once + # for each fixture, whereas the hook may be invoked multiple times for + # any specific fixture. + # see https://github.com/pytest-dev/pytest/issues/5848 + _add_finalizers( + fixturedef, + _close_event_loop, + _provide_clean_event_loop, + ) outcome = yield loop = outcome.get_result() policy = asyncio.get_event_loop_policy() @@ -421,6 +405,61 @@ def pytest_fixture_setup( yield +def _add_finalizers(fixturedef: FixtureDef, *finalizers: Callable[[], object]) -> None: + """ + Regsiters the specified fixture finalizers in the fixture. + + Finalizers need to specified in the exact order in which they should be invoked. + + :param fixturedef: Fixture definition which finalizers should be added to + :param finalizers: Finalizers to be added + """ + for finalizer in reversed(finalizers): + fixturedef.addfinalizer(finalizer) + + +_UNCLOSED_EVENT_LOOP_WARNING = dedent( + """\ + unclosed event loop %r. + Possible causes are: + 1. A custom "event_loop" fixture is used which doesn't close the loop + 2. Your code or one of your dependencies created a new event loop during + the test run + """ +) + + +def _close_event_loop() -> None: + policy = asyncio.get_event_loop_policy() + try: + loop = policy.get_event_loop() + except RuntimeError: + loop = None + if loop is not None: + # Emit ResourceWarnings in the context of the fixture/test case + # rather than waiting for the interpreter to trigger the warning when + # garbage collecting the event loop. + if not loop.is_closed(): + warnings.warn( + _UNCLOSED_EVENT_LOOP_WARNING % loop, + ResourceWarning, + source=loop, + ) + loop.close() + + +def _provide_clean_event_loop() -> None: + # At this point, the event loop for the current thread is closed. + # When a user calls asyncio.get_event_loop(), they will get a closed loop. + # In order to avoid this side effect from pytest-asyncio, we need to replace + # the current loop with a fresh one. + # Note that we cannot set the loop to None, because get_event_loop only creates + # a new loop, when set_event_loop has not been called. + policy = asyncio.get_event_loop_policy() + new_loop = policy.new_event_loop() + policy.set_event_loop(new_loop) + + @pytest.hookimpl(tryfirst=True, hookwrapper=True) def pytest_pyfunc_call(pyfuncitem: pytest.Function) -> Optional[object]: """ diff --git a/tests/async_fixtures/test_async_fixtures_scope.py b/tests/async_fixtures/test_async_fixtures_scope.py index b150f8a8..079a981a 100644 --- a/tests/async_fixtures/test_async_fixtures_scope.py +++ b/tests/async_fixtures/test_async_fixtures_scope.py @@ -10,7 +10,9 @@ @pytest.fixture(scope="module") def event_loop(): """A module-scoped event loop.""" - return asyncio.new_event_loop() + loop = asyncio.new_event_loop() + yield loop + loop.close() @pytest.fixture(scope="module") diff --git a/tests/hypothesis/test_base.py b/tests/hypothesis/test_base.py index e6da3427..aef20d79 100644 --- a/tests/hypothesis/test_base.py +++ b/tests/hypothesis/test_base.py @@ -1,18 +1,11 @@ """Tests for the Hypothesis integration, which wraps async functions in a sync shim for Hypothesis. """ -import asyncio from textwrap import dedent import pytest from hypothesis import given, strategies as st - - -@pytest.fixture(scope="module") -def event_loop(): - loop = asyncio.get_event_loop_policy().new_event_loop() - yield loop - loop.close() +from pytest import Pytester @given(st.integers()) @@ -35,16 +28,38 @@ async def test_mark_and_parametrize(x, y): assert y in (1, 2) -@given(st.integers()) -@pytest.mark.asyncio -async def test_can_use_fixture_provided_event_loop(event_loop, n): - semaphore = asyncio.Semaphore(value=0) - event_loop.call_soon(semaphore.release) - await semaphore.acquire() +def test_can_use_explicit_event_loop_fixture(pytester: Pytester): + pytester.makepyfile( + dedent( + """\ + import asyncio + import pytest + from hypothesis import given + import hypothesis.strategies as st + + pytest_plugins = 'pytest_asyncio' + + @pytest.fixture(scope="module") + def event_loop(): + loop = asyncio.get_event_loop_policy().new_event_loop() + yield loop + loop.close() + + @given(st.integers()) + @pytest.mark.asyncio + async def test_explicit_fixture_request(event_loop, n): + semaphore = asyncio.Semaphore(value=0) + event_loop.call_soon(semaphore.release) + await semaphore.acquire() + """ + ) + ) + result = pytester.runpytest("--asyncio-mode=strict") + result.assert_outcomes(passed=1) -def test_async_auto_marked(testdir): - testdir.makepyfile( +def test_async_auto_marked(pytester: Pytester): + pytester.makepyfile( dedent( """\ import asyncio @@ -60,13 +75,13 @@ async def test_hypothesis(n: int): """ ) ) - result = testdir.runpytest("--asyncio-mode=auto") + result = pytester.runpytest("--asyncio-mode=auto") result.assert_outcomes(passed=1) -def test_sync_not_auto_marked(testdir): +def test_sync_not_auto_marked(pytester: Pytester): """Assert that synchronous Hypothesis functions are not marked with asyncio""" - testdir.makepyfile( + pytester.makepyfile( dedent( """\ import asyncio @@ -84,5 +99,5 @@ def test_hypothesis(request, n: int): """ ) ) - result = testdir.runpytest("--asyncio-mode=auto") + result = pytester.runpytest("--asyncio-mode=auto") result.assert_outcomes(passed=1) diff --git a/tests/respect_event_loop_policy/conftest.py b/tests/respect_event_loop_policy/conftest.py deleted file mode 100644 index 2c5cef24..00000000 --- a/tests/respect_event_loop_policy/conftest.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Defines and sets a custom event loop policy""" -import asyncio -from asyncio import DefaultEventLoopPolicy, SelectorEventLoop - - -class TestEventLoop(SelectorEventLoop): - pass - - -class TestEventLoopPolicy(DefaultEventLoopPolicy): - def new_event_loop(self): - return TestEventLoop() - - -# This statement represents a code which sets a custom event loop policy -asyncio.set_event_loop_policy(TestEventLoopPolicy()) diff --git a/tests/respect_event_loop_policy/test_respects_event_loop_policy.py b/tests/respect_event_loop_policy/test_respects_event_loop_policy.py deleted file mode 100644 index 610b3388..00000000 --- a/tests/respect_event_loop_policy/test_respects_event_loop_policy.py +++ /dev/null @@ -1,17 +0,0 @@ -"""Tests that any externally provided event loop policy remains unaltered.""" -import asyncio - -import pytest - - -@pytest.mark.asyncio -async def test_uses_loop_provided_by_custom_policy(): - """Asserts that test cases use the event loop - provided by the custom event loop policy""" - assert type(asyncio.get_event_loop()).__name__ == "TestEventLoop" - - -@pytest.mark.asyncio -async def test_custom_policy_is_not_overwritten(): - """Asserts that any custom event loop policy stays the same across test cases""" - assert type(asyncio.get_event_loop()).__name__ == "TestEventLoop" diff --git a/tests/test_event_loop_fixture.py b/tests/test_event_loop_fixture.py new file mode 100644 index 00000000..aaf591c9 --- /dev/null +++ b/tests/test_event_loop_fixture.py @@ -0,0 +1,53 @@ +from textwrap import dedent + +from pytest import Pytester + + +def test_event_loop_fixture_respects_event_loop_policy(pytester: Pytester): + pytester.makeconftest( + dedent( + """\ + '''Defines and sets a custom event loop policy''' + import asyncio + from asyncio import DefaultEventLoopPolicy, SelectorEventLoop + + class TestEventLoop(SelectorEventLoop): + pass + + class TestEventLoopPolicy(DefaultEventLoopPolicy): + def new_event_loop(self): + return TestEventLoop() + + # This statement represents a code which sets a custom event loop policy + asyncio.set_event_loop_policy(TestEventLoopPolicy()) + """ + ) + ) + pytester.makepyfile( + dedent( + """\ + '''Tests that any externally provided event loop policy remains unaltered''' + import asyncio + + import pytest + + + @pytest.mark.asyncio + async def test_uses_loop_provided_by_custom_policy(): + '''Asserts that test cases use the event loop + provided by the custom event loop policy''' + assert type(asyncio.get_event_loop()).__name__ == "TestEventLoop" + + + @pytest.mark.asyncio + async def test_custom_policy_is_not_overwritten(): + ''' + Asserts that any custom event loop policy stays the same + across test cases. + ''' + assert type(asyncio.get_event_loop()).__name__ == "TestEventLoop" + """ + ) + ) + result = pytester.runpytest_subprocess("--asyncio-mode=strict") + result.assert_outcomes(passed=2) diff --git a/tests/test_event_loop_fixture_finalizer.py b/tests/test_event_loop_fixture_finalizer.py index d3622a08..2d12f7f4 100644 --- a/tests/test_event_loop_fixture_finalizer.py +++ b/tests/test_event_loop_fixture_finalizer.py @@ -86,3 +86,31 @@ async def test_async_with_explicit_fixture_request(event_loop): ) result = pytester.runpytest("--asyncio-mode=strict") result.assert_outcomes(passed=1) + + +def test_event_loop_fixture_finalizer_raises_warning_when_loop_is_unclosed( + pytester: Pytester, +): + pytester.makepyfile( + dedent( + """\ + import asyncio + import pytest + import pytest_asyncio + + pytest_plugins = 'pytest_asyncio' + + @pytest.fixture + def event_loop(): + loop = asyncio.get_event_loop_policy().new_event_loop() + yield loop + + @pytest.mark.asyncio + async def test_ends_with_unclosed_loop(): + pass + """ + ) + ) + result = pytester.runpytest("--asyncio-mode=strict", "-W", "default") + result.assert_outcomes(passed=1, warnings=1) + result.stdout.fnmatch_lines("*unclosed event loop*") From 37aec4db3b77d0e3abdc33babea4a4900492314c Mon Sep 17 00:00:00 2001 From: David Greaves Date: Mon, 13 Feb 2023 13:49:27 +0000 Subject: [PATCH 31/47] Add documentation link after migration to docs (#496) The README doesn't provide an easy way to find the docs :) --- README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 81984e88..9eba8d23 100644 --- a/README.rst +++ b/README.rst @@ -13,7 +13,7 @@ pytest-asyncio .. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/ambv/black -pytest-asyncio is a `pytest `_ plugin. It facilitates testing of code that uses the `asyncio `_ library. +`pytest-asyncio `_ is a `pytest `_ plugin. It facilitates testing of code that uses the `asyncio `_ library. Specifically, pytest-asyncio provides support for coroutines as test functions. This allows users to *await* code inside their tests. For example, the following code is executed as a test item by pytest: @@ -24,6 +24,7 @@ Specifically, pytest-asyncio provides support for coroutines as test functions. res = await library.do_something() assert b"expected result" == res +More details can be found in the `documentation `_. Note that test classes subclassing the standard `unittest `__ library are not supported. Users are advised to use `unittest.IsolatedAsyncioTestCase `__ From 91bb8ccaf52211e0916a87db26594b826bf195b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Feb 2023 17:21:18 +0100 Subject: [PATCH 32/47] Build(deps): Bump hypothesis in /dependencies/default (#497) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.67.1 to 6.68.1. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.67.1...hypothesis-python-6.68.1) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 75c1cc62..9cffc064 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -3,7 +3,7 @@ attrs==22.2.0 coverage==7.1.0 exceptiongroup==1.1.0 flaky==3.7.0 -hypothesis==6.67.1 +hypothesis==6.68.1 idna==3.4 importlib-metadata==6.0.0 iniconfig==2.0.0 From f5d1cdca092abec0a36f5e1b0f56dbc0b60d0ceb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Feb 2023 17:21:34 +0100 Subject: [PATCH 33/47] Build(deps): Bump zipp from 3.12.1 to 3.13.0 in /dependencies/default (#498) Bumps [zipp](https://github.com/jaraco/zipp) from 3.12.1 to 3.13.0. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.12.1...v3.13.0) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 9cffc064..d162e222 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -21,4 +21,4 @@ tomli==2.0.1 trio==0.22.0 typed-ast==1.5.4 typing_extensions==4.4.0 -zipp==3.12.1 +zipp==3.13.0 From 88e489a1b440a16af64cbadb500f279d0d0b45e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Feb 2023 17:21:59 +0100 Subject: [PATCH 34/47] Build(deps): Bump mypy from 0.991 to 1.0.0 in /dependencies/default (#499) Bumps [mypy](https://github.com/python/mypy) from 0.991 to 1.0.0. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v0.991...v1.0.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index d162e222..0b8f8b23 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -7,7 +7,7 @@ hypothesis==6.68.1 idna==3.4 importlib-metadata==6.0.0 iniconfig==2.0.0 -mypy==0.991 +mypy==1.0.0 mypy-extensions==1.0.0 outcome==1.2.0 packaging==23.0 From e0d087df82bba15ab6b537425274468b26f7fca8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Feb 2023 07:48:00 +0100 Subject: [PATCH 35/47] Build(deps): Bump typing-extensions in /dependencies/default (#503) Bumps [typing-extensions](https://github.com/python/typing_extensions) from 4.4.0 to 4.5.0. - [Release notes](https://github.com/python/typing_extensions/releases) - [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) - [Commits](https://github.com/python/typing_extensions/compare/4.4.0...4.5.0) --- updated-dependencies: - dependency-name: typing-extensions dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 0b8f8b23..fcf0d8ff 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -20,5 +20,5 @@ sortedcontainers==2.4.0 tomli==2.0.1 trio==0.22.0 typed-ast==1.5.4 -typing_extensions==4.4.0 +typing_extensions==4.5.0 zipp==3.13.0 From 48f6378159eda259f60d4e8002ad81e2837a67c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Feb 2023 07:48:16 +0100 Subject: [PATCH 36/47] Build(deps): Bump hypothesis in /dependencies/default (#502) Bumps [hypothesis](https://github.com/HypothesisWorks/hypothesis) from 6.68.1 to 6.68.2. - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.68.1...hypothesis-python-6.68.2) --- updated-dependencies: - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index fcf0d8ff..6a12ed7a 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -3,7 +3,7 @@ attrs==22.2.0 coverage==7.1.0 exceptiongroup==1.1.0 flaky==3.7.0 -hypothesis==6.68.1 +hypothesis==6.68.2 idna==3.4 importlib-metadata==6.0.0 iniconfig==2.0.0 From 6211c173b09e0c2b93b9a43020f68b9ec2027f04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Feb 2023 07:49:23 +0100 Subject: [PATCH 37/47] Build(deps): Bump mypy from 1.0.0 to 1.0.1 in /dependencies/default (#500) Bumps [mypy](https://github.com/python/mypy) from 1.0.0 to 1.0.1. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v1.0.0...v1.0.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 6a12ed7a..8f9b68cb 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -7,7 +7,7 @@ hypothesis==6.68.2 idna==3.4 importlib-metadata==6.0.0 iniconfig==2.0.0 -mypy==1.0.0 +mypy==1.0.1 mypy-extensions==1.0.0 outcome==1.2.0 packaging==23.0 From 254bd8542c058fc5432ed40be5a4ecd590d44dcd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Feb 2023 07:50:39 +0100 Subject: [PATCH 38/47] Build(deps): Bump zipp from 3.13.0 to 3.15.0 in /dependencies/default (#504) Bumps [zipp](https://github.com/jaraco/zipp) from 3.13.0 to 3.15.0. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/CHANGES.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.13.0...v3.15.0) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 8f9b68cb..15ef2cb0 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -21,4 +21,4 @@ tomli==2.0.1 trio==0.22.0 typed-ast==1.5.4 typing_extensions==4.5.0 -zipp==3.13.0 +zipp==3.15.0 From 1dfb3b7ee1499218b2b721550ea5fca90702baae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 15:51:39 +0100 Subject: [PATCH 39/47] Build(deps): Bump coverage from 7.1.0 to 7.2.1 in /dependencies/default (#505) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.1.0 to 7.2.1. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.1.0...7.2.1) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 15ef2cb0..a8ae6708 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -1,6 +1,6 @@ async-generator==1.10 attrs==22.2.0 -coverage==7.1.0 +coverage==7.2.1 exceptiongroup==1.1.0 flaky==3.7.0 hypothesis==6.68.2 From 3d63056d46b596fd0ea5fc785f2d602eebe4b8d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 15:54:39 +0100 Subject: [PATCH 40/47] Build(deps): Bump pytest from 7.2.1 to 7.2.2 in /dependencies/default (#506) Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.2.1 to 7.2.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.2.1...7.2.2) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index a8ae6708..6054a09d 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -13,7 +13,7 @@ outcome==1.2.0 packaging==23.0 pluggy==1.0.0 pyparsing==3.0.9 -pytest==7.2.1 +pytest==7.2.2 pytest-trio==0.8.0 sniffio==1.3.0 sortedcontainers==2.4.0 From 108b322dfa4b2876485b0676d834c468b03e125f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 15:56:07 +0100 Subject: [PATCH 41/47] Build(deps): Bump exceptiongroup in /dependencies/default (#508) Bumps [exceptiongroup](https://github.com/agronholm/exceptiongroup) from 1.1.0 to 1.1.1. - [Release notes](https://github.com/agronholm/exceptiongroup/releases) - [Changelog](https://github.com/agronholm/exceptiongroup/blob/main/CHANGES.rst) - [Commits](https://github.com/agronholm/exceptiongroup/compare/1.1.0...1.1.1) --- updated-dependencies: - dependency-name: exceptiongroup dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 6054a09d..76e437c1 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -1,7 +1,7 @@ async-generator==1.10 attrs==22.2.0 coverage==7.2.1 -exceptiongroup==1.1.0 +exceptiongroup==1.1.1 flaky==3.7.0 hypothesis==6.68.2 idna==3.4 From 455d94540d4d2b6752b03ae882445b55bd87096e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 15:58:29 +0100 Subject: [PATCH 42/47] Build(deps): Bump mypy from 1.0.1 to 1.1.1 in /dependencies/default (#507) Bumps [mypy](https://github.com/python/mypy) from 1.0.1 to 1.1.1. - [Release notes](https://github.com/python/mypy/releases) - [Commits](https://github.com/python/mypy/compare/v1.0.1...v1.1.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dependencies/default/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies/default/constraints.txt b/dependencies/default/constraints.txt index 76e437c1..11d6bd3d 100644 --- a/dependencies/default/constraints.txt +++ b/dependencies/default/constraints.txt @@ -7,7 +7,7 @@ hypothesis==6.68.2 idna==3.4 importlib-metadata==6.0.0 iniconfig==2.0.0 -mypy==1.0.1 +mypy==1.1.1 mypy-extensions==1.0.0 outcome==1.2.0 packaging==23.0 From f51948e4781a80a4d1242497c211353a7df889a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 15:59:57 +0100 Subject: [PATCH 43/47] Build(deps): Bump pypa/gh-action-pypi-publish from 1.6.4 to 1.7.1 (#509) Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.6.4 to 1.7.1. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.6.4...v1.7.1) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index da8dd51a..72a84102 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -140,7 +140,7 @@ jobs: run: | pandoc -s -o README.md README.rst - name: PyPI upload - uses: pypa/gh-action-pypi-publish@v1.6.4 + uses: pypa/gh-action-pypi-publish@v1.7.1 with: packages_dir: dist password: ${{ secrets.PYPI_API_TOKEN }} From e1cc62d3956f76f5d816d25a362092d4d29550c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Mar 2023 07:46:48 +0100 Subject: [PATCH 44/47] Build(deps): Bump pypa/gh-action-pypi-publish from 1.7.1 to 1.8.1 (#513) Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.7.1 to 1.8.1. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.7.1...v1.8.1) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 72a84102..01c7ca12 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -140,7 +140,7 @@ jobs: run: | pandoc -s -o README.md README.rst - name: PyPI upload - uses: pypa/gh-action-pypi-publish@v1.7.1 + uses: pypa/gh-action-pypi-publish@v1.8.1 with: packages_dir: dist password: ${{ secrets.PYPI_API_TOKEN }} From 947e31acf9747158b44b682ad4498b2bd3c98c05 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Sun, 19 Mar 2023 09:34:49 +0100 Subject: [PATCH 45/47] Deprecate closing of existing loops (#510) * [docs] Corrected comment on when a RuntimeError occurs upon calling get_event_loop. Signed-off-by: Michael Seifert * [refactor] Turn ResourceWarning for unclosed event loops into a DeprecationWarning. Changing the warning type emphasizes that the functionality will no longer be available in the future. The commit also extends the tests for the deprecation warning and adjusts the changlog entry and deprecation message. Signed-off-by: Michael Seifert --------- Signed-off-by: Michael Seifert --- docs/source/reference/changelog.rst | 5 ++++- pytest_asyncio/plugin.py | 22 +++++++++---------- tests/test_event_loop_fixture_finalizer.py | 25 ++++++++++++++++++++-- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/docs/source/reference/changelog.rst b/docs/source/reference/changelog.rst index 851bbea0..ec681a24 100644 --- a/docs/source/reference/changelog.rst +++ b/docs/source/reference/changelog.rst @@ -5,7 +5,10 @@ Changelog UNRELEASED ================= - Drop compatibility with pytest 6.1. Pytest-asyncio now depends on pytest 7.0 or newer. -- event_loop fixture teardown emits a ResourceWarning when the current event loop has not been closed. +- pytest-asyncio cleans up any stale event loops when setting up and tearing down the + event_loop fixture. This behavior has been deprecated and pytest-asyncio emits a + DeprecationWarning when tearing down the event_loop fixture and current event loop + has not been closed. 0.20.3 (22-12-08) ================= diff --git a/pytest_asyncio/plugin.py b/pytest_asyncio/plugin.py index 0b6fa9db..c0aa4261 100644 --- a/pytest_asyncio/plugin.py +++ b/pytest_asyncio/plugin.py @@ -397,7 +397,9 @@ def pytest_fixture_setup( if old_loop is not loop: old_loop.close() except RuntimeError: - # Swallow this, since it's probably bad event loop hygiene. + # Either the current event loop has been set to None + # or the loop policy doesn't specify to create new loops + # or we're not in the main thread pass policy.set_event_loop(loop) return @@ -420,11 +422,13 @@ def _add_finalizers(fixturedef: FixtureDef, *finalizers: Callable[[], object]) - _UNCLOSED_EVENT_LOOP_WARNING = dedent( """\ - unclosed event loop %r. - Possible causes are: - 1. A custom "event_loop" fixture is used which doesn't close the loop - 2. Your code or one of your dependencies created a new event loop during - the test run + pytest-asyncio detected an unclosed event loop when tearing down the event_loop + fixture: %r + pytest-asyncio will close the event loop for you, but future versions of the + library will no longer do so. In order to ensure compatibility with future + versions, please make sure that: + 1. Any custom "event_loop" fixture properly closes the loop after yielding it + 2. Your code does not modify the event loop in async fixtures or tests """ ) @@ -436,14 +440,10 @@ def _close_event_loop() -> None: except RuntimeError: loop = None if loop is not None: - # Emit ResourceWarnings in the context of the fixture/test case - # rather than waiting for the interpreter to trigger the warning when - # garbage collecting the event loop. if not loop.is_closed(): warnings.warn( _UNCLOSED_EVENT_LOOP_WARNING % loop, - ResourceWarning, - source=loop, + DeprecationWarning, ) loop.close() diff --git a/tests/test_event_loop_fixture_finalizer.py b/tests/test_event_loop_fixture_finalizer.py index 2d12f7f4..b676df2d 100644 --- a/tests/test_event_loop_fixture_finalizer.py +++ b/tests/test_event_loop_fixture_finalizer.py @@ -88,7 +88,7 @@ async def test_async_with_explicit_fixture_request(event_loop): result.assert_outcomes(passed=1) -def test_event_loop_fixture_finalizer_raises_warning_when_loop_is_unclosed( +def test_event_loop_fixture_finalizer_raises_warning_when_fixture_leaves_loop_unclosed( pytester: Pytester, ): pytester.makepyfile( @@ -96,7 +96,6 @@ def test_event_loop_fixture_finalizer_raises_warning_when_loop_is_unclosed( """\ import asyncio import pytest - import pytest_asyncio pytest_plugins = 'pytest_asyncio' @@ -114,3 +113,25 @@ async def test_ends_with_unclosed_loop(): result = pytester.runpytest("--asyncio-mode=strict", "-W", "default") result.assert_outcomes(passed=1, warnings=1) result.stdout.fnmatch_lines("*unclosed event loop*") + + +def test_event_loop_fixture_finalizer_raises_warning_when_test_leaves_loop_unclosed( + pytester: Pytester, +): + pytester.makepyfile( + dedent( + """\ + import asyncio + import pytest + + pytest_plugins = 'pytest_asyncio' + + @pytest.mark.asyncio + async def test_ends_with_unclosed_loop(): + asyncio.set_event_loop(asyncio.new_event_loop()) + """ + ) + ) + result = pytester.runpytest("--asyncio-mode=strict", "-W", "default") + result.assert_outcomes(passed=1, warnings=1) + result.stdout.fnmatch_lines("*unclosed event loop*") From 46b8f9e3f1d0ff5fc7f9bcf07f38252668516ba8 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Sun, 19 Mar 2023 11:05:51 +0100 Subject: [PATCH 46/47] [build] Tests are run against Python 3.12 (dev). (#514) This should make any incompatibilities visible earlier. This, in turn, gives pytest-asyncio more time to adjust and react. Signed-off-by: Michael Seifert --- .github/workflows/main.yml | 7 ++++++- tox.ini | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 01c7ca12..a4e8580c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -60,11 +60,16 @@ jobs: strategy: matrix: - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', 3.12-dev] steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 + if: "!endsWith(matrix.python-version, '-dev')" + with: + python-version: ${{ matrix.python-version }} + - uses: deadsnakes/action@v3.0.0 + if: endsWith(matrix.python-version, '-dev') with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/tox.ini b/tox.ini index ceaccb39..4987355b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] minversion = 3.14.0 -envlist = py37, py38, py39, py310, py311, pytest-min +envlist = py37, py38, py39, py310, py311, py312, pytest-min isolated_build = true passenv = CI @@ -30,4 +30,5 @@ python = 3.9: py39 3.10: py310 3.11: py311 + 3.12: py312 pypy3: pypy3 From 75dcceafcea94b8c286b8cba1b00ddec2593261f Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Sun, 19 Mar 2023 11:07:34 +0100 Subject: [PATCH 47/47] [docs] Prepare v0.21.0. Signed-off-by: Michael Seifert --- docs/source/reference/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/reference/changelog.rst b/docs/source/reference/changelog.rst index ec681a24..06d4f108 100644 --- a/docs/source/reference/changelog.rst +++ b/docs/source/reference/changelog.rst @@ -2,7 +2,7 @@ Changelog ========= -UNRELEASED +0.21.0 (23-03-19) ================= - Drop compatibility with pytest 6.1. Pytest-asyncio now depends on pytest 7.0 or newer. - pytest-asyncio cleans up any stale event loops when setting up and tearing down the