Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions mindtrace/registry/mindtrace/registry/core/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ def __init__(
Default ``True``.
**kwargs: Additional arguments forwarded to the backend.
"""
# Registry is a library-facing API; avoid leaking debug records into
# globally configured root handlers (e.g. ZenML import-time logging).
kwargs.setdefault("propagate", False)

super().__init__(**kwargs)

is_remote = backend is not None and not isinstance(backend, (str, Path, LocalRegistryBackend))
Expand Down
3 changes: 3 additions & 0 deletions tests/unit/mindtrace/registry/core/test_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -2496,6 +2496,9 @@ def test_load_missing_hash_warning(registry, test_config, caplog):
"""Test that load() logs warning when hash is missing from metadata."""
import yaml

# Explicitly opt-in to propagation for this capture-oriented test.
registry.logger.propagate = True

# Save an object
registry.save("test:config", test_config, version="1.0.0")

Expand Down
38 changes: 38 additions & 0 deletions tests/unit/mindtrace/registry/core/test_registry_logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import io
import logging
from tempfile import TemporaryDirectory

from mindtrace.registry import Registry


def test_registry_debug_logs_do_not_propagate_to_root_logger():
"""Registry debug logs should not leak to root handlers.

This reproduces the noisy-console scenario where another dependency
(e.g. ZenML) configures root handlers. Registry backend debug logs should
remain internal unless explicitly opted in.
"""
root_logger = logging.getLogger()
old_level = root_logger.level

capture_stream = io.StringIO()
capture_handler = logging.StreamHandler(capture_stream)
capture_handler.setLevel(logging.DEBUG)

root_logger.addHandler(capture_handler)
root_logger.setLevel(logging.DEBUG)

try:
with TemporaryDirectory() as temp_dir:
registry = Registry(backend=temp_dir, version_objects=True)
registry.save("a:shareditem", 1)
assert registry.load("a:shareditem") == 1

output = capture_stream.getvalue()
assert "Loading metadata from:" not in output
assert "Loaded metadata:" not in output
assert "Downloading directory from" not in output
assert "Download complete." not in output
finally:
root_logger.removeHandler(capture_handler)
root_logger.setLevel(old_level)