IceCream

A Python debugging library that prints both an expression and its value, so you never have to write print("x:", x) again.

Library
PyPI
v2.2.0
10,108stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
72/100Good
Development Activity72
Maintenance56
Community60
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
72/100Good
Architecture78
Code Quality72
Innovation82
Learning Curve55

IceCream is a Python debugging library built around a single function, ic(), that inspects its own call site to print both the expression you passed and its evaluated value — turning a debug print statement like print(foo(123)) into a one-character call that self-documents. It uses the executing library to reliably locate its own call in the source AST (even across multi-line calls, method chains, or when several ic() calls appear on one line), formats output with syntax highlighting via Pygments, and pretty-prints nested data structures for readability.

Beyond variable inspection, calling ic() with no arguments prints the calling filename, line number, and parent function to trace execution flow — a lightweight replacement for scattering print(1)/print(2) breadcrumbs through conditional branches. Output can be redirected into a logging pipeline, disabled globally in production via ic.disable(), or installed onto Python’s builtins module so no import is required across an entire project.

What You Get

  • Self-documenting output - ic(x) prints both the expression text and its value, so you never need print("x:", x) boilerplate.
  • Syntax-highlighted, pretty-printed values - Output is colorized via Pygments and formatted with a tuned pprint.pformat() wrapper for readable nested data structures.
  • Execution tracing - Calling ic() with no arguments prints the filename, line number, and parent function, useful for tracing branchy control flow.
  • Global install/disable - install() adds ic to Python’s builtins so it’s available in every file without imports; ic.disable()/enable() toggles output globally, e.g. for production.

Common Use Cases

  • Quick variable inspection while iterating on a function - drop ic(result) inline instead of writing a labeled print() call, then delete it when done.
  • Tracing which branch of an if/else executed - call bare ic() inside each branch to see exactly which path and line ran without adding custom print markers.
  • Debugging inside REPL-unfriendly code paths - ic.format() returns the formatted string so it can be piped into logging.debug() instead of stderr.
  • Project-wide debug helper without per-file imports - call install() once at startup so ic() is available as a builtin across the whole codebase during development.

Under The Hood

Architecture The library is a small, flat module set: icecream.py holds the single IceCreamDebugger class that is the entire public surface, coloring.py defines a standalone Pygments SolarizedDark style, and builtins.py patches Python’s builtins module to install/uninstall the global ic name. Rather than subclassing, configuration is done through injectable callables (prefix, outputFunction, argToStringFunction) set via configureOutput(), a strategy-style design that keeps the default zero-config path simple while still being pluggable. The core trick the whole library depends on is Source.executing(callFrame) from the third-party executing package, which walks the call frame to recover the exact AST node of the ic() call so its source text can be reprinted alongside its value; when that lookup fails (a REPL, a frozen executable, or source that changed at runtime) the code falls back to a Sentinel.absent marker and emits a RuntimeWarning rather than crashing, so the degradation path was designed in rather than bolted on. Timer, exposed via the ic.timer property, reuses the same IceCreamDebugger instance as both a decorator and a context manager for measuring elapsed time.

Tech Stack A pure-Python 3.8–3.14 (plus PyPy3.10) library with no runtime framework dependencies beyond colorama (Windows ANSI passthrough), pygments (lexing/highlighting), and executing/asttokens (frame-to-AST resolution). It ships as a setuptools-built wheel with an inline py.typed marker, and its GitHub Actions CI runs a tox matrix across every supported Python version plus a dedicated mypy job configured with disallow_untyped_defs/disallow_untyped_calls in pyproject.toml.

Code Quality A roughly 1,000-line unittest.TestCase suite in tests/test_icecream.py exercises install()/uninstall(), context tracing, coloring, the timer, format(), and enable/disable behavior, including regex assertions on ANSI escape sequences in output. Source files are extensively type-annotated (cast, Literal, Union, generics) and checked by a strict mypy configuration in CI, and error handling is explicit — safe_pformat() catches TypeError from pprint, retries with adjusted arguments, and warns before falling back to repr(). Naming conventions mix camelCase (formatPair, includeContext) with snake_case (has_non_ascii_chars), likely reflecting the project’s age and later contributions, and no dedicated linter step (e.g. ruff/flake8) runs in CI alongside mypy.

API Design ic(x) is deliberately the same shape as print(x), so adopting it requires no new syntax to learn — the self-documenting output is the entire pitch. configureOutput() provides escape hatches (custom prefix, output routing to logging, per-type serializers via argumentToString.register()) without complicating the zero-config default. Reusing the same IceCreamDebugger object as both a decorator and a context manager for timing, and offering install() to make ic() available as a language builtin, are both small but genuinely ergonomic touches that reduce everyday debugging friction.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search