From 9163efa4f35d54fb8dbed766207e6690b75199d4 Mon Sep 17 00:00:00 2001 From: Joey Leake Date: Mon, 31 Aug 2026 13:18:23 -0400 Subject: [PATCH] Stop configuring the root logger on import logging.basicConfig() at import time in __init__.py silently clobbered the embedding application's own logging setup. Replace it with a NullHandler so the library stays silent by default without touching global config. Also stop MeshCore.__init__ from unconditionally forcing the "meshcore" logger to INFO when neither debug= nor only_error= is passed - only set a level when the caller explicitly asks for one, otherwise leave whatever the app already configured alone. Document the idiomatic logging setup for consumers in README.md. Fixes #58 --- README.md | 9 +++++++++ src/meshcore/__init__.py | 6 ++++-- src/meshcore/meshcore.py | 6 +++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 58ea6f6..c9a0b3e 100644 --- a/README.md +++ b/README.md @@ -371,6 +371,15 @@ meshcore = await MeshCore.create_serial("/dev/ttyUSB0", debug=True) This logs detailed information about commands sent and events received. +meshcore_py does not configure Python's root logger or call `logging.basicConfig()` itself - it only attaches a `NullHandler` so it stays silent by default. To see its logs, configure logging in your own application, e.g.: + +```python +import logging + +logging.basicConfig(level=logging.INFO) +logging.getLogger("meshcore").setLevel(logging.DEBUG) +``` + ## Common Examples ### Sending Messages to Contacts diff --git a/src/meshcore/__init__.py b/src/meshcore/__init__.py index 6c7feb3..81b4f51 100644 --- a/src/meshcore/__init__.py +++ b/src/meshcore/__init__.py @@ -9,9 +9,11 @@ from .serial_cx import SerialConnection from .tcp_cx import TCPConnection -# Setup default logger -logging.basicConfig(level=logging.INFO) +# Setup default logger. Libraries must not configure the root logger (that's +# the embedding application's call) - a NullHandler just silences the "no +# handlers found" warning when the app hasn't configured logging at all. logger = logging.getLogger(__name__) +logger.addHandler(logging.NullHandler()) __all__ = [ "BinaryReqType", diff --git a/src/meshcore/meshcore.py b/src/meshcore/meshcore.py index a7e06c1..73b154e 100644 --- a/src/meshcore/meshcore.py +++ b/src/meshcore/meshcore.py @@ -46,13 +46,13 @@ def __init__( self.commands = CommandHandler(default_timeout=default_timeout) self.commands.set_contact_getter_by_prefix(self.get_contact_by_key_prefix) - # Set up logger + # Set up logger. Only override the level when the caller explicitly + # asked for debug/only_error behavior - otherwise leave whatever + # level the embedding app already configured alone. if debug: logger.setLevel(logging.DEBUG) elif only_error: logger.setLevel(logging.ERROR) - else: - logger.setLevel(logging.INFO) # Set up connections self.commands.set_connection(self.connection_manager)