From 463ce984677f0ac965f225c3b7ac14ebf43adad6 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Sun, 14 Jan 2024 19:53:35 +0100 Subject: [PATCH] [fix] Avoid trying to install scoped event loops for unknown test collector types. Signed-off-by: Michael Seifert --- docs/source/reference/changelog.rst | 1 + pytest_asyncio/plugin.py | 40 ++++++++++++++--------------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/docs/source/reference/changelog.rst b/docs/source/reference/changelog.rst index dfcc7c05..2fde5a76 100644 --- a/docs/source/reference/changelog.rst +++ b/docs/source/reference/changelog.rst @@ -5,6 +5,7 @@ Changelog 0.23.4 (UNRELEASED) =================== - pytest-asyncio no longer imports additional, unrelated packages during test collection `#729 `_ +- Addresses further issues that caused an internal pytest error during test collection Known issues ------------ diff --git a/pytest_asyncio/plugin.py b/pytest_asyncio/plugin.py index 5bf8d3b5..4729b267 100644 --- a/pytest_asyncio/plugin.py +++ b/pytest_asyncio/plugin.py @@ -608,21 +608,7 @@ def scoped_event_loop( # know it exists. We work around this by attaching the fixture function to the # collected Python object, where it will be picked up by pytest.Class.collect() # or pytest.Module.collect(), respectively - if type(collector) is Module: - # Accessing Module.obj triggers a module import executing module-level - # statements. A module-level pytest.skip statement raises the "Skipped" - # OutcomeException or a Collector.CollectError, if the "allow_module_level" - # kwargs is missing. These cases are handled correctly when they happen inside - # Collector.collect(), but this hook runs before the actual collect call. - # Therefore, we monkey patch Module.collect to add the scoped fixture to the - # module before it runs the actual collection. - def _patched_collect(): - collector.obj.__pytest_asyncio_scoped_event_loop = scoped_event_loop - return collector.__original_collect() - - collector.__original_collect = collector.collect - collector.collect = _patched_collect - elif type(collector) is Package: + if type(collector) is Package: def _patched_collect(): # When collector is a Package, collector.obj is the package's @@ -648,12 +634,24 @@ def _patched_collect(): collector.__original_collect = collector.collect collector.collect = _patched_collect - else: - pyobject = collector.obj - # If the collected module is a DoctestTextfile, collector.obj is None - if pyobject is None: - return - pyobject.__pytest_asyncio_scoped_event_loop = scoped_event_loop + elif isinstance(collector, Module): + # Accessing Module.obj triggers a module import executing module-level + # statements. A module-level pytest.skip statement raises the "Skipped" + # OutcomeException or a Collector.CollectError, if the "allow_module_level" + # kwargs is missing. These cases are handled correctly when they happen inside + # Collector.collect(), but this hook runs before the actual collect call. + # Therefore, we monkey patch Module.collect to add the scoped fixture to the + # module before it runs the actual collection. + def _patched_collect(): + # If the collected module is a DoctestTextfile, collector.obj is None + if collector.obj is not None: + collector.obj.__pytest_asyncio_scoped_event_loop = scoped_event_loop + return collector.__original_collect() + + collector.__original_collect = collector.collect + collector.collect = _patched_collect + elif isinstance(collector, Class): + collector.obj.__pytest_asyncio_scoped_event_loop = scoped_event_loop def _removesuffix(s: str, suffix: str) -> str: