Skip to content
🍦 Sweet and creamy print debugging.
Branch: master
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
icecream Support multiline container arguments. Collapse argument whitespace. Feb 18, 2019
.gitignore The future of print debugging. Feb 13, 2018
LICENSE.txt The future of print debugging. Feb 13, 2018 Update ic.format() example in the readme. Feb 20, 2019
changelog.txt Support multiline container arguments. Collapse argument whitespace. Feb 18, 2019
logo.svg Rename icon.svg to the more apposite logo.svg. Aug 28, 2018
setup.cfg Publish both a source distribution and a Wheel to PyPi. Sep 3, 2018
tox.ini Remove old, unused Python 2.6 related test code. Sep 15, 2018


IceCream is a little library for sweet and creamy debugging.

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.

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

Inspect Variables

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


or the more thorough

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

then ic() is here to help. With arguments, ic() inspects itself and prints both its own arguments and the values of those arguments.

from icecream import ic

def foo(i):
    return i + 333



ic| foo(123): 456


d = {'key': {1: 'one'}}

class klass():
    attr = 'yep'


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

def foo():

    if expression:

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

from icecream import ic

def foo():
    if expression:


ic| in foo()
ic| 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.

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


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

>>> 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.

from icecream import ic





ic| 1: 1
ic| 3: 3

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


ic.configureOutput(prefix, outputFunction, argToStringFunction, includeContext) can be used to adopt a custom output prefix (the default is ic| ), change the output function (default is to write to stderr), customize how arguments are serialized to strings, and/or include the ic() call's context (filename, line number, and parent function) in ic() output with arguments.

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

prefix can optionally be a function, too.

>>> import time
>>> from icecream import ic
>>> def unixTimestamp():
>>>     return '%i |> ' % int(time.time())
>>> ic.configureOutput(prefix=unixTimestamp)
>>> ic('world')
1519185860 |> 'world': 'world'

outputFunction, if provided, is called with ic()'s output instead of that output being written to stderr (the default).

>>> import logging
>>> from icecream import ic
>>> def warn(s):
>>>     logging.warning(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.

>>> 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!]

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

>>> from icecream import ic
>>> ic.configureOutput(includeContext=True)
>>> def foo():
>>>   ic('str')
>>> foo()
ic| in foo()- 'str': 'str'

includeContext is False by default.


Installing IceCream with pip is easy.

$ pip install icecream


It's often useful to import ic() in a manner that falls back gracefully if IceCream isn't installed, like in production environments (i.e. not development). To that end, this fallback import snippet may prove useful:

    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

IceCream in Other Languages

IceCream should be enjoyed with 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.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.