Python Debugging Cheat Sheet

Core Python debugging commands, traceback inspection, runtime introspection, and practical troubleshooting workflows.

View
StandardDetailedCompact
Export
Copy the compact sheet, download it, or print it.
Download
`D` dense toggle · `C` copy all

Breakpoints and pdb

Interactive debugging with built-in breakpoints and pdb.

Insert a built-in breakpoint

Pause execution and enter the configured debugger.

pythonANYbreakpointpdbinteractive
python
breakpoint()

Uses Python's built-in breakpoint hook. By default this opens pdb in interactive runs.

Drop into pdb at a specific line

Classic explicit breakpoint using pdb.

pythonANYpdbset-tracebreakpoint
python
import pdb; pdb.set_trace()

Useful when you want an explicit dependency-free breakpoint in scripts and older codebases.

Run a script under pdb

Start Python's debugger from the command line.

bashANYpdbclidebugger
bash
python -m pdb app.py

Starts the debugger before the first line of the script and lets you step through execution.

Run a script with pdb and arguments

Pass normal program arguments when starting under pdb.

bashANYpdbargumentscli
bash
python -m pdb app.py --env dev --port 8000

pdb next

Step over the current line without entering function calls.

textANYpdbstep-over
text
n

In pdb, `n` runs the current line and stops at the next line in the same frame.

pdb step

Step into a called function.

textANYpdbstep-into
text
s

pdb continue

Resume execution until the next breakpoint.

textANYpdbcontinue
text
c

pdb until

Continue until a later line in the current frame.

textANYpdbcontrol-flow
text
until

pdb list source

Show nearby source lines.

textANYpdbsource-view
text
l

Print a variable in pdb

Inspect the value of an expression.

textANYpdbinspectvariables
text
p variable_name

Pretty-print in pdb

Print structured data in a readable format.

textANYpdbpretty-print
text
pp complex_object

Show stack trace in pdb

Display the current call stack.

textANYpdbstacktrace
text
w

Move up and down stack frames

Navigate the traceback to inspect caller frames.

textANYpdbframestraceback
text
u
d

Set a breakpoint in pdb

Break on a file and line number from within the debugger.

textANYpdbbreakpoints
text
b app.py:42

Tracebacks and Exceptions

Capture and inspect failures quickly.

Print the current exception traceback

Dump the active exception traceback in an except block.

pythonANYtracebackexceptionsdiagnostics
python
import traceback

try:
    risky_call()
except Exception:
    traceback.print_exc()

Format exception as a string

Capture traceback output for logs or APIs.

pythonANYtracebacklogging
python
import traceback

try:
    risky_call()
except Exception:
    error_text = traceback.format_exc()

Get exception info tuple

Access exception type, value, and traceback explicitly.

pythonANYexceptionssystraceback
python
import sys

try:
    risky_call()
except Exception:
    exc_type, exc_value, exc_tb = sys.exc_info()

Preserve context with raise from

Chain exceptions to keep original failure context.

pythonANYexceptionschainingdebugging
python
try:
    parse_config()
except ValueError as exc:
    raise RuntimeError("Invalid configuration") from exc

Enable faulthandler

Print Python tracebacks on fatal errors like segfaults.

pythonANYfaulthandlercrashsegfault
python
import faulthandler
faulthandler.enable()

Enable faulthandler from CLI

Turn on fatal error tracebacks without code changes.

bashANYfaulthandlercli
bash
python -X faulthandler app.py

Show default warnings

Enable warnings that may help reveal bad behavior.

bashANYwarningsdiagnostics
bash
python -Wd app.py

Run in Python development mode

Enable extra runtime checks and debug-friendly behavior.

bashANYdev-moderuntimediagnostics
bash
python -X dev app.py

Runtime Inspection

Inspect objects, frames, environment, and imports.

Inspect object type and attributes

Quickly see what an object is and what it exposes.

pythonANYinspectionobjects
python
print(type(obj))
print(dir(obj))

Inspect an object's __dict__

Show instance attributes stored on an object.

pythonANYinspectiondict
python
print(vars(obj))

Pretty print nested data

Display dicts and lists more readably.

pythonANYpprintinspection
python
from pprint import pprint

pprint(payload)

Inspect a callable signature

See function parameters at runtime.

pythonANYinspectsignaturefunctions
python
import inspect

print(inspect.signature(func))

Print source code for a function

Display source when available.

pythonANYinspectsource
python
import inspect

print(inspect.getsource(func))

Show import search path

Debug why imports resolve incorrectly.

pythonANYimportssys-path
python
import sys

for path in sys.path:
    print(path)

Show the file backing an imported module

Confirm which module file was actually imported.

pythonANYimportsmodule-resolution
python
import package_name

print(package_name.__file__)

Inspect environment variables

Print environment values affecting program behavior.

pythonANYenvironmentconfiguration
python
import os

print(os.environ.get("APP_ENV"))

Logging and Diagnostics

Use structured, actionable logs for faster debugging.

Enable basic debug logging

Turn on debug-level logs quickly.

pythonANYloggingdebug
python
import logging

logging.basicConfig(level=logging.DEBUG)
logging.debug("Starting debug run")

Use a readable log format

Add timestamps and levels to logs.

pythonANYloggingformat
python
import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s %(levelname)s %(name)s %(message)s',
)

Log an exception with traceback

Emit the stack trace automatically in an except block.

pythonANYloggingexceptionstraceback
python
import logging

logger = logging.getLogger(__name__)

try:
    risky_call()
except Exception:
    logger.exception("Request processing failed")

Attach request or job context to logs

Add contextual identifiers that make debugging easier.

pythonANYloggingcontext
python
import logging

base_logger = logging.getLogger(__name__)
logger = logging.LoggerAdapter(base_logger, {"request_id": request_id})
logger.info("Processing request")

Time a block of code

Measure elapsed time around suspicious code paths.

pythonANYtimingperformance
python
import time

start = time.perf_counter()
result = expensive_call()
elapsed = time.perf_counter() - start
print(f"Elapsed: {elapsed:.4f}s")

Benchmark small snippets with timeit

Measure a small expression from the command line.

bashANYtimeitbenchmark
bash
python -m timeit "sum(range(1000))"

pytest and unittest Debugging

Debug tests and isolate flaky or failing behavior.

Stop after first failure

Fail fast and debug one issue at a time.

bashANYpytestfail-fast
bash
pytest -x

Drop into pdb on failure

Open the debugger automatically when a test fails.

bashANYpytestpdb
bash
pytest --pdb

Disable output capture

See print statements and standard output live.

bashANYpyteststdoutcapture
bash
pytest -s

Run one test function

Narrow execution to one failing test quickly.

bashANYpytesttargeted-run
bash
pytest tests/test_api.py::test_create_user

Re-run only last failed tests

Speed up debugging after a failing run.

bashANYpytestlast-failed
bash
pytest --lf

Show local variables in tracebacks

Reveal local state in failing assertions and exceptions.

bashANYpytesttracebackslocals
bash
pytest -vv --showlocals

Run unittest in verbose mode

See each test case as it runs.

bashANYunittestverbose
bash
python -m unittest -v tests.test_service

Profiling and Memory

Distinguish slow code from broken code and inspect resource usage.

Profile a script with cProfile

Collect function-level runtime statistics.

bashANYcprofileprofiling
bash
python -m cProfile app.py

Sort cProfile output by total time

Surface slow functions first.

bashANYcprofileperformance
bash
python -m cProfile -s tottime app.py

Profile code inside Python

Wrap a hot path in cProfile and print stats.

pythonANYcprofilein-process
python
import cProfile
import pstats

profiler = cProfile.Profile()
profiler.enable()
expensive_call()
profiler.disable()
pstats.Stats(profiler).sort_stats('tottime').print_stats(20)

Track memory allocations with tracemalloc

Capture memory allocation snapshots.

pythonANYmemorytracemalloc
python
import tracemalloc

tracemalloc.start()
# run code
snapshot = tracemalloc.take_snapshot()
for stat in snapshot.statistics('lineno')[:10]:
    print(stat)

Inspect process memory and CPU with psutil

Check runtime resource usage from inside the process.

pythonANYpsutilmemorycpu
python
import os
import psutil

process = psutil.Process(os.getpid())
print(process.memory_info())
print(process.cpu_percent(interval=1.0))

Requires the third-party `psutil` package, but it is extremely useful for production debugging and local diagnostics.

Async, Web, and Production Troubleshooting

Common debugging patterns for servers, workers, and async code.

Enable asyncio debug mode

Expose slow callbacks and event-loop issues.

bashANYasynciodebug-mode
bash
PYTHONASYNCIODEBUG=1 python app.py

Enable debug mode programmatically

Turn on event loop debugging in code.

pythonANYasynciodebug
python
import asyncio

async def main():
    ...

asyncio.run(main(), debug=True)

Start a simple HTTP server for quick testing

Serve files locally to reproduce client behavior.

bashANYhttp-serverrepro
bash
python -m http.server 8000

Profile import time

See which imports are slowing startup.

bashANYimportsstartupperformance
bash
python -X importtime app.py

Dump stack traces for all threads

Useful when an app appears hung or deadlocked.

pythonANYthreadssignalshung-process
python
import faulthandler
import signal

faulthandler.register(signal.SIGUSR1)

After registering a signal, send `SIGUSR1` to the process to dump thread stack traces.

Recommended next

No recommendations yet.