2 min read

IceCream makes Python print debugging less painful

The IceCream Python library replaces bare print() calls with ic(), showing expressions and values together with optional file and line context.

Image: Hacker News

IceCream is a small Python debugging library built around one idea: replace print() with ic() and get more useful output with less typing. The project, maintained by Jakeroid (Ivan Karabadzhak) with support from the confidential computing team at 🌖 Lunal, targets Python 3 and PyPy3.

Instead of only printing a value, ic() prints both the expression and the result. In the project’s example, ic(foo(123)) outputs ic| foo(123): 456. The same applies to dictionary lookups and class attributes, which makes quick inspection easier without manually labeling each print statement.

Called with no arguments, ic() switches roles and reports execution context: filename, line number, and parent function. That makes it useful for tracing code paths when you would otherwise scatter numbered print statements through a function.

A practical touch is that ic() returns its argument or arguments, so it can be dropped into existing expressions without changing program flow. The library also includes *ic.format(args) to return formatted debug output as a string instead of sending it to stderr, plus ic.disable() and ic.enable()** for turning output off and on without breaking code.

Recommended reading

Waze adds smarter routing and a quieter voice mode

Output configuration and imports

IceCream exposes a broad configureOutput API, including:

  • custom prefix strings or functions
  • a custom outputFunction
  • a custom argToStringFunction
  • optional includeContext
  • optional contextAbsPath

The default string conversion uses pprint.pformat(), but the project also supports class-specific formatting via functools.singledispatch. The documentation shows this with a NumPy ndarray formatter that summarizes shape and dtype before falling back to normal behavior.

There’s also an install() helper that adds ic() to Python’s builtins so it can be used across imported files without repeated imports, and an uninstall() counterpart. For production environments where IceCream may not be installed, the project suggests a fallback try/except ImportError snippet that turns ic into a no-op while preserving return values.

Installation is straightforward: pip install icecream. The project also notes that ic() relies on executing by @alexmojaki to locate call sites in source code, and lists ports in other languages including Dart, Rust, Node.js, C++, C99, PHP, Go, Ruby, Java, R, Lua, Clojure(Script), Bash, SystemVerilog, and GameMaker Language.

Tomas Berg

Computing Editor

Tomas lives in the terminal. He covers chips, laptops, and operating systems with a focus on performance and efficiency. He reads kernel changelogs the way other people read fiction, and he's always on the hunt for the perfect mechanical keyboard switch. If it processes data, Tomas has an opinion on it.

via Hacker News

// Keep reading