diff --git a/AUTHORS b/AUTHORS index ab84a3e5289..cdc256029b9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -90,6 +90,7 @@ Dmitry Pribysh Duncan Betts Edison Gustavo Muenz Edoardo Batini +Edson Tadeu M. Manoel Eduardo Schettino Eli Boyarski Elizaveta Shashkova diff --git a/changelog/7856.bugfix.rst b/changelog/7856.bugfix.rst new file mode 100644 index 00000000000..5f158b4bdad --- /dev/null +++ b/changelog/7856.bugfix.rst @@ -0,0 +1 @@ +An error with ``--import-mode=importlib`` used with modules containing dataclasses or pickle was fixed. diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index 0bc5bff2bb5..7df0d4ec5f8 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -480,6 +480,7 @@ def import_path( "Can't find module {} at location {}".format(module_name, str(path)) ) mod = importlib.util.module_from_spec(spec) + sys.modules[module_name] = mod spec.loader.exec_module(mod) # type: ignore[union-attr] return mod diff --git a/testing/test_pathlib.py b/testing/test_pathlib.py index e37b33847ee..ebf37a31394 100644 --- a/testing/test_pathlib.py +++ b/testing/test_pathlib.py @@ -401,3 +401,54 @@ def test_commonpath() -> None: assert commonpath(subpath, path) == path assert commonpath(Path(str(path) + "suffix"), path) == path.parent assert commonpath(path, path.parent.parent) == path.parent.parent + + +@pytest.fixture +def module_with_dataclass(tmpdir): + fn = tmpdir.join("test_dataclass.py") + fn.write( + dedent(f"""\ + {'from __future__ import annotations' if (3, 7) <= sys.version_info < (3, 10) else ''} + + from dataclasses import dataclass + + @dataclass + class DataClass: + value: str + + def test_dataclass(): + assert DataClass(value='test').value == 'test' + """ + ) + ) + return fn + + +@pytest.fixture +def module_with_pickle(tmpdir): + fn = tmpdir.join("test_dataclass.py") + fn.write( + dedent("""\ + import pickle + + def do_action(): + pass + + def test_pickle(): + pickle.dumps(do_action) + """ + ) + ) + return fn + + +def test_importmode_importlib_with_dataclass(module_with_dataclass): + """Ensure that importlib mode works with a module containing dataclasses""" + module = import_path(module_with_dataclass, mode="importlib") + module.test_dataclass() + + +def test_importmode_importlib_with_pickle(module_with_pickle): + """Ensure that importlib mode works with pickle""" + module = import_path(module_with_pickle, mode="importlib") + module.test_pickle()