Skip to content

Commit

Permalink
Create LogCaptureHandler if necessary (closes #6240)
Browse files Browse the repository at this point in the history
  • Loading branch information
Felix Nieuwenhuizen committed May 13, 2020
1 parent 6df0b9c commit 4dfc461
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 1 deletion.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ Erik M. Bray
Evan Kepner
Fabien Zarifian
Fabio Zadrozny
Felix Nieuwenhuizen
Feng Ma
Florian Bruhin
Floris Bruynooghe
Expand Down
2 changes: 2 additions & 0 deletions changelog/6240.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fixes an issue where logging during collection step caused duplication of log
messages to stderr.
8 changes: 7 additions & 1 deletion src/_pytest/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,13 @@ def pytest_collection(self) -> Generator[None, None, None]:
with catching_logs(self.log_file_handler, level=self.log_file_level):
yield
else:
yield
# Add a dummy handler to ensure logging.root.handlers is not empty.
# If it were empty, then a `logging.warning()` call (and similar) during collection
# would trigger a `logging.basicConfig()` call, which would add a `StreamHandler`
# handler, which would cause all subsequent logs which reach the root to be also
# printed to stdout, which we don't want (issue #6240).
with catching_logs(logging.NullHandler()):
yield

@contextmanager
def _runtest_for(self, item, when):
Expand Down
29 changes: 29 additions & 0 deletions testing/test_capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -1493,3 +1493,32 @@ def test__get_multicapture() -> None:
pytest.raises(ValueError, _get_multicapture, "unknown").match(
r"^unknown capturing method: 'unknown'"
)


def test_logging_while_collecting(testdir):
"""Issue #6240: Calls to logging.xxx() during collection causes all logging calls to be duplicated to stderr"""
p = testdir.makepyfile(
"""\
import logging
logging.warning("during collection")
def test_logging():
logging.warning("during call")
assert False
"""
)
result = testdir.runpytest_subprocess(p)
assert result.ret == ExitCode.TESTS_FAILED
result.stdout.fnmatch_lines(
[
"*test_*.py F*",
"====* FAILURES *====",
"____*____",
"*--- Captured log call*",
"WARNING * during call",
"*1 failed*",
]
)
result.stdout.no_fnmatch_line("*Captured stderr call*")
result.stdout.no_fnmatch_line("*during collection*")

0 comments on commit 4dfc461

Please sign in to comment.