Skip to content
Open
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
7 changes: 5 additions & 2 deletions ddtrace/internal/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,11 @@ def call_back(self, module: ModuleType) -> None:
# loader type
module.register_loader_type(_ImportHookChainedLoader, module.DefaultProvider)

for callback in self.callbacks.values():
callback(module)
for key, callback in self.callbacks.items():
try:
callback(module)
except Exception:
log.exception("Exception ignored in after_import hook %r for module %s", key, module.__name__)

def load_module(self, fullname: str) -> t.Optional[ModuleType]:
if self.loader is None:
Expand Down
34 changes: 34 additions & 0 deletions tests/internal/test_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,40 @@ class Bob(BaseCollector):
Alice.uninstall()


@pytest.mark.subprocess(err=None)
def test_module_watchdog_after_import_hook_isolation():
# A failing after_import hook on one watchdog subclass must not prevent
# another watchdog subclass's after_import hook from running for the
# same import.
from ddtrace.internal.module import ModuleWatchdog

class Failing(ModuleWatchdog):
def after_import(self, module):
super(Failing, self).after_import(module)
raise ValueError("boom")

class Collector(ModuleWatchdog):
def __init__(self):
self.__modules__ = set()
super(Collector, self).__init__()

def after_import(self, module):
self.__modules__.add(module.__name__)
return super(Collector, self).after_import(module)

Failing.install()
Collector.install()

c = Collector._instance

import tests.submod.stuff # noqa:F401

assert c.__modules__ >= {"tests.submod.stuff"}, c.__modules__

Collector.uninstall()
Failing.uninstall()


@pytest.mark.subprocess(out="ddtrace imported\naccessing lazy module\nlazy loaded\n")
def test_module_watchdog_no_lazy_force_load():
"""Test that the module watchdog does not force-load lazy modules.
Expand Down
Loading