Skip to content

Commit

Permalink
Bug fix: Restore StandardErrorHandler functionality
Browse files Browse the repository at this point in the history
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
  • Loading branch information
xolox committed Jun 11, 2021
1 parent 1851069 commit 8a2f2d1
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
9 changes: 6 additions & 3 deletions coloredlogs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Colored terminal output for Python's logging module.
#
# Author: Peter Odding <peter@peterodding.com>
# Last Change: December 10, 2020
# Last Change: June 11, 2021
# URL: https://coloredlogs.readthedocs.io

"""
Expand Down Expand Up @@ -394,7 +394,7 @@ def install(level=None, **kw):
"""
logger = kw.get('logger') or logging.getLogger()
reconfigure = kw.get('reconfigure', True)
stream = kw.get('stream', sys.stderr)
stream = kw.get('stream') or sys.stderr
style = check_style(kw.get('style') or DEFAULT_FORMAT_STYLE)
# Get the log level from an argument, environment variable or default and
# convert the names of log levels to numbers to enable numeric comparison.
Expand Down Expand Up @@ -453,7 +453,10 @@ def install(level=None, **kw):
# Create a stream handler and make sure to preserve any filters
# the current handler may have (if an existing handler is found).
filters = handler.filters if handler else None
handler = logging.StreamHandler(stream) if stream else StandardErrorHandler()
if stream is sys.stderr:
handler = StandardErrorHandler()
else:
handler = logging.StreamHandler(stream)
handler.setLevel(level)
if filters:
handler.filters = filters
Expand Down
18 changes: 17 additions & 1 deletion coloredlogs/tests.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Automated tests for the `coloredlogs' package.
#
# Author: Peter Odding <peter@peterodding.com>
# Last Change: December 10, 2020
# Last Change: June 11, 2021
# URL: https://coloredlogs.readthedocs.io

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

def test_dynamic_stderr_lookup(self):
"""Make sure coloredlogs.install() uses StandardErrorHandler when possible."""
coloredlogs.install()
# Redirect sys.stderr to a temporary buffer.
initial_stream = StringIO()
initial_text = "Which stream will receive this text?"
with PatchedAttribute(sys, 'stderr', initial_stream):
logging.info(initial_text)
assert initial_text in initial_stream.getvalue()
# Redirect sys.stderr again, to a different destination.
subsequent_stream = StringIO()
subsequent_text = "And which stream will receive this other text?"
with PatchedAttribute(sys, 'stderr', subsequent_stream):
logging.info(subsequent_text)
assert subsequent_text in subsequent_stream.getvalue()

def test_force_enable(self):
"""Make sure ANSI escape sequences can be forced (bypassing auto-detection)."""
interpreter = subprocess.Popen([
Expand Down

0 comments on commit 8a2f2d1

Please sign in to comment.