pytest-asyncio 0.25.2__tar.gz → 0.26.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/PKG-INFO +5 -4
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/dependencies/default/constraints.txt +5 -5
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/dependencies/docs/constraints.txt +3 -3
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/concepts.rst +5 -1
- pytest_asyncio-0.26.0/docs/how-to-guides/change_default_test_loop.rst +24 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/index.rst +1 -1
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/uvloop.rst +1 -1
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/changelog.rst +13 -2
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/configuration.rst +6 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pyproject.toml +6 -8
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pytest_asyncio/_version.py +9 -4
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pytest_asyncio/plugin.py +56 -26
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pytest_asyncio.egg-info/PKG-INFO +5 -4
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pytest_asyncio.egg-info/SOURCES.txt +1 -3
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pytest_asyncio.egg-info/requires.txt +3 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_asyncio_mark.py +77 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_event_loop_fixture.py +58 -0
- pytest_asyncio-0.25.2/docs/how-to-guides/run_session_tests_in_same_loop.rst +0 -10
- pytest_asyncio-0.25.2/docs/how-to-guides/session_scoped_loop_example.py +0 -10
- pytest_asyncio-0.25.2/docs/how-to-guides/test_session_scoped_loop_example.py +0 -63
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/.readthedocs.yaml +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/LICENSE +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/MANIFEST.in +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/Makefile +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/README.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/SECURITY.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/dependencies/default/requirements.txt +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/dependencies/docs/requirements.txt +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/dependencies/pytest-min/constraints.txt +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/dependencies/pytest-min/requirements.txt +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/concepts_function_scope_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/concepts_module_scope_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/conf.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/change_default_fixture_loop.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/change_fixture_loop.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/change_fixture_loop_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/class_scoped_loop_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/migrate_from_0_21.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/migrate_from_0_23.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/module_scoped_loop_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/multiple_loops.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/multiple_loops_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/package_scoped_loop_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/run_class_tests_in_same_loop.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/run_module_tests_in_same_loop.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/run_package_tests_in_same_loop.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/test_item_is_async.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/test_item_is_async_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/index.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/decorators/index.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/decorators/pytest_asyncio_fixture_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/fixtures/event_loop_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/fixtures/event_loop_policy_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/fixtures/event_loop_policy_parametrized_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/fixtures/index.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/functions.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/index.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/markers/class_scoped_loop_custom_policies_strict_mode_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/markers/class_scoped_loop_strict_mode_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/markers/class_scoped_loop_with_fixture_strict_mode_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/markers/function_scoped_loop_pytestmark_strict_mode_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/markers/function_scoped_loop_strict_mode_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/markers/index.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/markers/module_scoped_loop_strict_mode_example.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/support.rst +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pytest_asyncio/__init__.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pytest_asyncio/py.typed +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pytest_asyncio.egg-info/dependency_links.txt +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pytest_asyncio.egg-info/entry_points.txt +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pytest_asyncio.egg-info/top_level.txt +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/setup.cfg +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/__init__.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/__init__.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_async_fixtures.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_async_fixtures_contextvars.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_async_fixtures_scope.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_async_fixtures_with_finalizer.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_async_gen_fixtures.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_nested.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_parametrized_loop.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_shared_module_fixture.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/conftest.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/hypothesis/__init__.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/hypothesis/test_base.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/loop_fixture_scope/__init__.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/loop_fixture_scope/conftest.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/loop_fixture_scope/test_loop_fixture_scope.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/markers/__init__.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/markers/test_class_scope.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/markers/test_function_scope.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/markers/test_invalid_arguments.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/markers/test_mixed_scope.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/markers/test_module_scope.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/markers/test_package_scope.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/markers/test_session_scope.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/modes/__init__.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/modes/test_auto_mode.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/modes/test_strict_mode.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_asyncio_fixture.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_dependent_fixtures.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_doctest.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_event_loop_fixture_finalizer.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_event_loop_fixture_override_deprecation.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_explicit_event_loop_fixture_request.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_fixture_loop_scopes.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_import.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_is_async_test.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_multiloop.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_port_factories.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_simple.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_skips.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_subprocess.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tools/get-version.py +0 -0
- {pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tox.ini +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pytest-asyncio
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.26.0
|
|
4
4
|
Summary: Pytest support for asyncio
|
|
5
5
|
Author-email: "Tin Tvrtković <tinchester@gmail.com>" <tinchester@gmail.com>
|
|
6
|
-
License: Apache
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
7
|
Project-URL: Bug Tracker, https://github.com/pytest-dev/pytest-asyncio/issues
|
|
8
8
|
Project-URL: Changelog, https://pytest-asyncio.readthedocs.io/en/latest/reference/changelog.html
|
|
9
9
|
Project-URL: Documentation, https://pytest-asyncio.readthedocs.io
|
|
@@ -13,7 +13,6 @@ Classifier: Development Status :: 4 - Beta
|
|
|
13
13
|
Classifier: Framework :: AsyncIO
|
|
14
14
|
Classifier: Framework :: Pytest
|
|
15
15
|
Classifier: Intended Audience :: Developers
|
|
16
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
17
16
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -26,12 +25,14 @@ Requires-Python: >=3.9
|
|
|
26
25
|
Description-Content-Type: text/x-rst
|
|
27
26
|
License-File: LICENSE
|
|
28
27
|
Requires-Dist: pytest<9,>=8.2
|
|
28
|
+
Requires-Dist: typing-extensions>=4.12; python_version < "3.10"
|
|
29
29
|
Provides-Extra: docs
|
|
30
30
|
Requires-Dist: sphinx>=5.3; extra == "docs"
|
|
31
31
|
Requires-Dist: sphinx-rtd-theme>=1; extra == "docs"
|
|
32
32
|
Provides-Extra: testing
|
|
33
33
|
Requires-Dist: coverage>=6.2; extra == "testing"
|
|
34
34
|
Requires-Dist: hypothesis>=5.7.1; extra == "testing"
|
|
35
|
+
Dynamic: license-file
|
|
35
36
|
|
|
36
37
|
pytest-asyncio
|
|
37
38
|
==============
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
attrs==
|
|
2
|
-
coverage==7.
|
|
1
|
+
attrs==25.3.0
|
|
2
|
+
coverage==7.7.1
|
|
3
3
|
exceptiongroup==1.2.2
|
|
4
|
-
hypothesis==6.
|
|
5
|
-
iniconfig==2.
|
|
4
|
+
hypothesis==6.130.3
|
|
5
|
+
iniconfig==2.1.0
|
|
6
6
|
packaging==24.2
|
|
7
7
|
pluggy==1.5.0
|
|
8
|
-
pytest==8.3.
|
|
8
|
+
pytest==8.3.5
|
|
9
9
|
sortedcontainers==2.4.0
|
|
10
10
|
tomli==2.2.1
|
|
11
11
|
typing_extensions==4.12.2
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
alabaster==0.7.16
|
|
2
|
-
Babel==2.
|
|
3
|
-
certifi==
|
|
2
|
+
Babel==2.17.0
|
|
3
|
+
certifi==2025.1.31
|
|
4
4
|
charset-normalizer==3.4.1
|
|
5
5
|
docutils==0.21.2
|
|
6
6
|
idna==3.10
|
|
7
7
|
imagesize==1.4.1
|
|
8
|
-
Jinja2==3.1.
|
|
8
|
+
Jinja2==3.1.6
|
|
9
9
|
MarkupSafe==3.0.2
|
|
10
10
|
packaging==24.2
|
|
11
11
|
Pygments==2.19.1
|
|
@@ -47,8 +47,12 @@ Assigning neighboring tests to different event loop scopes is discouraged as it
|
|
|
47
47
|
Test discovery modes
|
|
48
48
|
====================
|
|
49
49
|
|
|
50
|
-
Pytest-asyncio provides two modes for test discovery, *strict* and *auto*.
|
|
50
|
+
Pytest-asyncio provides two modes for test discovery, *strict* and *auto*. This can be set through Pytest's ``--asyncio-mode`` command line flag, or through the configuration file:
|
|
51
51
|
|
|
52
|
+
.. code-block:: toml
|
|
53
|
+
|
|
54
|
+
[tool.pytest.ini_options]
|
|
55
|
+
asyncio_mode = "auto" # or "strict"
|
|
52
56
|
|
|
53
57
|
Strict mode
|
|
54
58
|
-----------
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
=======================================================
|
|
2
|
+
How to change the default event loop scope of all tests
|
|
3
|
+
=======================================================
|
|
4
|
+
The :ref:`configuration/asyncio_default_test_loop_scope` configuration option sets the default event loop scope for asynchronous tests. The following code snippets configure all tests to run in a session-scoped loop by default:
|
|
5
|
+
|
|
6
|
+
.. code-block:: ini
|
|
7
|
+
:caption: pytest.ini
|
|
8
|
+
|
|
9
|
+
[pytest]
|
|
10
|
+
asyncio_default_test_loop_scope = session
|
|
11
|
+
|
|
12
|
+
.. code-block:: toml
|
|
13
|
+
:caption: pyproject.toml
|
|
14
|
+
|
|
15
|
+
[tool.pytest.ini_options]
|
|
16
|
+
asyncio_default_test_loop_scope = "session"
|
|
17
|
+
|
|
18
|
+
.. code-block:: ini
|
|
19
|
+
:caption: setup.cfg
|
|
20
|
+
|
|
21
|
+
[tool:pytest]
|
|
22
|
+
asyncio_default_test_loop_scope = session
|
|
23
|
+
|
|
24
|
+
Please refer to :ref:`configuration/asyncio_default_test_loop_scope` for other valid scopes.
|
|
@@ -9,10 +9,10 @@ How-To Guides
|
|
|
9
9
|
migrate_from_0_23
|
|
10
10
|
change_fixture_loop
|
|
11
11
|
change_default_fixture_loop
|
|
12
|
+
change_default_test_loop
|
|
12
13
|
run_class_tests_in_same_loop
|
|
13
14
|
run_module_tests_in_same_loop
|
|
14
15
|
run_package_tests_in_same_loop
|
|
15
|
-
run_session_tests_in_same_loop
|
|
16
16
|
multiple_loops
|
|
17
17
|
uvloop
|
|
18
18
|
test_item_is_async
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
How to test with uvloop
|
|
3
3
|
=======================
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Redefining the *event_loop_policy* fixture will parametrize all async tests. The following example causes all async tests to run multiple times, once for each event loop in the fixture parameters:
|
|
6
6
|
Replace the default event loop policy in your *conftest.py:*
|
|
7
7
|
|
|
8
8
|
.. code-block:: python
|
|
@@ -2,11 +2,23 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
-
0.
|
|
5
|
+
0.26.0 (2025-03-25)
|
|
6
6
|
===================
|
|
7
|
+
- Adds configuration option that sets default event loop scope for all tests `#793 <https://github.com/pytest-dev/pytest-asyncio/issues/793>`_
|
|
8
|
+
- Improved type annotations for ``pytest_asyncio.fixture`` `#1045 <https://github.com/pytest-dev/pytest-asyncio/pull/1045>`_
|
|
9
|
+
- Added ``typing-extensions`` as additional dependency for Python ``<3.10`` `#1045 <https://github.com/pytest-dev/pytest-asyncio/pull/1045>`_
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
0.25.3 (2025-01-28)
|
|
13
|
+
===================
|
|
14
|
+
- Avoid errors in cleanup of async generators when event loop is already closed `#1040 <https://github.com/pytest-dev/pytest-asyncio/issues/1040>`_
|
|
15
|
+
|
|
7
16
|
|
|
17
|
+
0.25.2 (2025-01-08)
|
|
18
|
+
===================
|
|
8
19
|
- Call ``loop.shutdown_asyncgens()`` before closing the event loop to ensure async generators are closed in the same manner as ``asyncio.run`` does `#1034 <https://github.com/pytest-dev/pytest-asyncio/pull/1034>`_
|
|
9
20
|
|
|
21
|
+
|
|
10
22
|
0.25.1 (2025-01-02)
|
|
11
23
|
===================
|
|
12
24
|
- Fixes an issue that caused a broken event loop when a function-scoped test was executed in between two tests with wider loop scope `#950 <https://github.com/pytest-dev/pytest-asyncio/issues/950>`_
|
|
@@ -22,7 +34,6 @@ Changelog
|
|
|
22
34
|
- Propagates `contextvars` set in async fixtures to other fixtures and tests on Python 3.11 and above. `#1008 <https://github.com/pytest-dev/pytest-asyncio/pull/1008>`_
|
|
23
35
|
|
|
24
36
|
|
|
25
|
-
|
|
26
37
|
0.24.0 (2024-08-22)
|
|
27
38
|
===================
|
|
28
39
|
- BREAKING: Updated minimum supported pytest version to v8.2.0
|
|
@@ -8,6 +8,12 @@ asyncio_default_fixture_loop_scope
|
|
|
8
8
|
==================================
|
|
9
9
|
Determines the default event loop scope of asynchronous fixtures. When this configuration option is unset, it defaults to the fixture scope. In future versions of pytest-asyncio, the value will default to ``function`` when unset. Possible values are: ``function``, ``class``, ``module``, ``package``, ``session``
|
|
10
10
|
|
|
11
|
+
.. _configuration/asyncio_default_test_loop_scope:
|
|
12
|
+
|
|
13
|
+
asyncio_default_test_loop_scope
|
|
14
|
+
===============================
|
|
15
|
+
Determines the default event loop scope of asynchronous tests. When this configuration option is unset, it default to function scope. Possible values are: ``function``, ``class``, ``module``, ``package``, ``session``
|
|
16
|
+
|
|
11
17
|
asyncio_mode
|
|
12
18
|
============
|
|
13
19
|
The pytest-asyncio mode can be set by the ``asyncio_mode`` configuration option in the `configuration file
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
[build-system]
|
|
2
2
|
build-backend = "setuptools.build_meta"
|
|
3
|
-
|
|
4
3
|
requires = [
|
|
5
|
-
"setuptools>=
|
|
4
|
+
"setuptools>=77",
|
|
6
5
|
"setuptools-scm[toml]>=6.2",
|
|
7
|
-
"wheel>=0.36",
|
|
8
6
|
]
|
|
9
7
|
|
|
10
8
|
[project]
|
|
@@ -12,7 +10,10 @@ name = "pytest-asyncio"
|
|
|
12
10
|
description = "Pytest support for asyncio"
|
|
13
11
|
readme.content-type = "text/x-rst"
|
|
14
12
|
readme.file = "README.rst"
|
|
15
|
-
license
|
|
13
|
+
license = "Apache-2.0"
|
|
14
|
+
license-files = [
|
|
15
|
+
"LICENSE",
|
|
16
|
+
]
|
|
16
17
|
authors = [
|
|
17
18
|
{ name = "Tin Tvrtković <tinchester@gmail.com>", email = "tinchester@gmail.com" },
|
|
18
19
|
]
|
|
@@ -22,7 +23,6 @@ classifiers = [
|
|
|
22
23
|
"Framework :: AsyncIO",
|
|
23
24
|
"Framework :: Pytest",
|
|
24
25
|
"Intended Audience :: Developers",
|
|
25
|
-
"License :: OSI Approved :: Apache Software License",
|
|
26
26
|
"Programming Language :: Python :: 3 :: Only",
|
|
27
27
|
"Programming Language :: Python :: 3.9",
|
|
28
28
|
"Programming Language :: Python :: 3.10",
|
|
@@ -38,6 +38,7 @@ dynamic = [
|
|
|
38
38
|
|
|
39
39
|
dependencies = [
|
|
40
40
|
"pytest>=8.2,<9",
|
|
41
|
+
"typing-extensions>=4.12; python_version<'3.10'",
|
|
41
42
|
]
|
|
42
43
|
optional-dependencies.docs = [
|
|
43
44
|
"sphinx>=5.3",
|
|
@@ -59,9 +60,6 @@ packages = [
|
|
|
59
60
|
"pytest_asyncio",
|
|
60
61
|
]
|
|
61
62
|
include-package-data = true
|
|
62
|
-
license-files = [
|
|
63
|
-
"LICENSE",
|
|
64
|
-
]
|
|
65
63
|
|
|
66
64
|
[tool.setuptools_scm]
|
|
67
65
|
write_to = "pytest_asyncio/_version.py"
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
# file generated by
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
+
|
|
3
6
|
TYPE_CHECKING = False
|
|
4
7
|
if TYPE_CHECKING:
|
|
5
|
-
from typing import Tuple
|
|
8
|
+
from typing import Tuple
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
6
11
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
7
12
|
else:
|
|
8
13
|
VERSION_TUPLE = object
|
|
@@ -12,5 +17,5 @@ __version__: str
|
|
|
12
17
|
__version_tuple__: VERSION_TUPLE
|
|
13
18
|
version_tuple: VERSION_TUPLE
|
|
14
19
|
|
|
15
|
-
__version__ = version = '0.
|
|
16
|
-
__version_tuple__ = version_tuple = (0,
|
|
20
|
+
__version__ = version = '0.26.0'
|
|
21
|
+
__version_tuple__ = version_tuple = (0, 26, 0)
|
|
@@ -9,6 +9,7 @@ import enum
|
|
|
9
9
|
import functools
|
|
10
10
|
import inspect
|
|
11
11
|
import socket
|
|
12
|
+
import sys
|
|
12
13
|
import warnings
|
|
13
14
|
from asyncio import AbstractEventLoop, AbstractEventLoopPolicy
|
|
14
15
|
from collections.abc import (
|
|
@@ -53,17 +54,17 @@ from pytest import (
|
|
|
53
54
|
StashKey,
|
|
54
55
|
)
|
|
55
56
|
|
|
57
|
+
if sys.version_info >= (3, 10):
|
|
58
|
+
from typing import ParamSpec
|
|
59
|
+
else:
|
|
60
|
+
from typing_extensions import ParamSpec
|
|
61
|
+
|
|
62
|
+
|
|
56
63
|
_ScopeName = Literal["session", "package", "module", "class", "function"]
|
|
57
64
|
_T = TypeVar("_T")
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
)
|
|
62
|
-
FactoryFixtureFunction = TypeVar(
|
|
63
|
-
"FactoryFixtureFunction", bound=Callable[..., AsyncIterator[object]]
|
|
64
|
-
)
|
|
65
|
-
FixtureFunction = Union[SimpleFixtureFunction, FactoryFixtureFunction]
|
|
66
|
-
FixtureFunctionMarker = Callable[[FixtureFunction], FixtureFunction]
|
|
65
|
+
_R = TypeVar("_R", bound=Union[Awaitable[Any], AsyncIterator[Any]])
|
|
66
|
+
_P = ParamSpec("_P")
|
|
67
|
+
FixtureFunction = Callable[_P, _R]
|
|
67
68
|
|
|
68
69
|
|
|
69
70
|
class PytestAsyncioError(Exception):
|
|
@@ -107,11 +108,17 @@ def pytest_addoption(parser: Parser, pluginmanager: PytestPluginManager) -> None
|
|
|
107
108
|
help="default scope of the asyncio event loop used to execute async fixtures",
|
|
108
109
|
default=None,
|
|
109
110
|
)
|
|
111
|
+
parser.addini(
|
|
112
|
+
"asyncio_default_test_loop_scope",
|
|
113
|
+
type="string",
|
|
114
|
+
help="default scope of the asyncio event loop used to execute tests",
|
|
115
|
+
default="function",
|
|
116
|
+
)
|
|
110
117
|
|
|
111
118
|
|
|
112
119
|
@overload
|
|
113
120
|
def fixture(
|
|
114
|
-
fixture_function: FixtureFunction,
|
|
121
|
+
fixture_function: FixtureFunction[_P, _R],
|
|
115
122
|
*,
|
|
116
123
|
scope: _ScopeName | Callable[[str, Config], _ScopeName] = ...,
|
|
117
124
|
loop_scope: _ScopeName | None = ...,
|
|
@@ -123,7 +130,7 @@ def fixture(
|
|
|
123
130
|
| None
|
|
124
131
|
) = ...,
|
|
125
132
|
name: str | None = ...,
|
|
126
|
-
) -> FixtureFunction: ...
|
|
133
|
+
) -> FixtureFunction[_P, _R]: ...
|
|
127
134
|
|
|
128
135
|
|
|
129
136
|
@overload
|
|
@@ -140,14 +147,17 @@ def fixture(
|
|
|
140
147
|
| None
|
|
141
148
|
) = ...,
|
|
142
149
|
name: str | None = None,
|
|
143
|
-
) ->
|
|
150
|
+
) -> Callable[[FixtureFunction[_P, _R]], FixtureFunction[_P, _R]]: ...
|
|
144
151
|
|
|
145
152
|
|
|
146
153
|
def fixture(
|
|
147
|
-
fixture_function: FixtureFunction | None = None,
|
|
154
|
+
fixture_function: FixtureFunction[_P, _R] | None = None,
|
|
148
155
|
loop_scope: _ScopeName | None = None,
|
|
149
156
|
**kwargs: Any,
|
|
150
|
-
) ->
|
|
157
|
+
) -> (
|
|
158
|
+
FixtureFunction[_P, _R]
|
|
159
|
+
| Callable[[FixtureFunction[_P, _R]], FixtureFunction[_P, _R]]
|
|
160
|
+
):
|
|
151
161
|
if fixture_function is not None:
|
|
152
162
|
_make_asyncio_fixture_function(fixture_function, loop_scope)
|
|
153
163
|
return pytest.fixture(fixture_function, **kwargs)
|
|
@@ -155,7 +165,7 @@ def fixture(
|
|
|
155
165
|
else:
|
|
156
166
|
|
|
157
167
|
@functools.wraps(fixture)
|
|
158
|
-
def inner(fixture_function: FixtureFunction) -> FixtureFunction:
|
|
168
|
+
def inner(fixture_function: FixtureFunction[_P, _R]) -> FixtureFunction[_P, _R]:
|
|
159
169
|
return fixture(fixture_function, loop_scope=loop_scope, **kwargs)
|
|
160
170
|
|
|
161
171
|
return inner
|
|
@@ -217,9 +227,15 @@ def pytest_configure(config: Config) -> None:
|
|
|
217
227
|
def pytest_report_header(config: Config) -> list[str]:
|
|
218
228
|
"""Add asyncio config to pytest header."""
|
|
219
229
|
mode = _get_asyncio_mode(config)
|
|
220
|
-
|
|
230
|
+
default_fixture_loop_scope = config.getini("asyncio_default_fixture_loop_scope")
|
|
231
|
+
default_test_loop_scope = _get_default_test_loop_scope(config)
|
|
232
|
+
header = [
|
|
233
|
+
f"mode={mode}",
|
|
234
|
+
f"asyncio_default_fixture_loop_scope={default_fixture_loop_scope}",
|
|
235
|
+
f"asyncio_default_test_loop_scope={default_test_loop_scope}",
|
|
236
|
+
]
|
|
221
237
|
return [
|
|
222
|
-
|
|
238
|
+
"asyncio: " + ", ".join(header),
|
|
223
239
|
]
|
|
224
240
|
|
|
225
241
|
|
|
@@ -667,7 +683,7 @@ _fixture_scope_by_collector_type: Mapping[type[pytest.Collector], _ScopeName] =
|
|
|
667
683
|
|
|
668
684
|
# A stack used to push package-scoped loops during collection of a package
|
|
669
685
|
# and pop those loops during collection of a Module
|
|
670
|
-
__package_loop_stack: list[
|
|
686
|
+
__package_loop_stack: list[Callable[..., Any]] = []
|
|
671
687
|
|
|
672
688
|
|
|
673
689
|
@pytest.hookimpl
|
|
@@ -807,7 +823,8 @@ def pytest_generate_tests(metafunc: Metafunc) -> None:
|
|
|
807
823
|
marker = metafunc.definition.get_closest_marker("asyncio")
|
|
808
824
|
if not marker:
|
|
809
825
|
return
|
|
810
|
-
|
|
826
|
+
default_loop_scope = _get_default_test_loop_scope(metafunc.config)
|
|
827
|
+
scope = _get_marked_loop_scope(marker, default_loop_scope)
|
|
811
828
|
if scope == "function":
|
|
812
829
|
return
|
|
813
830
|
event_loop_node = _retrieve_scope_root(metafunc.definition, scope)
|
|
@@ -1078,7 +1095,8 @@ def pytest_runtest_setup(item: pytest.Item) -> None:
|
|
|
1078
1095
|
marker = item.get_closest_marker("asyncio")
|
|
1079
1096
|
if marker is None:
|
|
1080
1097
|
return
|
|
1081
|
-
|
|
1098
|
+
default_loop_scope = _get_default_test_loop_scope(item.config)
|
|
1099
|
+
scope = _get_marked_loop_scope(marker, default_loop_scope)
|
|
1082
1100
|
if scope != "function":
|
|
1083
1101
|
parent_node = _retrieve_scope_root(item, scope)
|
|
1084
1102
|
event_loop_fixture_id = parent_node.stash[_event_loop_fixture_id]
|
|
@@ -1108,7 +1126,9 @@ Please use the "loop_scope" argument instead.
|
|
|
1108
1126
|
"""
|
|
1109
1127
|
|
|
1110
1128
|
|
|
1111
|
-
def _get_marked_loop_scope(
|
|
1129
|
+
def _get_marked_loop_scope(
|
|
1130
|
+
asyncio_marker: Mark, default_loop_scope: _ScopeName
|
|
1131
|
+
) -> _ScopeName:
|
|
1112
1132
|
assert asyncio_marker.name == "asyncio"
|
|
1113
1133
|
if asyncio_marker.args or (
|
|
1114
1134
|
asyncio_marker.kwargs and set(asyncio_marker.kwargs) - {"loop_scope", "scope"}
|
|
@@ -1119,12 +1139,18 @@ def _get_marked_loop_scope(asyncio_marker: Mark) -> _ScopeName:
|
|
|
1119
1139
|
raise pytest.UsageError(_DUPLICATE_LOOP_SCOPE_DEFINITION_ERROR)
|
|
1120
1140
|
warnings.warn(PytestDeprecationWarning(_MARKER_SCOPE_KWARG_DEPRECATION_WARNING))
|
|
1121
1141
|
scope = asyncio_marker.kwargs.get("loop_scope") or asyncio_marker.kwargs.get(
|
|
1122
|
-
"scope"
|
|
1142
|
+
"scope"
|
|
1123
1143
|
)
|
|
1144
|
+
if scope is None:
|
|
1145
|
+
scope = default_loop_scope
|
|
1124
1146
|
assert scope in {"function", "class", "module", "package", "session"}
|
|
1125
1147
|
return scope
|
|
1126
1148
|
|
|
1127
1149
|
|
|
1150
|
+
def _get_default_test_loop_scope(config: Config) -> _ScopeName:
|
|
1151
|
+
return config.getini("asyncio_default_test_loop_scope")
|
|
1152
|
+
|
|
1153
|
+
|
|
1128
1154
|
def _retrieve_scope_root(item: Collector | Item, scope: str) -> Collector:
|
|
1129
1155
|
node_type_by_scope = {
|
|
1130
1156
|
"class": Class,
|
|
@@ -1164,10 +1190,14 @@ def _provide_event_loop() -> Iterator[asyncio.AbstractEventLoop]:
|
|
|
1164
1190
|
try:
|
|
1165
1191
|
yield loop
|
|
1166
1192
|
finally:
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1193
|
+
# cleanup the event loop if it hasn't been cleaned up already
|
|
1194
|
+
if not loop.is_closed():
|
|
1195
|
+
try:
|
|
1196
|
+
loop.run_until_complete(loop.shutdown_asyncgens())
|
|
1197
|
+
except Exception as e:
|
|
1198
|
+
warnings.warn(f"Error cleaning up asyncio loop: {e}", RuntimeWarning)
|
|
1199
|
+
finally:
|
|
1200
|
+
loop.close()
|
|
1171
1201
|
|
|
1172
1202
|
|
|
1173
1203
|
@pytest.fixture(scope="session")
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pytest-asyncio
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.26.0
|
|
4
4
|
Summary: Pytest support for asyncio
|
|
5
5
|
Author-email: "Tin Tvrtković <tinchester@gmail.com>" <tinchester@gmail.com>
|
|
6
|
-
License: Apache
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
7
|
Project-URL: Bug Tracker, https://github.com/pytest-dev/pytest-asyncio/issues
|
|
8
8
|
Project-URL: Changelog, https://pytest-asyncio.readthedocs.io/en/latest/reference/changelog.html
|
|
9
9
|
Project-URL: Documentation, https://pytest-asyncio.readthedocs.io
|
|
@@ -13,7 +13,6 @@ Classifier: Development Status :: 4 - Beta
|
|
|
13
13
|
Classifier: Framework :: AsyncIO
|
|
14
14
|
Classifier: Framework :: Pytest
|
|
15
15
|
Classifier: Intended Audience :: Developers
|
|
16
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
17
16
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -26,12 +25,14 @@ Requires-Python: >=3.9
|
|
|
26
25
|
Description-Content-Type: text/x-rst
|
|
27
26
|
License-File: LICENSE
|
|
28
27
|
Requires-Dist: pytest<9,>=8.2
|
|
28
|
+
Requires-Dist: typing-extensions>=4.12; python_version < "3.10"
|
|
29
29
|
Provides-Extra: docs
|
|
30
30
|
Requires-Dist: sphinx>=5.3; extra == "docs"
|
|
31
31
|
Requires-Dist: sphinx-rtd-theme>=1; extra == "docs"
|
|
32
32
|
Provides-Extra: testing
|
|
33
33
|
Requires-Dist: coverage>=6.2; extra == "testing"
|
|
34
34
|
Requires-Dist: hypothesis>=5.7.1; extra == "testing"
|
|
35
|
+
Dynamic: license-file
|
|
35
36
|
|
|
36
37
|
pytest-asyncio
|
|
37
38
|
==============
|
|
@@ -20,6 +20,7 @@ docs/conf.py
|
|
|
20
20
|
docs/index.rst
|
|
21
21
|
docs/support.rst
|
|
22
22
|
docs/how-to-guides/change_default_fixture_loop.rst
|
|
23
|
+
docs/how-to-guides/change_default_test_loop.rst
|
|
23
24
|
docs/how-to-guides/change_fixture_loop.rst
|
|
24
25
|
docs/how-to-guides/change_fixture_loop_example.py
|
|
25
26
|
docs/how-to-guides/class_scoped_loop_example.py
|
|
@@ -33,11 +34,8 @@ docs/how-to-guides/package_scoped_loop_example.py
|
|
|
33
34
|
docs/how-to-guides/run_class_tests_in_same_loop.rst
|
|
34
35
|
docs/how-to-guides/run_module_tests_in_same_loop.rst
|
|
35
36
|
docs/how-to-guides/run_package_tests_in_same_loop.rst
|
|
36
|
-
docs/how-to-guides/run_session_tests_in_same_loop.rst
|
|
37
|
-
docs/how-to-guides/session_scoped_loop_example.py
|
|
38
37
|
docs/how-to-guides/test_item_is_async.rst
|
|
39
38
|
docs/how-to-guides/test_item_is_async_example.py
|
|
40
|
-
docs/how-to-guides/test_session_scoped_loop_example.py
|
|
41
39
|
docs/how-to-guides/uvloop.rst
|
|
42
40
|
docs/reference/changelog.rst
|
|
43
41
|
docs/reference/configuration.rst
|
|
@@ -146,3 +146,80 @@ def test_asyncio_mark_on_async_generator_staticmethod_emits_warning_in_auto_mode
|
|
|
146
146
|
result.stdout.fnmatch_lines(
|
|
147
147
|
["*Tests based on asynchronous generators are not supported*"]
|
|
148
148
|
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def test_asyncio_marker_fallbacks_to_configured_default_loop_scope_if_not_set(
|
|
152
|
+
pytester: Pytester,
|
|
153
|
+
):
|
|
154
|
+
pytester.makeini(
|
|
155
|
+
dedent(
|
|
156
|
+
"""\
|
|
157
|
+
[pytest]
|
|
158
|
+
asyncio_default_fixture_loop_scope = function
|
|
159
|
+
asyncio_default_test_loop_scope = session
|
|
160
|
+
"""
|
|
161
|
+
)
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
pytester.makepyfile(
|
|
165
|
+
dedent(
|
|
166
|
+
"""\
|
|
167
|
+
import asyncio
|
|
168
|
+
import pytest_asyncio
|
|
169
|
+
import pytest
|
|
170
|
+
|
|
171
|
+
loop: asyncio.AbstractEventLoop
|
|
172
|
+
|
|
173
|
+
@pytest_asyncio.fixture(loop_scope="session", scope="session")
|
|
174
|
+
async def session_loop_fixture():
|
|
175
|
+
global loop
|
|
176
|
+
loop = asyncio.get_running_loop()
|
|
177
|
+
|
|
178
|
+
async def test_a(session_loop_fixture):
|
|
179
|
+
global loop
|
|
180
|
+
assert asyncio.get_running_loop() is loop
|
|
181
|
+
"""
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
result = pytester.runpytest("--asyncio-mode=auto")
|
|
186
|
+
result.assert_outcomes(passed=1)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def test_asyncio_marker_uses_marker_loop_scope_even_if_config_is_set(
|
|
190
|
+
pytester: Pytester,
|
|
191
|
+
):
|
|
192
|
+
pytester.makeini(
|
|
193
|
+
dedent(
|
|
194
|
+
"""\
|
|
195
|
+
[pytest]
|
|
196
|
+
asyncio_default_fixture_loop_scope = function
|
|
197
|
+
asyncio_default_test_loop_scope = module
|
|
198
|
+
"""
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
pytester.makepyfile(
|
|
203
|
+
dedent(
|
|
204
|
+
"""\
|
|
205
|
+
import asyncio
|
|
206
|
+
import pytest_asyncio
|
|
207
|
+
import pytest
|
|
208
|
+
|
|
209
|
+
loop: asyncio.AbstractEventLoop
|
|
210
|
+
|
|
211
|
+
@pytest_asyncio.fixture(loop_scope="session", scope="session")
|
|
212
|
+
async def session_loop_fixture():
|
|
213
|
+
global loop
|
|
214
|
+
loop = asyncio.get_running_loop()
|
|
215
|
+
|
|
216
|
+
@pytest.mark.asyncio(loop_scope="session")
|
|
217
|
+
async def test_a(session_loop_fixture):
|
|
218
|
+
global loop
|
|
219
|
+
assert asyncio.get_running_loop() is loop
|
|
220
|
+
"""
|
|
221
|
+
)
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
result = pytester.runpytest("--asyncio-mode=auto")
|
|
225
|
+
result.assert_outcomes(passed=1)
|
|
@@ -80,3 +80,61 @@ def test_event_loop_fixture_handles_unclosed_async_gen(
|
|
|
80
80
|
)
|
|
81
81
|
result = pytester.runpytest_subprocess("--asyncio-mode=strict", "-W", "default")
|
|
82
82
|
result.assert_outcomes(passed=1, warnings=0)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_event_loop_already_closed(
|
|
86
|
+
pytester: Pytester,
|
|
87
|
+
):
|
|
88
|
+
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
|
|
89
|
+
pytester.makepyfile(
|
|
90
|
+
dedent(
|
|
91
|
+
"""\
|
|
92
|
+
import asyncio
|
|
93
|
+
import pytest
|
|
94
|
+
import pytest_asyncio
|
|
95
|
+
pytest_plugins = 'pytest_asyncio'
|
|
96
|
+
|
|
97
|
+
@pytest_asyncio.fixture
|
|
98
|
+
async def _event_loop():
|
|
99
|
+
return asyncio.get_running_loop()
|
|
100
|
+
|
|
101
|
+
@pytest.fixture
|
|
102
|
+
def cleanup_after(_event_loop):
|
|
103
|
+
yield
|
|
104
|
+
# fixture has its own cleanup code
|
|
105
|
+
_event_loop.close()
|
|
106
|
+
|
|
107
|
+
@pytest.mark.asyncio
|
|
108
|
+
async def test_something(cleanup_after):
|
|
109
|
+
await asyncio.sleep(0.01)
|
|
110
|
+
"""
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
result = pytester.runpytest_subprocess("--asyncio-mode=strict", "-W", "default")
|
|
114
|
+
result.assert_outcomes(passed=1, warnings=0)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def test_event_loop_fixture_asyncgen_error(
|
|
118
|
+
pytester: Pytester,
|
|
119
|
+
):
|
|
120
|
+
pytester.makeini("[pytest]\nasyncio_default_fixture_loop_scope = function")
|
|
121
|
+
pytester.makepyfile(
|
|
122
|
+
dedent(
|
|
123
|
+
"""\
|
|
124
|
+
import asyncio
|
|
125
|
+
import pytest
|
|
126
|
+
|
|
127
|
+
pytest_plugins = 'pytest_asyncio'
|
|
128
|
+
|
|
129
|
+
@pytest.mark.asyncio
|
|
130
|
+
async def test_something():
|
|
131
|
+
# mock shutdown_asyncgen failure
|
|
132
|
+
loop = asyncio.get_running_loop()
|
|
133
|
+
async def fail():
|
|
134
|
+
raise RuntimeError("mock error cleaning up...")
|
|
135
|
+
loop.shutdown_asyncgens = fail
|
|
136
|
+
"""
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
result = pytester.runpytest_subprocess("--asyncio-mode=strict", "-W", "default")
|
|
140
|
+
result.assert_outcomes(passed=1, warnings=1)
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
==========================================================
|
|
2
|
-
How to run all tests in the session in the same event loop
|
|
3
|
-
==========================================================
|
|
4
|
-
All tests can be run inside the same event loop by marking them with ``pytest.mark.asyncio(loop_scope="session")``.
|
|
5
|
-
The easiest way to mark all tests is via a ``pytest_collection_modifyitems`` hook in the ``conftest.py`` at the root folder of your test suite.
|
|
6
|
-
|
|
7
|
-
.. include:: session_scoped_loop_example.py
|
|
8
|
-
:code: python
|
|
9
|
-
|
|
10
|
-
Note that this will also override *all* manually applied marks in *strict* mode.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from pytest_asyncio import is_async_test
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def pytest_collection_modifyitems(items):
|
|
7
|
-
pytest_asyncio_tests = (item for item in items if is_async_test(item))
|
|
8
|
-
session_scope_marker = pytest.mark.asyncio(loop_scope="session")
|
|
9
|
-
for async_test in pytest_asyncio_tests:
|
|
10
|
-
async_test.add_marker(session_scope_marker, append=False)
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
from textwrap import dedent
|
|
3
|
-
|
|
4
|
-
from pytest import Pytester
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def test_session_scoped_loop_configuration_works_in_auto_mode(
|
|
8
|
-
pytester: Pytester,
|
|
9
|
-
):
|
|
10
|
-
session_wide_mark_conftest = (
|
|
11
|
-
Path(__file__).parent / "session_scoped_loop_example.py"
|
|
12
|
-
)
|
|
13
|
-
pytester.makeconftest(session_wide_mark_conftest.read_text())
|
|
14
|
-
pytester.makepyfile(
|
|
15
|
-
dedent(
|
|
16
|
-
"""\
|
|
17
|
-
import asyncio
|
|
18
|
-
|
|
19
|
-
session_loop = None
|
|
20
|
-
|
|
21
|
-
async def test_store_loop(request):
|
|
22
|
-
global session_loop
|
|
23
|
-
session_loop = asyncio.get_running_loop()
|
|
24
|
-
|
|
25
|
-
async def test_compare_loop(request):
|
|
26
|
-
global session_loop
|
|
27
|
-
assert asyncio.get_running_loop() is session_loop
|
|
28
|
-
"""
|
|
29
|
-
)
|
|
30
|
-
)
|
|
31
|
-
result = pytester.runpytest_subprocess("--asyncio-mode=auto")
|
|
32
|
-
result.assert_outcomes(passed=2)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def test_session_scoped_loop_configuration_works_in_strict_mode(
|
|
36
|
-
pytester: Pytester,
|
|
37
|
-
):
|
|
38
|
-
session_wide_mark_conftest = (
|
|
39
|
-
Path(__file__).parent / "session_scoped_loop_example.py"
|
|
40
|
-
)
|
|
41
|
-
pytester.makeconftest(session_wide_mark_conftest.read_text())
|
|
42
|
-
pytester.makepyfile(
|
|
43
|
-
dedent(
|
|
44
|
-
"""\
|
|
45
|
-
import asyncio
|
|
46
|
-
import pytest
|
|
47
|
-
|
|
48
|
-
session_loop = None
|
|
49
|
-
|
|
50
|
-
@pytest.mark.asyncio
|
|
51
|
-
async def test_store_loop(request):
|
|
52
|
-
global session_loop
|
|
53
|
-
session_loop = asyncio.get_running_loop()
|
|
54
|
-
|
|
55
|
-
@pytest.mark.asyncio
|
|
56
|
-
async def test_compare_loop(request):
|
|
57
|
-
global session_loop
|
|
58
|
-
assert asyncio.get_running_loop() is session_loop
|
|
59
|
-
"""
|
|
60
|
-
)
|
|
61
|
-
)
|
|
62
|
-
result = pytester.runpytest_subprocess("--asyncio-mode=strict")
|
|
63
|
-
result.assert_outcomes(passed=2)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/change_default_fixture_loop.rst
RENAMED
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/change_fixture_loop_example.py
RENAMED
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/class_scoped_loop_example.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/module_scoped_loop_example.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/multiple_loops_example.py
RENAMED
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/package_scoped_loop_example.py
RENAMED
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/run_class_tests_in_same_loop.rst
RENAMED
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/run_module_tests_in_same_loop.rst
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/how-to-guides/test_item_is_async_example.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/fixtures/event_loop_example.py
RENAMED
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/docs/reference/fixtures/event_loop_policy_example.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/pytest_asyncio.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_async_fixtures_scope.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_async_gen_fixtures.py
RENAMED
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_parametrized_loop.py
RENAMED
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/async_fixtures/test_shared_module_fixture.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/loop_fixture_scope/test_loop_fixture_scope.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_asyncio-0.25.2 → pytest_asyncio-0.26.0}/tests/test_explicit_event_loop_fixture_request.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|