ScriptsJul 28, 2026·2 min read

PySnooper — Never Use Print for Python Debugging Again

A debugging tool that lets you trace Python function execution by adding a single decorator. See every line executed, local variable changes, and return values without setting breakpoints.

Agent ready

Review-first install path

This asset needs a review step. The copied prompt tells the agent to dry-run, show the writes, then proceed only after confirmation.

Needs Confirmation · 64/100Policy: confirm
Agent surface
Any MCP/CLI agent
Kind
Skill
Install
Single
Trust
Trust: Established
Entrypoint
PySnooper
Review-first command
npx -y tokrepo@latest install 6f5466b0-8aa2-11f1-9bc6-00163e2b0d79 --target codex

Dry-run first, confirm the writes, then run this command.

Introduction

PySnooper is a poor man's debugger for Python. Instead of painstakingly adding print statements or configuring a full debugger, you decorate a function with @pysnooper.snoop() and get a complete trace of every line executed, every variable modified, and every return value.

What PySnooper Does

  • Traces function execution line by line with a single decorator
  • Logs all local variable assignments and their new values
  • Shows elapsed time for each traced line
  • Supports writing trace output to files or custom streams
  • Allows watching specific expressions and nested function calls

Architecture Overview

PySnooper hooks into Python's sys.settrace mechanism. When a decorated function runs, the tracer intercepts each line event, inspects the local namespace for changes, formats the output, and writes it to stderr or a specified file. The @pysnooper.snoop() decorator wraps the target function transparently, so no changes to the function body are needed.

Self-Hosting & Configuration

  • Install with pip: pip install pysnooper
  • Apply @pysnooper.snoop() to any function you want to trace
  • Write traces to a file: @pysnooper.snoop("/tmp/debug.log")
  • Watch specific expressions: @pysnooper.snoop(watch=("len(items)", "self.count"))
  • Trace deeper calls: @pysnooper.snoop(depth=2) to follow nested function invocations

Key Features

  • Zero-config debugging with a single decorator
  • Traces variable changes without manual print statements
  • Supports conditional tracing with watch and watch_explode
  • Thread-safe with per-thread trace output
  • Lightweight with no dependencies beyond the Python standard library

Comparison with Similar Tools

  • print() — Requires manual placement and removal; PySnooper automates the entire trace
  • pdb / breakpoint() — Interactive debugger requiring stepping; PySnooper is non-interactive and logs everything
  • icecream (ic) — Focused on inspect-style printing; PySnooper traces full execution flow
  • Hunter — More powerful tracing framework; PySnooper is simpler for quick debugging

FAQ

Q: Does PySnooper slow down my code? A: Yes, tracing adds overhead. Use it only during development and debugging, not in production. Remove the decorator when done.

Q: Can I use PySnooper with async functions? A: PySnooper works with synchronous functions. For async code, consider alternatives like snoop (a fork) or logging-based approaches.

Q: How do I trace only certain variables? A: Use the watch parameter: @pysnooper.snoop(watch=("my_var",)) to track specific expressions alongside the default local variable tracing.

Q: Can I integrate PySnooper with logging? A: Yes. Pass a logging handler or file object as the output target: @pysnooper.snoop(output=my_logger).

Sources

Discussion

Sign in to join the discussion.
No comments yet. Be the first to share your thoughts.

Related Assets