Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-pytest-asyncio for openSUSE:Factory checked in at 2022-12-12 18:59:12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pytest-asyncio (Old) and /work/SRC/openSUSE:Factory/.python-pytest-asyncio.new.1835 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest-asyncio" Mon Dec 12 18:59:12 2022 rev:12 rq:1041848 version:0.20.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pytest-asyncio/python-pytest-asyncio.changes 2022-08-10 17:12:35.113596053 +0200 +++ /work/SRC/openSUSE:Factory/.python-pytest-asyncio.new.1835/python-pytest-asyncio.changes 2022-12-12 18:59:13.659992474 +0100 @@ -1,0 +2,26 @@ +Fri Dec 9 11:11:04 UTC 2022 - Daniel Garcia <daniel.gar...@suse.com> + +- Update to 0.20.3: + * Prevent DeprecationWarning to bubble up on CPython 3.10.9 and 3.11.1. #460 + +------------------------------------------------------------------- +Wed Nov 30 07:13:34 UTC 2022 - Daniel Garcia <daniel.gar...@suse.com> + +- Update to 0.20.2: + * Fixes an issue with async fixtures that are defined as methods on a test + class not being rebound to the actual test instance. #197 + * Replaced usage of deprecated @pytest.mark.tryfirst with + @pytest.hookimpl(tryfirst=True) #438 +- 0.20.1 (22-10-21) + * Fixes an issue that warned about using an old version of pytest, even + though the most recent version was installed. #430 +- 0.20.0 (22-10-21) + * BREAKING: Removed legacy mode. If you're upgrading from v0.19 and you + haven't configured asyncio_mode = legacy, you can upgrade without taking + any additional action. If you're upgrading from an earlier version or you + have explicitly enabled legacy mode, you need to switch to auto or strict + mode before upgrading to this version. + * Deprecate use of pytest v6. + * Fixed an issue which prevented fixture setup from being cached. #404 + +------------------------------------------------------------------- Old: ---- pytest-asyncio-0.19.0.tar.gz New: ---- pytest-asyncio-0.20.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pytest-asyncio.spec ++++++ --- /var/tmp/diff_new_pack.07MExP/_old 2022-12-12 18:59:14.183995425 +0100 +++ /var/tmp/diff_new_pack.07MExP/_new 2022-12-12 18:59:14.187995448 +0100 @@ -1,5 +1,5 @@ # -# spec file for package python-pytest-asyncio +# spec file # # Copyright (c) 2022 SUSE LLC # @@ -25,7 +25,7 @@ %bcond_with test %endif Name: python-pytest-asyncio%{psuffix} -Version: 0.19.0 +Version: 0.20.3 Release: 0 Summary: Pytest support for asyncio License: Apache-2.0 @@ -83,8 +83,8 @@ %files %{python_files} %doc README.rst %license LICENSE -%{python_sitelib}/pytest_asyncio/ -%{python_sitelib}/pytest_asyncio-%{version}*-info/ +%{python_sitelib}/pytest_asyncio +%{python_sitelib}/pytest_asyncio-%{version}*-info %endif %changelog ++++++ pytest-asyncio-0.19.0.tar.gz -> pytest-asyncio-0.20.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/.github/workflows/main.yml new/pytest-asyncio-0.20.3/.github/workflows/main.yml --- old/pytest-asyncio-0.19.0/.github/workflows/main.yml 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/.github/workflows/main.yml 2022-12-08 13:08:38.000000000 +0100 @@ -118,7 +118,7 @@ run: | pandoc -s -o README.md README.rst - name: PyPI upload - uses: pypa/gh-action-pypi-publish@v1.5.0 + uses: pypa/gh-action-pypi-publish@v1.5.2 with: packages_dir: dist password: ${{ secrets.PYPI_API_TOKEN }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/.pre-commit-config.yaml new/pytest-asyncio-0.20.3/.pre-commit-config.yaml --- old/pytest-asyncio-0.19.0/.pre-commit-config.yaml 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/.pre-commit-config.yaml 2022-12-08 13:08:38.000000000 +0100 @@ -1,32 +1,31 @@ --- repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.3.0 hooks: - id: check-merge-conflict exclude: rst$ - repo: https://github.com/asottile/yesqa - rev: v1.3.0 + rev: v1.4.0 hooks: - id: yesqa - repo: https://github.com/Zac-HD/shed - rev: 0.6.0 # 0.7 does not support Python 3.7 + rev: 0.10.7 hooks: - id: shed args: - --refactor - - --py37-plus types_or: - python - markdown - rst - repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt - rev: 0.1.1 + rev: 0.2.2 hooks: - id: yamlfmt args: [--mapping, '2', --sequence, '2', --offset, '0'] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.3.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -37,8 +36,8 @@ - id: check-xml - id: check-yaml - id: debug-statements -- repo: https://gitlab.com/pycqa/flake8 - rev: 3.9.2 +- repo: https://github.com/pycqa/flake8 + rev: 5.0.4 hooks: - id: flake8 language_version: python3 @@ -47,7 +46,7 @@ hooks: - id: python-use-type-annotations - repo: https://github.com/rhysd/actionlint - rev: v1.6.8 + rev: v1.6.22 hooks: - id: actionlint-docker args: @@ -58,7 +57,7 @@ - -ignore - 'SC1004:' - repo: https://github.com/sirosen/check-jsonschema - rev: 0.9.1 + rev: 0.19.2 hooks: - id: check-github-actions ci: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/CHANGELOG.rst new/pytest-asyncio-0.20.3/CHANGELOG.rst --- old/pytest-asyncio-0.19.0/CHANGELOG.rst 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/CHANGELOG.rst 2022-12-08 13:08:38.000000000 +0100 @@ -2,6 +2,26 @@ Changelog ========= +0.20.3 (22-12-08) +================= +- Prevent DeprecationWarning to bubble up on CPython 3.10.9 and 3.11.1. + `#460 <https://github.com/pytest-dev/pytest-asyncio/issues/460>`_ + +0.20.2 (22-11-11) +================= +- Fixes an issue with async fixtures that are defined as methods on a test class not being rebound to the actual test instance. `#197 <https://github.com/pytest-dev/pytest-asyncio/issues/197>`_ +- Replaced usage of deprecated ``@pytest.mark.tryfirst`` with ``@pytest.hookimpl(tryfirst=True)`` `#438 <https://github.com/pytest-dev/pytest-asyncio/pull/438>`_ + +0.20.1 (22-10-21) +================= +- Fixes an issue that warned about using an old version of pytest, even though the most recent version was installed. `#430 <https://github.com/pytest-dev/pytest-asyncio/issues/430>`_ + +0.20.0 (22-10-21) +================= +- BREAKING: Removed *legacy* mode. If you're upgrading from v0.19 and you haven't configured ``asyncio_mode = legacy``, you can upgrade without taking any additional action. If you're upgrading from an earlier version or you have explicitly enabled *legacy* mode, you need to switch to *auto* or *strict* mode before upgrading to this version. +- Deprecate use of pytest v6. +- Fixed an issue which prevented fixture setup from being cached. `#404 <https://github.com/pytest-dev/pytest-asyncio/pull/404>`_ + 0.19.0 (22-07-13) ================= - BREAKING: The default ``asyncio_mode`` is now *strict*. `#293 <https://github.com/pytest-dev/pytest-asyncio/issues/293>`_ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/README.rst new/pytest-asyncio-0.20.3/README.rst --- old/pytest-asyncio-0.19.0/README.rst 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/README.rst 2022-12-08 13:08:38.000000000 +0100 @@ -1,5 +1,5 @@ -pytest-asyncio: pytest support for asyncio -========================================== +pytest-asyncio +============== .. image:: https://img.shields.io/pypi/v/pytest-asyncio.svg :target: https://pypi.python.org/pypi/pytest-asyncio @@ -13,12 +13,9 @@ .. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/ambv/black -pytest-asyncio is an Apache2 licensed library, written in Python, for testing -asyncio code with pytest. +pytest-asyncio is a `pytest <https://docs.pytest.org/en/latest/contents.html>`_ plugin. It facilitates testing of code that uses the `asyncio <https://docs.python.org/3/library/asyncio.html>`_ library. -asyncio code is usually written in the form of coroutines, which makes it -slightly more difficult to test using normal testing tools. pytest-asyncio -provides useful fixtures and markers to make testing easier. +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: .. code-block:: python @@ -27,21 +24,14 @@ res = await library.do_something() assert b"expected result" == res -pytest-asyncio has been strongly influenced by pytest-tornado_. -.. _pytest-tornado: https://github.com/eugeniy/pytest-tornado +Note that test classes subclassing the standard `unittest <https://docs.python.org/3/library/unittest.html>`__ library are not supported. Users +are advised to use `unittest.IsolatedAsyncioTestCase <https://docs.python.org/3/library/unittest.html#unittest.IsolatedAsyncioTestCase>`__ +or an async framework such as `asynctest <https://asynctest.readthedocs.io/en/latest>`__. + -Features --------- +pytest-asyncio is available under the `Apache License 2.0 <https://github.com/pytest-dev/pytest-asyncio/blob/master/LICENSE>`_. -- fixtures for creating and injecting versions of the asyncio event loop -- fixtures for injecting unused tcp/udp ports -- pytest markers for treating tests as asyncio coroutines -- easy testing with non-default event loops -- support for `async def` fixtures and async generator fixtures -- support *auto* mode to handle all async fixtures and tests automatically by asyncio; - provide *strict* mode if a test suite should work with different async frameworks - simultaneously, e.g. ``asyncio`` and ``trio``. Installation ------------ @@ -54,204 +44,6 @@ This is enough for pytest to pick up pytest-asyncio. -Modes ------ - -Starting from ``pytest-asyncio>=0.17``, three modes are provided: *auto*, *strict* and -*legacy*. Starting from ``pytest-asyncio>=0.19`` the *strict* mode is the default. - -The mode can be set by ``asyncio_mode`` configuration option in `configuration file -<https://docs.pytest.org/en/latest/reference/customize.html>`_: - -.. code-block:: ini - - # pytest.ini - [pytest] - asyncio_mode = auto - -The value can be overridden by command-line option for ``pytest`` invocation: - -.. code-block:: bash - - $ pytest tests --asyncio-mode=strict - -Auto mode -~~~~~~~~~ - -When the mode is auto, all discovered *async* tests are considered *asyncio-driven* even -if they have no ``@pytest.mark.asyncio`` marker. - -All async fixtures are considered *asyncio-driven* as well, even if they are decorated -with a regular ``@pytest.fixture`` decorator instead of dedicated -``@pytest_asyncio.fixture`` counterpart. - -*asyncio-driven* means that tests and fixtures are executed by ``pytest-asyncio`` -plugin. - -This mode requires the simplest tests and fixtures configuration and is -recommended for default usage *unless* the same project and its test suite should -execute tests from different async frameworks, e.g. ``asyncio`` and ``trio``. In this -case, auto-handling can break tests designed for other framework; please use *strict* -mode instead. - -Strict mode -~~~~~~~~~~~ - -Strict mode enforces ``@pytest.mark.asyncio`` and ``@pytest_asyncio.fixture`` usage. -Without these markers, tests and fixtures are not considered as *asyncio-driven*, other -pytest plugin can handle them. - -Please use this mode if multiple async frameworks should be combined in the same test -suite. - -This mode is used by default for the sake of project inter-compatibility. - - -Legacy mode -~~~~~~~~~~~ - -This mode follows rules used by ``pytest-asyncio<0.17``: tests are not auto-marked but -fixtures are. - -Deprecation warnings are emitted with suggestion to either switching to ``auto`` mode -or using ``strict`` mode with ``@pytest_asyncio.fixture`` decorators. - -The default was changed to ``strict`` in ``pytest-asyncio>=0.19``. - - -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 <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.get_running_loop>`__. -The event loop is closed when the fixture scope ends. The fixture scope defaults -to ``function`` scope. - -Note that just using the ``event_loop`` fixture won't make your test function -a coroutine. You'll need to interact with the event loop directly, using methods -like ``event_loop.run_until_complete``. See the ``pytest.mark.asyncio`` marker -for treating test functions like coroutines. - -.. 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 - -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`` marker 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`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Work just like their TCP counterparts but return unused UDP ports. - - -Async fixtures -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -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* and *legacy* mode automatically converts async fixtures declared with the -standard ``@pytest.fixture`` decorator to *asyncio-driven* versions. - - -Markers -------- - -``pytest.mark.asyncio`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Mark your test coroutine with this marker and pytest will execute it as an -asyncio task using the event loop provided by the ``event_loop`` fixture. See -the introductory section for an example. - -The event loop used can be overridden by overriding the ``event_loop`` fixture -(see above). - -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 - -Note about unittest -------------------- - -Test classes subclassing the standard `unittest <https://docs.python.org/3/library/unittest.html>`__ library are not supported, users -are recommended to use `unittest.IsolatedAsyncioTestCase <https://docs.python.org/3/library/unittest.html#unittest.IsolatedAsyncioTestCase>`__ -or an async framework such as `asynctest <https://asynctest.readthedocs.io/en/latest>`__. Contributing ------------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/dependencies/default/constraints.txt new/pytest-asyncio-0.20.3/dependencies/default/constraints.txt --- old/pytest-asyncio-0.19.0/dependencies/default/constraints.txt 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/dependencies/default/constraints.txt 2022-12-08 13:08:38.000000000 +0100 @@ -1,24 +1,24 @@ async-generator==1.10 -attrs==21.4.0 -coverage==6.4.1 +attrs==22.1.0 +coverage==6.5.0 +exceptiongroup==1.0.4 flaky==3.7.0 -hypothesis==6.48.3 -idna==3.3 -importlib-metadata==4.12.0 +hypothesis==6.58.1 +idna==3.4 +importlib-metadata==5.1.0 iniconfig==1.1.1 -mypy==0.961 +mypy==0.991 mypy-extensions==0.4.3 outcome==1.2.0 packaging==21.3 pluggy==1.0.0 -py==1.11.0 pyparsing==3.0.9 -pytest==7.1.2 -pytest-trio==0.7.0 -sniffio==1.2.0 +pytest==7.2.0 +pytest-trio==0.8.0 +sniffio==1.3.0 sortedcontainers==2.4.0 tomli==2.0.1 -trio==0.21.0 +trio==0.22.0 typed-ast==1.5.4 -typing_extensions==4.3.0 -zipp==3.8.0 +typing_extensions==4.4.0 +zipp==3.11.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/docs/Makefile new/pytest-asyncio-0.20.3/docs/Makefile --- old/pytest-asyncio-0.19.0/docs/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-asyncio-0.20.3/docs/Makefile 2022-12-08 13:08:38.000000000 +0100 @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/docs/make.bat new/pytest-asyncio-0.20.3/docs/make.bat --- old/pytest-asyncio-0.19.0/docs/make.bat 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-asyncio-0.20.3/docs/make.bat 2022-12-08 13:08:38.000000000 +0100 @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/docs/source/concepts.rst new/pytest-asyncio-0.20.3/docs/source/concepts.rst --- old/pytest-asyncio-0.19.0/docs/source/concepts.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-asyncio-0.20.3/docs/source/concepts.rst 2022-12-08 13:08:38.000000000 +0100 @@ -0,0 +1,38 @@ +======== +Concepts +======== + +asyncio event loops +=================== +pytest-asyncio runs each test item in its own asyncio event loop. The loop can be accessed via the ``event_loop`` fixture, which is automatically requested by all async tests. + +.. code-block:: python + + async def test_provided_loop_is_running_loop(event_loop): + assert event_loop is asyncio.get_running_loop() + +You can think of `event_loop` as an autouse fixture for async tests. + +Test discovery modes +==================== + +Pytest-asyncio provides two modes for test discovery, *strict* and *auto*. + + +Strict mode +----------- + +In strict mode pytest-asyncio will only run tests that have the *asyncio* marker and will only evaluate async fixtures decorated with ``@pytest_asyncio.fixture``. Test functions and fixtures without these markers and decorators will not be handled by pytest-asyncio. + +This mode is intended for projects that want so support multiple asynchronous programming libraries as it allows pytest-asyncio to coexist with other async testing plugins in the same codebase. + +Pytest automatically enables installed plugins. As a result pytest plugins need to coexist peacefully in their default configuration. This is why strict mode is the default mode. + +Auto mode +--------- + +In *auto* mode pytest-asyncio automatically adds the *asyncio* marker to all asynchronous test functions. It will also take ownership of all async fixtures, regardless of whether they are decorated with ``@pytest.fixture`` or ``@pytest_asyncio.fixture``. + +This mode is intended for projects that use *asyncio* as their only asynchronous programming library. Auto mode makes for the simplest test and fixture configuration and is the recommended default. + +If you intend to support multiple asynchronous programming libraries, e.g. *asyncio* and *trio*, strict mode will be the preferred option. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/docs/source/conf.py new/pytest-asyncio-0.20.3/docs/source/conf.py --- old/pytest-asyncio-0.19.0/docs/source/conf.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-asyncio-0.20.3/docs/source/conf.py 2022-12-08 13:08:38.000000000 +0100 @@ -0,0 +1,27 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "pytest-asyncio" +copyright = "2022, pytest-asyncio contributors" +author = "Tin TvrtkoviÄ" +release = "v0.20.1" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [] + +templates_path = ["_templates"] +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "sphinx_rtd_theme" +html_static_path = ["_static"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/docs/source/index.rst new/pytest-asyncio-0.20.3/docs/source/index.rst --- old/pytest-asyncio-0.19.0/docs/source/index.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-asyncio-0.20.3/docs/source/index.rst 2022-12-08 13:08:38.000000000 +0100 @@ -0,0 +1,30 @@ +========================== +Welcome to pytest-asyncio! +========================== + +.. toctree:: + :maxdepth: 1 + :hidden: + + concepts + reference + support + +pytest-asyncio is a `pytest <https://docs.pytest.org/en/latest/contents.html>`_ plugin. It facilitates testing of code that uses the `asyncio <https://docs.python.org/3/library/asyncio.html>`_ 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: + +.. code-block:: python + + @pytest.mark.asyncio + async def test_some_asyncio_code(): + res = await library.do_something() + assert b"expected result" == res + + +Note that test classes subclassing the standard `unittest <https://docs.python.org/3/library/unittest.html>`__ library are not supported. Users +are advised to use `unittest.IsolatedAsyncioTestCase <https://docs.python.org/3/library/unittest.html#unittest.IsolatedAsyncioTestCase>`__ +or an async framework such as `asynctest <https://asynctest.readthedocs.io/en/latest>`__. + + +pytest-asyncio is available under the `Apache License 2.0 <https://github.com/pytest-dev/pytest-asyncio/blob/master/LICENSE>`_. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/docs/source/reference.rst new/pytest-asyncio-0.20.3/docs/source/reference.rst --- old/pytest-asyncio-0.19.0/docs/source/reference.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-asyncio-0.20.3/docs/source/reference.rst 2022-12-08 13:08:38.000000000 +0100 @@ -0,0 +1,145 @@ +========= +Reference +========= + +Configuration +============= + +The pytest-asyncio mode can be set by the ``asyncio_mode`` configuration option in the `configuration file +<https://docs.pytest.org/en/latest/reference/customize.html>`_: + +.. 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 <https://docs.python.org/3/library/asyncio-eventloop.html#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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/docs/source/support.rst new/pytest-asyncio-0.20.3/docs/source/support.rst --- old/pytest-asyncio-0.19.0/docs/source/support.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-asyncio-0.20.3/docs/source/support.rst 2022-12-08 13:08:38.000000000 +0100 @@ -0,0 +1,21 @@ +=============== +Getting support +=============== + +Enterprise support +================== +`Tidelift <https://www.tidelift.com>`_ works with maintainers of numerous open source projects to ensure enterprise-grade support for your software supply chain. + +The Tidelift subscription includes security updates, verified license compliance, continuous software maintenance, and more. As a result, you get the guarantees provided by commercial software for the open source packages you use. + +Consider `signing up for the Tidelift subscription <https://tidelift.com/subscription/pkg/pypi-pytest-asyncio?utm_source=pypi-pytest-asyncio&utm_medium=referral&utm_campaign=enterprise>`__. + + +Direct maintainer support +========================= +If you require commercial support outside of the Tidelift subscription, reach out to `Michael Seifert, <https://seifertm.de>`__ one of the project's maintainers. + + +Community support +================= +The GitHub page of pytest-asyncio offers free community support on a best-effort basis. Please use the `issue tracker <https://github.com/pytest-dev/pytest-asyncio/issues>`__ to report bugs and the `discussions <https://github.com/pytest-dev/pytest-asyncio/discussions>`__ to ask questions. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/pytest_asyncio/plugin.py new/pytest-asyncio-0.20.3/pytest_asyncio/plugin.py --- old/pytest-asyncio-0.19.0/pytest_asyncio/plugin.py 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/pytest_asyncio/plugin.py 2022-12-08 13:08:38.000000000 +0100 @@ -25,6 +25,7 @@ ) import pytest +from pytest import Function, Item, Session if sys.version_info >= (3, 8): from typing import Literal @@ -55,22 +56,6 @@ class Mode(str, enum.Enum): AUTO = "auto" STRICT = "strict" - LEGACY = "legacy" - - -LEGACY_MODE = DeprecationWarning( - "The 'asyncio_mode' default value will change to 'strict' in future, " - "please explicitly use 'asyncio_mode=strict' or 'asyncio_mode=auto' " - "in pytest configuration file." -) - -LEGACY_ASYNCIO_FIXTURE = ( - "'@pytest.fixture' is applied to {name} " - "in 'legacy' mode, " - "please replace it with '@pytest_asyncio.fixture' as a preparation " - "for switching to 'strict' mode (or use 'auto' mode to seamlessly handle " - "all these fixtures as asyncio-driven)." -) ASYNCIO_MODE_HELP = """\ @@ -78,8 +63,6 @@ 'strict' - for autoprocessing disabling (useful if different async frameworks \ should be tested together, e.g. \ both pytest-asyncio and pytest-trio are used in the same project) -'legacy' - for keeping compatibility with pytest-asyncio<0.17: \ -auto-handling is disabled but pytest_asyncio.fixture usage is not enforced """ @@ -106,11 +89,10 @@ scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = ..., params: Optional[Iterable[object]] = ..., autouse: bool = ..., - ids: Optional[ - Union[ - Iterable[Union[None, str, float, int, bool]], - Callable[[Any], Optional[object]], - ] + ids: Union[ + Iterable[Union[str, float, int, bool, None]], + Callable[[Any], Optional[object]], + None, ] = ..., name: Optional[str] = ..., ) -> FixtureFunction: @@ -124,11 +106,10 @@ scope: "Union[_ScopeName, Callable[[str, Config], _ScopeName]]" = ..., params: Optional[Iterable[object]] = ..., autouse: bool = ..., - ids: Optional[ - Union[ - Iterable[Union[None, str, float, int, bool]], - Callable[[Any], Optional[object]], - ] + ids: Union[ + Iterable[Union[str, float, int, bool, None]], + Callable[[Any], Optional[object]], + None, ] = ..., name: Optional[str] = None, ) -> FixtureFunctionMarker: @@ -139,7 +120,7 @@ fixture_function: Optional[FixtureFunction] = None, **kwargs: Any ) -> Union[FixtureFunction, FixtureFunctionMarker]: if fixture_function is not None: - _set_explicit_asyncio_mark(fixture_function) + _make_asyncio_fixture_function(fixture_function) return pytest.fixture(fixture_function, **kwargs) else: @@ -151,12 +132,12 @@ return inner -def _has_explicit_asyncio_mark(obj: Any) -> bool: +def _is_asyncio_fixture_function(obj: Any) -> bool: obj = getattr(obj, "__func__", obj) # instance method maybe? return getattr(obj, "_force_asyncio_fixture", False) -def _set_explicit_asyncio_mark(obj: Any) -> None: +def _make_asyncio_fixture_function(obj: Any) -> None: if hasattr(obj, "__func__"): # instance method, check the function object obj = obj.__func__ @@ -187,66 +168,67 @@ "mark the test as a coroutine, it will be " "run using an asyncio event loop", ) - if _get_asyncio_mode(config) == Mode.LEGACY: - config.issue_config_time_warning(LEGACY_MODE, stacklevel=2) + + 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.mark.tryfirst +@pytest.hookimpl(tryfirst=True) def pytest_report_header(config: Config) -> List[str]: """Add asyncio config to pytest header.""" mode = _get_asyncio_mode(config) return [f"asyncio: mode={mode}"] -def _preprocess_async_fixtures(config: Config, holder: Set[FixtureDef]) -> None: +def _preprocess_async_fixtures( + config: Config, + processed_fixturedefs: Set[FixtureDef], +) -> None: asyncio_mode = _get_asyncio_mode(config) fixturemanager = config.pluginmanager.get_plugin("funcmanage") for fixtures in fixturemanager._arg2fixturedefs.values(): for fixturedef in fixtures: - if fixturedef is holder: - continue func = fixturedef.func - if not _is_coroutine_or_asyncgen(func): - # Nothing to do with a regular fixture function + if fixturedef in processed_fixturedefs or not _is_coroutine_or_asyncgen( + func + ): continue - if not _has_explicit_asyncio_mark(func): - if asyncio_mode == Mode.STRICT: - # Ignore async fixtures without explicit asyncio mark in strict mode - # This applies to pytest_trio fixtures, for example - continue - elif asyncio_mode == Mode.AUTO: - # Enforce asyncio mode if 'auto' - _set_explicit_asyncio_mark(func) - elif asyncio_mode == Mode.LEGACY: - _set_explicit_asyncio_mark(func) - try: - code = func.__code__ - except AttributeError: - code = func.__func__.__code__ - name = ( - f"<fixture {func.__qualname__}, file={code.co_filename}, " - f"line={code.co_firstlineno}>" - ) - warnings.warn( - LEGACY_ASYNCIO_FIXTURE.format(name=name), - DeprecationWarning, - ) - - to_add = [] - for name in ("request", "event_loop"): - if name not in fixturedef.argnames: - to_add.append(name) - - if to_add: - fixturedef.argnames += tuple(to_add) - - if inspect.isasyncgenfunction(func): - fixturedef.func = _wrap_asyncgen(func) - elif inspect.iscoroutinefunction(func): - fixturedef.func = _wrap_async(func) - - assert _has_explicit_asyncio_mark(fixturedef.func) - holder.add(fixturedef) + if not _is_asyncio_fixture_function(func) and asyncio_mode == Mode.STRICT: + # Ignore async fixtures without explicit asyncio mark in strict mode + # This applies to pytest_trio fixtures, for example + continue + _make_asyncio_fixture_function(func) + _inject_fixture_argnames(fixturedef) + _synchronize_async_fixture(fixturedef) + assert _is_asyncio_fixture_function(fixturedef.func) + processed_fixturedefs.add(fixturedef) + + +def _inject_fixture_argnames(fixturedef: FixtureDef) -> None: + """ + Ensures that `request` and `event_loop` are arguments of the specified fixture. + """ + to_add = [] + for name in ("request", "event_loop"): + if name not in fixturedef.argnames: + to_add.append(name) + if to_add: + fixturedef.argnames += tuple(to_add) + + +def _synchronize_async_fixture(fixturedef: FixtureDef) -> None: + """ + Wraps the fixture function of an async fixture in a synchronous function. + """ + if inspect.isasyncgenfunction(fixturedef.func): + _wrap_asyncgen_fixture(fixturedef) + elif inspect.iscoroutinefunction(fixturedef.func): + _wrap_async_fixture(fixturedef) def _add_kwargs( @@ -264,14 +246,38 @@ return ret -def _wrap_asyncgen(func: Callable[..., AsyncIterator[_R]]) -> Callable[..., _R]: - @functools.wraps(func) +def _perhaps_rebind_fixture_func( + func: _T, instance: Optional[Any], unittest: bool +) -> _T: + if instance is not None: + # The fixture needs to be bound to the actual request.instance + # so it is bound to the same object as the test method. + unbound, cls = func, None + try: + unbound, cls = func.__func__, type(func.__self__) # type: ignore + except AttributeError: + pass + # If unittest is true, the fixture is bound unconditionally. + # otherwise, only if the fixture was bound before to an instance of + # the same type. + if unittest or (cls is not None and isinstance(instance, cls)): + func = unbound.__get__(instance) # type: ignore + return func + + +def _wrap_asyncgen_fixture(fixturedef: FixtureDef) -> None: + fixture = fixturedef.func + + @functools.wraps(fixture) def _asyncgen_fixture_wrapper( event_loop: asyncio.AbstractEventLoop, request: SubRequest, **kwargs: Any - ) -> _R: + ): + func = _perhaps_rebind_fixture_func( + fixture, request.instance, fixturedef.unittest + ) gen_obj = func(**_add_kwargs(func, kwargs, event_loop, request)) - async def setup() -> _R: + async def setup(): res = await gen_obj.__anext__() return res @@ -294,58 +300,74 @@ request.addfinalizer(finalizer) return result - return _asyncgen_fixture_wrapper + fixturedef.func = _asyncgen_fixture_wrapper -def _wrap_async(func: Callable[..., Awaitable[_R]]) -> Callable[..., _R]: - @functools.wraps(func) +def _wrap_async_fixture(fixturedef: FixtureDef) -> None: + fixture = fixturedef.func + + @functools.wraps(fixture) def _async_fixture_wrapper( event_loop: asyncio.AbstractEventLoop, request: SubRequest, **kwargs: Any - ) -> _R: - async def setup() -> _R: + ): + func = _perhaps_rebind_fixture_func( + fixture, request.instance, fixturedef.unittest + ) + + async def setup(): res = await func(**_add_kwargs(func, kwargs, event_loop, request)) return res return event_loop.run_until_complete(setup()) - return _async_fixture_wrapper + fixturedef.func = _async_fixture_wrapper _HOLDER: Set[FixtureDef] = set() -@pytest.mark.tryfirst +@pytest.hookimpl(tryfirst=True) def pytest_pycollect_makeitem( collector: Union[pytest.Module, pytest.Class], name: str, obj: object ) -> Union[ - None, pytest.Item, pytest.Collector, List[Union[pytest.Item, pytest.Collector]] + pytest.Item, pytest.Collector, List[Union[pytest.Item, pytest.Collector]], None ]: """A pytest hook to collect asyncio coroutines.""" if not collector.funcnamefilter(name): return None _preprocess_async_fixtures(collector.config, _HOLDER) - if isinstance(obj, staticmethod): - # staticmethods need to be unwrapped. - obj = obj.__func__ - if ( - _is_coroutine(obj) - or _is_hypothesis_test(obj) - and _hypothesis_test_wraps_coroutine(obj) - ): - item = pytest.Function.from_parent(collector, name=name) - marker = item.get_closest_marker("asyncio") - if marker is not None: - return list(collector._genfunctions(name, obj)) - else: - if _get_asyncio_mode(item.config) == Mode.AUTO: - # implicitly add asyncio marker if asyncio mode is on - ret = list(collector._genfunctions(name, obj)) - for elem in ret: - elem.add_marker("asyncio") - return ret # type: ignore[return-value] return None +def pytest_collection_modifyitems( + session: Session, config: Config, items: List[Item] +) -> None: + """ + Marks collected async test items as `asyncio` tests. + + The mark is only applied in `AUTO` mode. It is applied to: + + - coroutines + - staticmethods wrapping coroutines + - Hypothesis tests wrapping coroutines + + """ + if _get_asyncio_mode(config) != Mode.AUTO: + return + function_items = (item for item in items if isinstance(item, Function)) + for function_item in function_items: + function = function_item.obj + if isinstance(function, staticmethod): + # staticmethods need to be unwrapped. + function = function.__func__ + if ( + _is_coroutine(function) + or _is_hypothesis_test(function) + and _hypothesis_test_wraps_coroutine(function) + ): + function_item.add_marker("asyncio") + + def _hypothesis_test_wraps_coroutine(function: Any) -> bool: return _is_coroutine(function.hypothesis.inner_test) @@ -377,7 +399,9 @@ loop = outcome.get_result() policy = asyncio.get_event_loop_policy() try: - old_loop = policy.get_event_loop() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + old_loop = policy.get_event_loop() if old_loop is not loop: old_loop.close() except RuntimeError: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/setup.cfg new/pytest-asyncio-0.20.3/setup.cfg --- old/pytest-asyncio-0.19.0/setup.cfg 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/setup.cfg 2022-12-08 13:08:38.000000000 +0100 @@ -10,7 +10,7 @@ author = Tin TvrtkoviÄ <tinches...@gmail.com> author_email = tinches...@gmail.com license = Apache 2.0 -license_file = LICENSE +license_files = LICENSE classifiers = Development Status :: 4 - Beta @@ -47,6 +47,9 @@ flaky >= 3.5.0 mypy >= 0.931 pytest-trio >= 0.7.0 +docs = + sphinx >= 5.3 + sphinx-rtd-theme >= 1.0 [options.entry_points] pytest11 = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/tests/async_fixtures/test_async_fixtures.py new/pytest-asyncio-0.20.3/tests/async_fixtures/test_async_fixtures.py --- old/pytest-asyncio-0.19.0/tests/async_fixtures/test_async_fixtures.py 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/tests/async_fixtures/test_async_fixtures.py 2022-12-08 13:08:38.000000000 +0100 @@ -23,3 +23,15 @@ assert mock.call_count == 1 assert mock.call_args_list[-1] == unittest.mock.call(START) assert async_fixture is RETVAL + + +class TestAsyncFixtureMethod: + is_same_instance = False + + @pytest.fixture(autouse=True) + async def async_fixture_method(self): + self.is_same_instance = True + + @pytest.mark.asyncio + async def test_async_fixture_method(self): + assert self.is_same_instance diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/tests/async_fixtures/test_async_gen_fixtures.py new/pytest-asyncio-0.20.3/tests/async_fixtures/test_async_gen_fixtures.py --- old/pytest-asyncio-0.19.0/tests/async_fixtures/test_async_gen_fixtures.py 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/tests/async_fixtures/test_async_gen_fixtures.py 2022-12-08 13:08:38.000000000 +0100 @@ -36,3 +36,16 @@ assert mock.call_args_list[-1] == unittest.mock.call(END) finally: mock.reset_mock() + + +class TestAsyncGenFixtureMethod: + is_same_instance = False + + @pytest.fixture(autouse=True) + async def async_gen_fixture_method(self): + self.is_same_instance = True + yield None + + @pytest.mark.asyncio + async def test_async_gen_fixture_method(self): + assert self.is_same_instance diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/tests/modes/test_legacy_mode.py new/pytest-asyncio-0.20.3/tests/modes/test_legacy_mode.py --- old/pytest-asyncio-0.19.0/tests/modes/test_legacy_mode.py 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/tests/modes/test_legacy_mode.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,112 +0,0 @@ -from textwrap import dedent - -LEGACY_MODE = ( - "The 'asyncio_mode' default value will change to 'strict' in future, " - "please explicitly use 'asyncio_mode=strict' or 'asyncio_mode=auto' " - "in pytest configuration file." -) - -LEGACY_ASYNCIO_FIXTURE = ( - "'@pytest.fixture' is applied to {name} " - "in 'legacy' mode, " - "please replace it with '@pytest_asyncio.fixture' as a preparation " - "for switching to 'strict' mode (or use 'auto' mode to seamlessly handle " - "all these fixtures as asyncio-driven)." -).format(name="*") - - -def test_warning_for_legacy_mode_cmdline(testdir): - testdir.makepyfile( - dedent( - """\ - import asyncio - import pytest - - pytest_plugins = 'pytest_asyncio' - - @pytest.mark.asyncio - async def test_a(): - await asyncio.sleep(0) - """ - ) - ) - result = testdir.runpytest("--asyncio-mode=legacy") - assert result.parseoutcomes()["warnings"] == 1 - result.stdout.fnmatch_lines(["*" + LEGACY_MODE + "*"]) - - -def test_warning_for_legacy_mode_cfg(testdir): - testdir.makepyfile( - dedent( - """\ - import asyncio - import pytest - - pytest_plugins = 'pytest_asyncio' - - @pytest.mark.asyncio - async def test_a(): - await asyncio.sleep(0) - """ - ) - ) - testdir.makefile(".ini", pytest="[pytest]\nasyncio_mode = legacy\n") - result = testdir.runpytest() - assert result.parseoutcomes()["warnings"] == 1 - result.stdout.fnmatch_lines(["*" + LEGACY_MODE + "*"]) - result.stdout.no_fnmatch_line("*" + LEGACY_ASYNCIO_FIXTURE + "*") - - -def test_warning_for_legacy_fixture(testdir): - testdir.makepyfile( - dedent( - """\ - import asyncio - import pytest - - pytest_plugins = 'pytest_asyncio' - - @pytest.fixture - async def fixture_a(): - await asyncio.sleep(0) - return 1 - - @pytest.mark.asyncio - async def test_a(fixture_a): - await asyncio.sleep(0) - assert fixture_a == 1 - """ - ) - ) - result = testdir.runpytest("--asyncio-mode=legacy") - assert result.parseoutcomes()["warnings"] == 2 - result.stdout.fnmatch_lines(["*" + LEGACY_ASYNCIO_FIXTURE + "*"]) - - -def test_warning_for_legacy_method_fixture(testdir): - testdir.makepyfile( - dedent( - """\ - import asyncio - import pytest - - pytest_plugins = 'pytest_asyncio' - - - class TestA: - - @pytest.fixture - async def fixture_a(self): - await asyncio.sleep(0) - return 1 - - @pytest.mark.asyncio - async def test_a(self, fixture_a): - await asyncio.sleep(0) - assert fixture_a == 1 - """ - ) - ) - result = testdir.runpytest("--asyncio-mode=legacy") - assert result.parseoutcomes()["warnings"] == 2 - result.stdout.fnmatch_lines(["*" + LEGACY_ASYNCIO_FIXTURE + "*"]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/tests/test_asyncio_fixture.py new/pytest-asyncio-0.20.3/tests/test_asyncio_fixture.py --- old/pytest-asyncio-0.19.0/tests/test_asyncio_fixture.py 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/tests/test_asyncio_fixture.py 2022-12-08 13:08:38.000000000 +0100 @@ -42,7 +42,7 @@ assert fixture_with_params % 2 == 0 -@pytest.mark.parametrize("mode", ("auto", "strict", "legacy")) +@pytest.mark.parametrize("mode", ("auto", "strict")) def test_sync_function_uses_async_fixture(testdir, mode): testdir.makepyfile( dedent( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/tests/test_pytest_min_version_warning.py new/pytest-asyncio-0.20.3/tests/test_pytest_min_version_warning.py --- old/pytest-asyncio-0.19.0/tests/test_pytest_min_version_warning.py 1970-01-01 01:00:00.000000000 +0100 +++ new/pytest-asyncio-0.20.3/tests/test_pytest_min_version_warning.py 2022-12-08 13:08:38.000000000 +0100 @@ -0,0 +1,26 @@ +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) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-asyncio-0.19.0/tests/test_simple.py new/pytest-asyncio-0.20.3/tests/test_simple.py --- old/pytest-asyncio-0.19.0/tests/test_simple.py 2022-07-15 10:00:30.000000000 +0200 +++ new/pytest-asyncio-0.20.3/tests/test_simple.py 2022-12-08 13:08:38.000000000 +0100 @@ -240,7 +240,6 @@ def test_async_close_loop(event_loop): event_loop.close() - return "ok" def test_warn_asyncio_marker_for_regular_func(testdir):