Create LogCaptureHandler if necessary (closes #6240)

This commit is contained in:
Felix Nieuwenhuizen 2019-11-27 11:50:22 +01:00
parent 6df0b9c41a
commit 4dfc461036
4 changed files with 39 additions and 1 deletions

View File

@ -99,6 +99,7 @@ Erik M. Bray
Evan Kepner Evan Kepner
Fabien Zarifian Fabien Zarifian
Fabio Zadrozny Fabio Zadrozny
Felix Nieuwenhuizen
Feng Ma Feng Ma
Florian Bruhin Florian Bruhin
Floris Bruynooghe Floris Bruynooghe

View File

@ -0,0 +1,2 @@
Fixes an issue where logging during collection step caused duplication of log
messages to stderr.

View File

@ -613,6 +613,12 @@ class LoggingPlugin:
with catching_logs(self.log_file_handler, level=self.log_file_level): with catching_logs(self.log_file_handler, level=self.log_file_level):
yield yield
else: else:
# 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 yield
@contextmanager @contextmanager

View File

@ -1493,3 +1493,32 @@ def test__get_multicapture() -> None:
pytest.raises(ValueError, _get_multicapture, "unknown").match( pytest.raises(ValueError, _get_multicapture, "unknown").match(
r"^unknown capturing method: 'unknown'" 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*")