Skip to content

Commit 8a2f2d1

Browse files
committed
Bug fix: Restore StandardErrorHandler functionality
The StandardErrorHandler class is responsible for dynamically resolving (looking up the value of) sys.stderr for each logged message instead of once when coloredlogs.install() is called. This was unintentionally broken by changes in 4f8c9aa which were released as part of coloredlogs version 14.1. This was brought to my attention by @hugovk here: xolox/python-humanfriendly#51
1 parent 1851069 commit 8a2f2d1

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

coloredlogs/__init__.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Colored terminal output for Python's logging module.
22
#
33
# Author: Peter Odding <[email protected]>
4-
# Last Change: December 10, 2020
4+
# Last Change: June 11, 2021
55
# URL: https://coloredlogs.readthedocs.io
66

77
"""
@@ -394,7 +394,7 @@ def install(level=None, **kw):
394394
"""
395395
logger = kw.get('logger') or logging.getLogger()
396396
reconfigure = kw.get('reconfigure', True)
397-
stream = kw.get('stream', sys.stderr)
397+
stream = kw.get('stream') or sys.stderr
398398
style = check_style(kw.get('style') or DEFAULT_FORMAT_STYLE)
399399
# Get the log level from an argument, environment variable or default and
400400
# convert the names of log levels to numbers to enable numeric comparison.
@@ -453,7 +453,10 @@ def install(level=None, **kw):
453453
# Create a stream handler and make sure to preserve any filters
454454
# the current handler may have (if an existing handler is found).
455455
filters = handler.filters if handler else None
456-
handler = logging.StreamHandler(stream) if stream else StandardErrorHandler()
456+
if stream is sys.stderr:
457+
handler = StandardErrorHandler()
458+
else:
459+
handler = logging.StreamHandler(stream)
457460
handler.setLevel(level)
458461
if filters:
459462
handler.filters = filters

coloredlogs/tests.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Automated tests for the `coloredlogs' package.
22
#
33
# Author: Peter Odding <[email protected]>
4-
# Last Change: December 10, 2020
4+
# Last Change: June 11, 2021
55
# URL: https://coloredlogs.readthedocs.io
66

77
"""Automated tests for the `coloredlogs` package."""
@@ -396,6 +396,22 @@ def test_plain_text_output_format(self):
396396
assert severity in last_line
397397
assert PLAIN_TEXT_PATTERN.match(last_line)
398398

399+
def test_dynamic_stderr_lookup(self):
400+
"""Make sure coloredlogs.install() uses StandardErrorHandler when possible."""
401+
coloredlogs.install()
402+
# Redirect sys.stderr to a temporary buffer.
403+
initial_stream = StringIO()
404+
initial_text = "Which stream will receive this text?"
405+
with PatchedAttribute(sys, 'stderr', initial_stream):
406+
logging.info(initial_text)
407+
assert initial_text in initial_stream.getvalue()
408+
# Redirect sys.stderr again, to a different destination.
409+
subsequent_stream = StringIO()
410+
subsequent_text = "And which stream will receive this other text?"
411+
with PatchedAttribute(sys, 'stderr', subsequent_stream):
412+
logging.info(subsequent_text)
413+
assert subsequent_text in subsequent_stream.getvalue()
414+
399415
def test_force_enable(self):
400416
"""Make sure ANSI escape sequences can be forced (bypassing auto-detection)."""
401417
interpreter = subprocess.Popen([

0 commit comments

Comments
 (0)