<!-- ---
!-- Timestamp: 2025-08-30 06:36:52
!-- Author: ywatanabe
!-- File: /home/ywatanabe/.claude/to_claude/guidelines/python/icecream.md
!-- --- -->

<h1 align="center">
  <img src="logo.svg" width="220px" height="370px" alt="IceCream">
</h1>

<p align="center">
  <a href="https://pypi.python.org/pypi/icecream"><img src="https://badge.fury.io/py/icecream.svg"></a>
  <a href="https://github.com/gruns/icecream/actions/workflows/ci.yml"><img src="https://github.com/gruns/icecream/actions/workflows/ci.yml/badge.svg"></a>
  <a href="/LICENSE.txt"><img src="https://img.shields.io/pypi/l/icecream.svg"></a>
  <a href="https://pypi.python.org/pypi/icecream"><img src="https://img.shields.io/pypi/pyversions/icecream.svg"></a>
</p>


### 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](LICENSE.txt), 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](https://docs.python.org/3.8/library/builtins.html) 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()](https://docs.python.org/3/library/pprint.html#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: <function icecream.icecream.argumentToString(obj)>,
              numpy.ndarray: <function __main__._(obj)>})
>>>
>>> # 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](https://github.com/gruns/icecream/issues/146).


### Installation

Installing IceCream with pip is easy.

```
$ pip install icecream
```


### Related Python libraries

`ic()` uses [**`executing`**](https://github.com/alexmojaki/executing)
by [**@alexmojaki**](https://github.com/alexmojaki) to reliably locate
`ic()` calls in Python source. It's magic.


### IceCream in Other Languages

Delicious IceCream should be enjoyed in every language.

- Dart: [icecream](https://github.com/HallerPatrick/icecream)
- Rust: [icecream-rs](https://github.com/ericchang00/icecream-rs)
- Node.js: [node-icecream](https://github.com/jmerle/node-icecream)
- C++: [IceCream-Cpp](https://github.com/renatoGarcia/icecream-cpp)
- C99: [icecream-c](https://github.com/chunqian/icecream-c)
- PHP: [icecream-php](https://github.com/ntzm/icecream-php)
- Go: [icecream-go](https://github.com/WAY29/icecream-go)
- Ruby: [Ricecream](https://github.com/nodai2hITC/ricecream)
- Java: [icecream-java](https://github.com/Akshay-Thakare/icecream-java)
- R: [icecream](https://github.com/lewinfox/icecream)
- Lua: [icecream-lua](https://github.com/wlingze/icecream-lua)
- Clojure(Script): [icecream-cljc](https://github.com/Eigenbahn/icecream-cljc)
- Bash: [IceCream-Bash](https://github.com/jtplaarj/IceCream-Bash)
- SystemVerilog: [icecream_sv](https://github.com/xver/icecream_sv)

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.

<!-- EOF -->