Skip to content

Commit a88de75

Browse files
committed
[fix] Fixes a bug that caused an INTERNALERROR when an __init__.py raised an error.
Signed-off-by: Michael Seifert <m.seifert@digitalernachschub.de>
1 parent 3e67b0d commit a88de75

File tree

2 files changed

+37
-12
lines changed

2 files changed

+37
-12
lines changed

pytest_asyncio/plugin.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,24 @@ def _patched_collect():
620620
collector.obj.__pytest_asyncio_scoped_event_loop = scoped_event_loop
621621
return collector.__original_collect()
622622

623+
collector.__original_collect = collector.collect
624+
collector.collect = _patched_collect
625+
elif type(collector) is Package:
626+
627+
def _patched_collect():
628+
# When collector is a package, collector.obj is the package's __init__.py.
629+
# pytest doesn't seem to collect fixtures in __init__.py.
630+
# Using parsefactories to collect fixtures in __init__.py their baseid will
631+
# end with "__init__.py", thus limiting the scope of the fixture to the
632+
# init module. Therefore, we tell the pluginmanager explicitly to collect
633+
# the fixtures in the init module, but strip "__init__.py" from the baseid
634+
# Possibly related to https://github.com/pytest-dev/pytest/issues/4085
635+
collector.obj.__pytest_asyncio_scoped_event_loop = scoped_event_loop
636+
fixturemanager = collector.config.pluginmanager.get_plugin("funcmanage")
637+
package_node_id = _removesuffix(collector.nodeid, "__init__.py")
638+
fixturemanager.parsefactories(collector.obj, nodeid=package_node_id)
639+
return collector.__original_collect()
640+
623641
collector.__original_collect = collector.collect
624642
collector.collect = _patched_collect
625643
else:
@@ -628,17 +646,6 @@ def _patched_collect():
628646
if pyobject is None:
629647
return
630648
pyobject.__pytest_asyncio_scoped_event_loop = scoped_event_loop
631-
# When collector is a package, collector.obj is the package's __init__.py.
632-
# pytest doesn't seem to collect fixtures in __init__.py.
633-
# Using parsefactories to collect fixtures in __init__.py their baseid will end
634-
# with "__init__.py", thus limiting the scope of the fixture to the init module.
635-
# Therefore, we tell the pluginmanager explicitly to collect the fixtures
636-
# in the init module, but strip "__init__.py" from the baseid
637-
# Possibly related to https://github.com/pytest-dev/pytest/issues/4085
638-
if isinstance(collector, Package):
639-
fixturemanager = collector.config.pluginmanager.get_plugin("funcmanage")
640-
package_node_id = _removesuffix(collector.nodeid, "__init__.py")
641-
fixturemanager.parsefactories(collector.obj, nodeid=package_node_id)
642649

643650

644651
def _removesuffix(s: str, suffix: str) -> str:

tests/test_import.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from pytest import Pytester
44

55

6-
def test_import_warning(pytester: Pytester):
6+
def test_import_warning_does_not_cause_internal_error(pytester: Pytester):
77
pytester.makepyfile(
88
dedent(
99
"""\
@@ -16,3 +16,21 @@ async def test_errors_out():
1616
)
1717
result = pytester.runpytest("--asyncio-mode=auto")
1818
result.assert_outcomes(errors=1)
19+
20+
21+
def test_import_warning_in_package_does_not_cause_internal_error(pytester: Pytester):
22+
pytester.makepyfile(
23+
__init__=dedent(
24+
"""\
25+
raise ImportWarning()
26+
"""
27+
),
28+
test_a=dedent(
29+
"""\
30+
async def test_errors_out():
31+
pass
32+
"""
33+
),
34+
)
35+
result = pytester.runpytest("--asyncio-mode=auto")
36+
result.assert_outcomes(errors=1)

0 commit comments

Comments
 (0)