Skip to content

Fix event_loop_policy parametrization scope#1454

Open
puneetdixit200 wants to merge 3 commits into
pytest-dev:mainfrom
puneetdixit200:fix/796-event-loop-policy
Open

Fix event_loop_policy parametrization scope#1454
puneetdixit200 wants to merge 3 commits into
pytest-dev:mainfrom
puneetdixit200:fix/796-event-loop-policy

Conversation

@puneetdixit200
Copy link
Copy Markdown

Summary

  • stop making the default event_loop_policy fixture autouse
  • request event_loop_policy only for pytest-asyncio tests and tests using asyncio fixtures, so plain sync tests are not parametrized
  • add regression coverage for plain sync tests and sync tests that use asyncio fixtures
  • avoid re-importing pytest_asyncio in one subprocess test under -W error; the entry point already loads the plugin

Fixes #796

Tests

  • .venv/bin/python -m pytest -q
  • .venv/bin/python -m pytest tests/test_set_event_loop.py::test_asyncio_run_after_async_fixture_does_not_leak_loop tests/markers/test_function_scope.py::test_parametrized_loop_policy_does_not_parametrize_sync_tests tests/markers/test_function_scope.py::test_parametrized_loop_policy_parametrizes_sync_tests_with_async_fixtures -q
  • .venv/bin/python -m pytest tests/markers/test_function_scope.py tests/markers/test_module_scope.py tests/markers/test_class_scope.py tests/markers/test_session_scope.py tests/test_loop_factory_parametrization.py tests/test_asyncio_fixture.py -q
  • .venv/bin/python -m ruff check pytest_asyncio/plugin.py tests/markers/test_function_scope.py tests/test_set_event_loop.py
  • .venv/bin/python -m mypy --python-version 3.13 pytest_asyncio/
  • .venv/bin/python -m pyright --pythonpath .venv/bin/python --pythonversion 3.13 pytest_asyncio/
  • git diff --check

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.75%. Comparing base (9190447) to head (cd89044).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1454      +/-   ##
==========================================
+ Coverage   94.50%   94.75%   +0.24%     
==========================================
  Files           2        2              
  Lines         510      534      +24     
  Branches       62       69       +7     
==========================================
+ Hits          482      506      +24     
  Misses         22       22              
  Partials        6        6              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@golikovichev golikovichev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approach looks clean. Dropping autouse=True from the event_loop_policy fixture and gating its injection on pytest_generate_tests only when the test uses asyncio fixtures (or is async itself) is the right shape to fix #796 without breaking the loop-policy parametrization use case.

Two observations from a downstream-user read:

  1. _uses_asyncio_fixtures walks metafunc._arg2fixturedefs and short-circuits on first match. In AUTO mode it falls back to _is_coroutine_or_asyncgen, which is what catches sync tests that happen to request async fixtures - exactly the gap #796 surfaced. Worth keeping the AUTO branch as-is even though it adds a per-fixture check.
  2. The negative-case regression test test_parametrized_loop_policy_does_not_parametrize_sync_tests is paired with test_parametrized_loop_policy_parametrizes_sync_tests_with_async_fixtures (positive case). Good coverage pattern.

CI green across the full matrix (Py 3.10-3.14 + Windows + pytest main). Lint + mypy + pyright also clean per PR body.

Not a maintainer, leaving this as a non-blocking review.

Comment thread pytest_asyncio/plugin.py
Copy link
Copy Markdown

@golikovichev golikovichev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch with the MRE. My read was too superficial - I focused on the autouse change and the regression test pair, but missed that _add_fixture_to_metafunc injecting event_loop_policy breaks valid fixture chains where event_loop_policy depends on another parametrized fixture (like your policy). The patch shifts the parametrization origin out from under pytest's resolver.

Leaving this to the PR author and maintainers.

Copy link
Copy Markdown

@golikovichev golikovichev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed after 8305b3a. The new _add_fixture_to_metafunc walks the closure via fixturemanager.getfixtureclosure() instead of attaching just the named fixture, so parametrize chains like event_loop_policy(policy) from @tjkuson's MRE are now preserved end to end.

The new test test_parametrized_loop_policy_can_depend_on_parametrized_fixture mirrors the MRE shape directly (parametrized policy fixture, event_loop_policy(policy) depending on it, both async and sync tests), so the regression is pinned. The two surrounding sync-vs-async parametrization tests cover the adjacent cases I would have asked for, so I do not have anything to add.

Sorry again for missing this in my first read - your MRE made the failure mode obvious, and the fix landed cleanly.

gmail-precheck-done

@puneetdixit200
Copy link
Copy Markdown
Author

Pushed cd89044 to cover the remaining event loop policy fixture discovery paths from the Codecov report.

Added coverage for auto-mode regular async fixtures and strict-mode unmarked async tests that still need the policy fixture closure.

Verified locally:

  • coverage run -m pytest -q (304 passed)
  • coverage report -m pytest_asyncio/plugin.py (the previously missing new lines are now covered)
  • python -m pytest tests/markers/test_function_scope.py tests/test_set_event_loop.py -q (78 passed)
  • ruff check tests/markers/test_function_scope.py
  • git diff --check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parametrizing event_loop_policy parametrizes all tests

4 participants