Skip to content

Commit e94fd5d

Browse files
committed
fix: LoggingHelper.set_level() now updates logger level, not just handler
Signed-off-by: suhr25 <suhridmarwah07@gmail.com>
1 parent ea9e24c commit e94fd5d

2 files changed

Lines changed: 46 additions & 0 deletions

File tree

malariagen_data/util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,7 @@ def info(self, msg):
929929
self.flush()
930930

931931
def set_level(self, level):
932+
self._logger.setLevel(level)
932933
if self._handler is not None:
933934
self._handler.setLevel(level)
934935

tests/anoph/test_base.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import io
2+
import logging
3+
14
import numpy as np
25
import pandas as pd
36
import pytest
@@ -8,6 +11,7 @@
811
from malariagen_data import ag3 as _ag3
912
from malariagen_data import adir1 as _adir1
1013
from malariagen_data.anoph.base import AnophelesBase
14+
from malariagen_data.util import LoggingHelper
1115

1216

1317
@pytest.fixture
@@ -258,6 +262,47 @@ def test_lookup_study(fixture, api):
258262
api.lookup_study("foobar")
259263

260264

265+
def test_logging_helper_no_handler_accumulation():
266+
# Regression test: repeated LoggingHelper construction on the same logger
267+
# name must not accumulate handlers (StreamHandler leak, FileHandler FD leak).
268+
logger_name = "test_logging_helper_no_handler_accumulation"
269+
for _ in range(10):
270+
LoggingHelper(name=logger_name, out=io.StringIO())
271+
logger = logging.getLogger(logger_name)
272+
assert (
273+
len(logger.handlers) <= 1
274+
), f"Handler leak: {len(logger.handlers)} handlers after 10 instantiations"
275+
276+
277+
def test_logging_helper_no_duplicate_output():
278+
# Regression test: a message emitted after N instantiations must appear
279+
# exactly once in the output stream.
280+
logger_name = "test_logging_helper_no_duplicate_output"
281+
out = io.StringIO()
282+
for _ in range(5):
283+
helper = LoggingHelper(name=logger_name, out=out)
284+
helper.info("sentinel")
285+
output = out.getvalue()
286+
assert (
287+
output.count("sentinel") == 1
288+
), f"Duplicate log output: 'sentinel' appeared {output.count('sentinel')} times"
289+
290+
291+
def test_logging_helper_set_level_updates_logger():
292+
# Regression test: set_level() must update the logger level, not just the
293+
# handler level. Without fixing the logger, the logger itself would filter
294+
# out DEBUG messages before they ever reached the handler.
295+
logger_name = "test_logging_helper_set_level_updates_logger"
296+
out = io.StringIO()
297+
helper = LoggingHelper(name=logger_name, out=out, debug=False)
298+
helper.set_level(logging.DEBUG)
299+
helper.debug("should appear")
300+
output = out.getvalue()
301+
assert "should appear" in output, (
302+
"set_level(DEBUG) had no effect: debug message was silently dropped"
303+
)
304+
305+
261306
def _strip_terms_of_use_from_manifest(manifest_path):
262307
"""Rewrite a manifest TSV file without terms-of-use columns."""
263308
df = pd.read_csv(manifest_path, sep="\t")

0 commit comments

Comments
 (0)