diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index 92deb6539..db3674930 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -179,11 +179,13 @@ class AssertionRewritingHook(object): The named module or package as well as any nested modules will be rewritten on import. """ - already_imported = set(names).intersection(set(sys.modules)) - if already_imported: - for name in already_imported: - if name not in self._rewritten_names: - self._warn_already_imported(name) + already_imported = (set(names) + .intersection(sys.modules) + .difference(self._rewritten_names)) + for name in already_imported: + if not AssertionRewriter.is_rewrite_disabled( + sys.modules[name].__doc__ or ""): + self._warn_already_imported(name) self._must_rewrite.update(names) def _warn_already_imported(self, name): @@ -635,7 +637,8 @@ class AssertionRewriter(ast.NodeVisitor): not isinstance(field, ast.expr)): nodes.append(field) - def is_rewrite_disabled(self, docstring): + @staticmethod + def is_rewrite_disabled(docstring): return "PYTEST_DONT_REWRITE" in docstring def variable(self): diff --git a/_pytest/pytester.py b/_pytest/pytester.py index 0b25d839b..ee7ca24cd 100644 --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -347,7 +347,7 @@ class RunResult: :stdout: :py:class:`LineMatcher` of stdout, use ``stdout.str()`` to reconstruct stdout or the commonly used ``stdout.fnmatch_lines()`` method - :stderrr: :py:class:`LineMatcher` of stderr + :stderr: :py:class:`LineMatcher` of stderr :duration: duration in seconds """ diff --git a/changelog/2995.bugfix b/changelog/2995.bugfix new file mode 100644 index 000000000..7a3dde4c8 --- /dev/null +++ b/changelog/2995.bugfix @@ -0,0 +1 @@ +``PYTEST_DONT_REWRITE`` is now checked for plugins too rather than only for test modules. diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 0e22c6dac..77cfd2900 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -128,6 +128,16 @@ class TestAssertionRewrite(object): assert len(m.body) == 1 assert m.body[0].msg is None + def test_dont_rewrite_plugin(self, testdir): + contents = { + "conftest.py": "pytest_plugins = 'plugin'; import plugin", + "plugin.py": "'PYTEST_DONT_REWRITE'", + "test_foo.py": "def test_foo(): pass", + } + testdir.makepyfile(**contents) + result = testdir.runpytest_subprocess() + assert "warnings" not in "".join(result.outlines) + def test_name(self): def f(): assert False