import threading import sys def tracer(frame, event, arg): if event == 'call': print(f"Entering: {frame.f_code.co_name}") return tracer elif event == 'c_call': print(f"C --- Entering: {arg.__name__}") elif event == 'return': print(f"Returning: {arg!r}") elif event == 'c_return': print(f"C --- Returning from: {arg.__name__}") lock = threading.Lock() sys.setprofile(tracer) threading.setprofile(tracer) print("Begin...") # In the following case, we would see the C functions being called: acquire and release lock.acquire() print("Do some routine with explicit locking") lock.release() print("In the middle...") # In the following case, we cannot see that any locking is happening, despite it working with lock: print("Do some routine with locking using context management") print("End...")