from __future__ import print_function import sys class DelWrapper(object): """ Wrap a dict and print the stack with a del operation occurs on the wrapped object. """ # save modules not in the globals to avoid issues if they gets cleaned up traceback = __import__('traceback') inspect = __import__('inspect') def __init__(self, wrapped): self.wrapped = wrapped def __getattr__(self, name): return getattr(self.wrapped, name) def __delitem__(self, item): if item.startswith('encodings.'): msg = "*** deletion of {item} detected ***".format(**vars()) print(msg, file=sys.stderr) frame = self.inspect.currentframe().f_back self.traceback.print_stack(frame) print("*" * len(msg)) # suppress the deletion return del self.wrapped[item] def __enter__(self): sys.modules = self def __exit__(self, type, val, tb): sys.modules = self.wrapped with DelWrapper(sys.modules): b'x'.decode('utf-8') del __import__('locale').encodings del sys.modules['encodings.utf_8'], sys.modules['encodings'] b'x'.decode('utf-8')