Skip to content

Commit 94e0e28

Browse files
committed
Fix getting module with --import-mode=importlib
1 parent 8008c0f commit 94e0e28

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

pytest_bdd/scenario.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import inspect
1515
import os
1616
import re
17+
import sys
1718

1819
import pytest
1920

@@ -283,13 +284,39 @@ def get_name():
283284
suffix = "_{0}".format(index)
284285

285286

287+
def find_module(frame):
288+
"""Get the module object for the given frame."""
289+
module = inspect.getmodule(frame[0])
290+
if module is not None:
291+
return module
292+
293+
# Probably using pytest's importlib mode, let's try to get the module
294+
# from the filename.
295+
# The imports will only work on Python 3 (hence why they are here rather
296+
# than at module level). However, we should only ever get here on Python 3,
297+
# because pytest's --import-module=importlib is in a Python 3 only release
298+
# of pytest.
299+
import pathlib
300+
import importlib.util
301+
302+
path = pathlib.Path(frame.filename)
303+
module_name = path.stem
304+
for meta_importer in sys.meta_path:
305+
spec = meta_importer.find_spec(module_name, [str(path.parent)])
306+
if spec is not None:
307+
break
308+
assert spec is not None
309+
310+
return importlib.util.module_from_spec(spec)
311+
312+
286313
def scenarios(*feature_paths, **kwargs):
287314
"""Parse features from the paths and put all found scenarios in the caller module.
288315
289316
:param *feature_paths: feature file paths to use for scenarios
290317
"""
291318
frame = inspect.stack()[1]
292-
module = inspect.getmodule(frame[0])
319+
module = find_module(frame)
293320

294321
features_base_dir = kwargs.get("features_base_dir")
295322
if features_base_dir is None:

0 commit comments

Comments
 (0)