icecream

🍦 Never use print() to debug again.

https://github.com/gruns/icecream

Science Score: 36.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • â—‹
    CITATION.cff file
  • âś“
    codemeta.json file
    Found codemeta.json file
  • âś“
    .zenodo.json file
    Found .zenodo.json file
  • â—‹
    DOI references
  • â—‹
    Academic publication links
  • âś“
    Committers with academic emails
    2 of 23 committers (8.7%) from academic institutions
  • â—‹
    Institutional organization owner
  • â—‹
    JOSS paper metadata
  • â—‹
    Scientific vocabulary similarity
    Low similarity (11.5%) to scientific vocabulary

Keywords

debug debugging debugging-tool inspects library print python python3

Keywords from Contributors

transformer genomics interactive serializer packaging network-simulation human shellcodes hacking autograding
Last synced: 6 months ago · JSON representation

Repository

🍦 Never use print() to debug again.

Basic Info
  • Host: GitHub
  • Owner: gruns
  • License: mit
  • Language: Python
  • Default Branch: master
  • Homepage:
  • Size: 436 KB
Statistics
  • Stars: 9,870
  • Watchers: 55
  • Forks: 200
  • Open Issues: 67
  • Releases: 11
Topics
debug debugging debugging-tool inspects library print python python3
Created about 8 years ago · Last pushed 6 months ago
Metadata Files
Readme Changelog License

README.md

IceCream

IceCream — Never use print() to debug again

Do you ever use print() or log() to debug your code? Of course you do. IceCream, or ic for short, makes print debugging a little sweeter.

ic() is like print(), but better:

  1. It prints both variables and expressions along with their values.
  2. It's 60% faster to type.
  3. Data structures are formatted and pretty printed.
  4. Output is syntax highlighted.
  5. It optionally includes program context: filename, line number, and parent function.

IceCream is well tested, permissively licensed, and supports Python 3 and PyPy3.

2025-04-26: Big scoop: I'm thrilled to share that @Jakeroid is now a maintainer of IceCream! 🎉 IceCream’s future just got a whole lot sweeter. 🍦

Inspect Variables

Have you ever printed variables or expressions to debug your program? If you've ever typed something like

python print(foo('123'))

or the more thorough

python print("foo('123')", foo('123'))

then ic() will put a smile on your face. With arguments, ic() inspects itself and prints both its own arguments and the values of those arguments.

```python from icecream import ic

def foo(i): return i + 333

ic(foo(123)) ```

Prints

ic| foo(123): 456

Similarly,

```python d = {'key': {1: 'one'}} ic(d['key'][1])

class klass(): attr = 'yep' ic(klass.attr) ```

Prints

ic| d['key'][1]: 'one' ic| klass.attr: 'yep'

Just give ic() a variable or expression and you're done. Easy.

Inspect Execution

Have you ever used print() to determine which parts of your program are executed, and in which order they're executed? For example, if you've ever added print statements to debug code like

```python def foo(): print(0) first()

if expression:
    print(1)
    second()
else:
    print(2)
    third()

```

then ic() helps here, too. Without arguments, ic() inspects itself and prints the calling filename, line number, and parent function.

```python from icecream import ic

def foo(): ic() first()

if expression:
    ic()
    second()
else:
    ic()
    third()

```

Prints

ic| example.py:4 in foo() ic| example.py:11 in foo()

Just call ic() and you're done. Simple.

Return Value

ic() returns its argument(s), so ic() can easily be inserted into pre-existing code.

```pycon

a = 6 def half(i): return i / 2 b = half(ic(a)) ic| a: 6 ic(b) ic| b: 3 ```

Miscellaneous

ic.format(*args) is like ic() but the output is returned as a string instead of written to stderr.

```pycon

from icecream import ic s = 'sup' out = ic.format(s) print(out) ic| s: 'sup' ```

Additionally, ic()'s output can be entirely disabled, and later re-enabled, with ic.disable() and ic.enable() respectively.

```python from icecream import ic

ic(1)

ic.disable() ic(2)

ic.enable() ic(3) ```

Prints

ic| 1: 1 ic| 3: 3

ic() continues to return its arguments when disabled, of course; no existing code with ic() breaks.

Import Tricks

To make ic() available in every file without needing to be imported in every file, you can install() it. For example, in a root A.py:

```python

!/usr/bin/env python3

-- coding: utf-8 --

from icecream import install install()

from B import foo foo() ```

and then in B.py, which is imported by A.py, just call ic():

```python

-- coding: utf-8 --

def foo(): x = 3 ic(x) ```

install() adds ic() to the builtins module, which is shared amongst all files imported by the interpreter. Similarly, ic() can later be uninstall()ed, too.

ic() can also be imported in a manner that fails gracefully if IceCream isn't installed, like in production environments (i.e. not development). To that end, this fallback import snippet may prove useful:

python try: from icecream import ic except ImportError: # Graceful fallback if IceCream isn't installed. ic = lambda *a: None if not a else (a[0] if len(a) == 1 else a) # noqa

Configuration

ic.configureOutput(prefix, outputFunction, argToStringFunction, includeContext, contextAbsPath) controls ic()'s output.

prefix, if provided, adopts a custom output prefix. prefix can be a string, like

```pycon

from icecream import ic ic.configureOutput(prefix='hello -> ') ic('world') hello -> 'world' ```

or a function.

```pycon

import time from icecream import ic

def unixTimestamp(): return '%i |> ' % int(time.time())

ic.configureOutput(prefix=unixTimestamp) ic('world') 1519185860 |> 'world': 'world' ```

prefix's default value is ic|.

outputFunction, if provided, is called once for every ic() call with ic()'s output, as a string, instead of that string being written to stderr (the default).

```pycon

import logging from icecream import ic

def warn(s): logging.warning("%s", s)

ic.configureOutput(outputFunction=warn) ic('eep') WARNING:root:ic| 'eep': 'eep' ```

argToStringFunction, if provided, is called with argument values to be serialized to displayable strings. The default is PrettyPrint's pprint.pformat(), but this can be changed to, for example, handle non-standard datatypes in a custom fashion.

```pycon

from icecream import ic

def toString(obj): if isinstance(obj, str): return '[!string %r with length %i!]' % (obj, len(obj)) return repr(obj)

ic.configureOutput(argToStringFunction=toString) ic(7, 'hello') ic| 7: 7, 'hello': [!string 'hello' with length 5!] ```

The default argToStringFunction is icecream.argumentToString, and has methods to register and unregister functions to be dispatched for specific classes using functools.singledispatch. It also has a registry property to view registered functions.

```pycon

from icecream import ic, argumentToString import numpy as np

Register a function to summarize numpy array

@argumentToString.register(np.ndarray) def _(obj): return f"ndarray, shape={obj.shape}, dtype={obj.dtype}"

x = np.zeros((1, 2)) ic(x) ic| x: ndarray, shape=(1, 2), dtype=float64

View registered functions

argumentToString.registry mappingproxy({object: , numpy.ndarray: })

Unregister a function and fallback to the default behavior

argumentToString.unregister(np.ndarray) ic(x) ic| x: array([[0., 0.]]) ```

includeContext, if provided and True, adds the ic() call's filename, line number, and parent function to ic()'s output.

```pycon

from icecream import ic ic.configureOutput(includeContext=True)

def foo(): i = 3 ic(i) foo() ic| example.py:12 in foo()- i: 3 ```

includeContext is False by default.

contextAbsPath, if provided and True, outputs absolute filepaths, like /path/to/foo.py, over just filenames, like foo.py, when ic() is called with includeContext == True. This is useful when debugging multiple files that share the same filename(s). Moreover, some editors, like VSCode, turn absolute filepaths into clickable links that open the file where ic() was called.

```pycon

from icecream import ic ic.configureOutput(includeContext=True, contextAbsPath=True)

i = 3

def foo(): ic(i) foo() ic| /absolute/path/to/example.py:12 in foo()- i: 3

ic.configureOutput(includeContext=True, contextAbsPath=False)

def foo(): ic(i) foo() ic| example.py:18 in foo()- i: 3 ```

contextAbsPath is False by default.

If you want to use icecream with multiple log levels, like with Python’s logging module, you can use ic.format() to integrate icecream’s debugging with your logger:

```python import logging from icecream import ic

foo = 'bar' logging.debug(ic.format(foo)) ```

âť• This is a bit clunky. Would you prefer built-in log level support in icecream? If so, please share your thoughts in issue.

Installation

Installing IceCream with pip is easy.

$ pip install icecream

Related Python libraries

ic() uses executing by @alexmojaki to reliably locate ic() calls in Python source. It's magic.

IceCream in Other Languages

Delicious IceCream should be enjoyed in every language.

If you'd like a similar ic() function in your favorite language, please open a pull request! IceCream's goal is to sweeten print debugging with a handy-dandy ic() function in every language.

Owner

  • Name: Ansgar Grunseid
  • Login: gruns
  • Kind: user
  • Company: https://arc.io, https://pep.dev

GitHub Events

Total
  • Create event: 3
  • Release event: 1
  • Issues event: 24
  • Watch event: 828
  • Delete event: 1
  • Member event: 1
  • Issue comment event: 124
  • Push event: 24
  • Pull request event: 24
  • Pull request review comment event: 3
  • Pull request review event: 8
  • Fork event: 25
Last Year
  • Create event: 3
  • Release event: 1
  • Issues event: 24
  • Watch event: 828
  • Delete event: 1
  • Member event: 1
  • Issue comment event: 124
  • Push event: 24
  • Pull request event: 24
  • Pull request review comment event: 3
  • Pull request review event: 8
  • Fork event: 25

Committers

Last synced: 9 months ago

All Time
  • Total Commits: 278
  • Total Committers: 23
  • Avg Commits per committer: 12.087
  • Development Distribution Score (DDS): 0.245
Past Year
  • Commits: 19
  • Committers: 1
  • Avg Commits per committer: 19.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Ansgar Grunseid g****d@g****m 210
Alex Hall a****i@g****m 13
Matthijs van der Burgh M****h@o****m 11
atusy 3****y 8
Ehud Halamish e****d@n****m 6
Tom Parker-Shemilt p****y@t****t 5
HelinXu x****9@m****n 5
Atsushi Yasumoto a****i@h****m 2
DominikRafacz d****z@s****l 2
Semen Zhydenko s****o@g****m 2
dependabot[bot] 4****] 2
Eric e****0@g****m 1
Bao Pham g****m@g****m 1
Akshay Thakare a****a@g****m 1
Jasper van Merle j****e@g****m 1
Miguel Gaiowski m****g@f****m 1
Nat Zimmermann n****m 1
Renato Garcia f****o@g****m 1
chunqian c****n@q****m 1
jtplaarj j****j@g****m 1
nodai2hITC n****c@g****m 1
p3r7 1****7 1
wlz w****4@1****m 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 116
  • Total pull requests: 61
  • Average time to close issues: 4 months
  • Average time to close pull requests: 7 months
  • Total issue authors: 101
  • Total pull request authors: 43
  • Average comments per issue: 4.09
  • Average comments per pull request: 2.69
  • Merged pull requests: 16
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 16
  • Pull requests: 15
  • Average time to close issues: about 2 months
  • Average time to close pull requests: 5 months
  • Issue authors: 14
  • Pull request authors: 9
  • Average comments per issue: 0.81
  • Average comments per pull request: 1.6
  • Merged pull requests: 3
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • alexmojaki (5)
  • salabim (3)
  • notPlancha (2)
  • dcsan (2)
  • lwilhoit (2)
  • Jakeroid (2)
  • gruns (2)
  • off99555 (2)
  • Mathemmagician (2)
  • EdLipson5117 (2)
  • vp-31 (1)
  • Deshdeepak1 (1)
  • PBhadoo (1)
  • cape-t (1)
  • KarlRW (1)
Pull Request Authors
  • alexmojaki (4)
  • palfrey (3)
  • marksmayo (3)
  • isidroas (2)
  • hooch (2)
  • Joaq33 (2)
  • YunfangHou (2)
  • DominikRafacz (2)
  • NightMachinery (2)
  • hexmode (2)
  • nbys (2)
  • notPlancha (2)
  • blech75 (2)
  • a-detiste (2)
  • danielathome19 (2)
Top Labels
Issue Labels
enhancement (2)
Pull Request Labels
enhancement (2)

Packages

  • Total packages: 4
  • Total downloads:
    • pypi 1,312,770 last-month
  • Total docker downloads: 31,474
  • Total dependent packages: 147
    (may contain duplicates)
  • Total dependent repositories: 1,308
    (may contain duplicates)
  • Total versions: 36
  • Total maintainers: 1
pypi.org: icecream

Never use print() to debug again; inspect variables, expressions, and program execution with a single, simple function call.

  • Versions: 21
  • Dependent Packages: 146
  • Dependent Repositories: 1,295
  • Downloads: 1,310,406 Last month
  • Docker Downloads: 31,474
Rankings
Dependent packages count: 0.2%
Stargazers count: 0.3%
Dependent repos count: 0.3%
Downloads: 0.6%
Average: 1.1%
Docker downloads count: 1.4%
Forks count: 3.9%
Maintainers (1)
Last synced: 6 months ago
proxy.golang.org: github.com/gruns/icecream
  • Versions: 10
  • Dependent Packages: 0
  • Dependent Repositories: 1
Rankings
Stargazers count: 0.8%
Forks count: 2.3%
Average: 4.1%
Dependent repos count: 4.8%
Dependent packages count: 8.5%
Last synced: 6 months ago
pypi.org: i

Never use print() to debug again; inspect variables, expressions, and program execution with a single, simple function call.

  • Versions: 1
  • Dependent Packages: 1
  • Dependent Repositories: 1
  • Downloads: 2,364 Last month
Rankings
Stargazers count: 0.3%
Forks count: 4.0%
Downloads: 5.5%
Dependent packages count: 7.4%
Average: 7.9%
Dependent repos count: 22.2%
Maintainers (1)
Last synced: 6 months ago
conda-forge.org: icecream

Do you ever use print() or log() to debug your code? Of course you do. IceCream, or ic for short, makes print debugging a little sweeter. ic() is like print(), but better: 1. It prints both expressions/variable names and their values. 2. It's 40% faster to type. 3. Data structures are pretty printed. 4. Output is syntax highlighted. 5. It optionally includes program context: filename, line number, and parent function.

  • Versions: 4
  • Dependent Packages: 0
  • Dependent Repositories: 11
Rankings
Stargazers count: 4.2%
Dependent repos count: 10.7%
Forks count: 15.5%
Average: 20.5%
Dependent packages count: 51.6%
Last synced: 6 months ago

Dependencies

setup.py pypi
  • asttokens >=2.0.1
  • colorama >=0.3.9
  • executing >=0.3.1
  • pygments >=2.2.0
.github/workflows/ci.yml actions
  • actions/checkout v3 composite
  • actions/setup-python v4 composite