{"id":13467807,"url":"https://github.com/gruns/icecream","last_synced_at":"2026-01-21T09:09:31.120Z","repository":{"id":37359370,"uuid":"121422840","full_name":"gruns/icecream","owner":"gruns","description":"🍦 Never use print() to debug again.","archived":false,"fork":false,"pushed_at":"2025-04-27T03:01:45.000Z","size":400,"stargazers_count":9699,"open_issues_count":93,"forks_count":201,"subscribers_count":54,"default_branch":"master","last_synced_at":"2025-05-01T13:52:28.034Z","etag":null,"topics":["debug","debugging","debugging-tool","inspects","library","print","python","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gruns.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.txt","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-02-13T18:56:12.000Z","updated_at":"2025-04-30T14:44:18.000Z","dependencies_parsed_at":"2024-09-29T21:40:39.661Z","dependency_job_id":"59defa74-acf6-42ca-8675-256d5aab415f","html_url":"https://github.com/gruns/icecream","commit_stats":{"total_commits":234,"total_committers":22,"mean_commits":"10.636363636363637","dds":0.2350427350427351,"last_synced_commit":"fc409817197f2c1e23cc5f0fe4d9e7ba9d6e6ad6"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruns%2Ficecream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruns%2Ficecream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruns%2Ficecream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruns%2Ficecream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gruns","download_url":"https://codeload.github.com/gruns/icecream/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253671905,"owners_count":21945471,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["debug","debugging","debugging-tool","inspects","library","print","python","python3"],"created_at":"2024-07-31T15:01:00.780Z","updated_at":"2026-01-21T09:09:31.108Z","avatar_url":"https://github.com/gruns.png","language":"Python","readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg src=\"logo.svg\" width=\"220px\" height=\"370px\" alt=\"IceCream\"\u003e\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://pypi.python.org/pypi/icecream\"\u003e\u003cimg src=\"https://badge.fury.io/py/icecream.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/gruns/icecream/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/gruns/icecream/actions/workflows/ci.yml/badge.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"/LICENSE.txt\"\u003e\u003cimg src=\"https://img.shields.io/pypi/l/icecream.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pypi.python.org/pypi/icecream\"\u003e\u003cimg src=\"https://img.shields.io/pypi/pyversions/icecream.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\n### IceCream — Never use print() to debug again\n\nDo you ever use `print()` or `log()` to debug your code? Of course you\ndo. IceCream, or `ic` for short, makes print debugging a little sweeter.\n\n`ic()` is like `print()`, but better:\n\n  1. It prints both variables and expressions along with their values.\n  2. It's 60% faster to type.\n  3. Data structures are formatted and pretty printed.\n  4. Output is syntax highlighted.\n  5. It optionally includes program context: filename, line number, and\n     parent function.\n\nIceCream is well tested, [permissively licensed](LICENSE.txt), and supports Python 3 and PyPy3.\n\nIceCream is maintained by [Jakeroid (Ivan Karabadzhak)](https://github.com/Jakeroid), with support from the confidential computing folks at [🌖 Lunal](https://lunal.dev/).\n\n\n### Inspect Variables\n\nHave you ever printed variables or expressions to debug your program? If\nyou've ever typed something like\n\n```python\nprint(foo('123'))\n```\n\nor the more thorough\n\n```python\nprint(\"foo('123')\", foo('123'))\n```\n\nthen `ic()` will put a smile on your face. With arguments, `ic()`\ninspects itself and prints both its own arguments and the values of\nthose arguments.\n\n```python\nfrom icecream import ic\n\ndef foo(i):\n    return i + 333\n\nic(foo(123))\n```\n\nPrints\n\n```\nic| foo(123): 456\n```\n\nSimilarly,\n\n```python\nd = {'key': {1: 'one'}}\nic(d['key'][1])\n\nclass klass():\n    attr = 'yep'\nic(klass.attr)\n```\n\nPrints\n\n```\nic| d['key'][1]: 'one'\nic| klass.attr: 'yep'\n```\n\nJust give `ic()` a variable or expression and you're done. Easy.\n\n\n### Inspect Execution\n\nHave you ever used `print()` to determine which parts of your program are\nexecuted, and in which order they're executed? For example, if you've ever added\nprint statements to debug code like\n\n```python\ndef foo():\n    print(0)\n    first()\n\n    if expression:\n        print(1)\n        second()\n    else:\n        print(2)\n        third()\n```\n\nthen `ic()` helps here, too. Without arguments, `ic()` inspects itself and\nprints the calling filename, line number, and parent function.\n\n```python\nfrom icecream import ic\n\ndef foo():\n    ic()\n    first()\n\n    if expression:\n        ic()\n        second()\n    else:\n        ic()\n        third()\n```\n\nPrints\n\n```\nic| example.py:4 in foo()\nic| example.py:11 in foo()\n```\n\nJust call `ic()` and you're done. Simple.\n\n\n### Return Value\n\n`ic()` returns its argument(s), so `ic()` can easily be inserted into\npre-existing code.\n\n```pycon\n\u003e\u003e\u003e a = 6\n\u003e\u003e\u003e def half(i):\n\u003e\u003e\u003e     return i / 2\n\u003e\u003e\u003e b = half(ic(a))\nic| a: 6\n\u003e\u003e\u003e ic(b)\nic| b: 3\n```\n\n\n### Miscellaneous\n\n`ic.format(*args)` is like `ic()` but the output is returned as a string instead\nof written to stderr.\n\n```pycon\n\u003e\u003e\u003e from icecream import ic\n\u003e\u003e\u003e s = 'sup'\n\u003e\u003e\u003e out = ic.format(s)\n\u003e\u003e\u003e print(out)\nic| s: 'sup'\n```\n\nAdditionally, `ic()`'s output can be entirely disabled, and later re-enabled, with\n`ic.disable()` and `ic.enable()` respectively.\n\n```python\nfrom icecream import ic\n\nic(1)\n\nic.disable()\nic(2)\n\nic.enable()\nic(3)\n```\n\nPrints\n\n```\nic| 1: 1\nic| 3: 3\n```\n\n`ic()` continues to return its arguments when disabled, of course; no existing\ncode with `ic()` breaks.\n\n\n### Import Tricks\n\nTo make `ic()` available in every file without needing to be imported in\nevery file, you can `install()` it. For example, in a root `A.py`:\n\n```python\n#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nfrom icecream import install\ninstall()\n\nfrom B import foo\nfoo()\n```\n\nand then in `B.py`, which is imported by `A.py`, just call `ic()`:\n\n```python\n# -*- coding: utf-8 -*-\n\ndef foo():\n    x = 3\n    ic(x)\n```\n\n`install()` adds `ic()` to the\n[builtins](https://docs.python.org/3.8/library/builtins.html) module,\nwhich is shared amongst all files imported by the interpreter.\nSimilarly, `ic()` can later be `uninstall()`ed, too.\n\n`ic()` can also be imported in a manner that fails gracefully if\nIceCream isn't installed, like in production environments (i.e. not\ndevelopment). To that end, this fallback import snippet may prove\nuseful:\n\n```python\ntry:\n    from icecream import ic\nexcept ImportError:  # Graceful fallback if IceCream isn't installed.\n    ic = lambda *a: None if not a else (a[0] if len(a) == 1 else a)  # noqa\n```\n\n\n### Configuration\n\n`ic.configureOutput(prefix, outputFunction, argToStringFunction,\nincludeContext, contextAbsPath)` controls `ic()`'s output.\n\n`prefix`, if provided, adopts a custom output prefix. `prefix` can be a\nstring, like\n\n```pycon\n\u003e\u003e\u003e from icecream import ic\n\u003e\u003e\u003e ic.configureOutput(prefix='hello -\u003e ')\n\u003e\u003e\u003e ic('world')\nhello -\u003e 'world'\n```\n\nor a function.\n\n```pycon\n\u003e\u003e\u003e import time\n\u003e\u003e\u003e from icecream import ic\n\u003e\u003e\u003e  \n\u003e\u003e\u003e def unixTimestamp():\n\u003e\u003e\u003e     return '%i |\u003e ' % int(time.time())\n\u003e\u003e\u003e\n\u003e\u003e\u003e ic.configureOutput(prefix=unixTimestamp)\n\u003e\u003e\u003e ic('world')\n1519185860 |\u003e 'world': 'world'\n```\n\n`prefix`'s default value is `ic| `.\n\n`outputFunction`, if provided, is called once for every `ic()` call with\n`ic()`'s output, as a string, instead of that string being written to\nstderr (the default).\n\n```pycon\n\u003e\u003e\u003e import logging\n\u003e\u003e\u003e from icecream import ic\n\u003e\u003e\u003e\n\u003e\u003e\u003e def warn(s):\n\u003e\u003e\u003e     logging.warning(\"%s\", s)\n\u003e\u003e\u003e\n\u003e\u003e\u003e ic.configureOutput(outputFunction=warn)\n\u003e\u003e\u003e ic('eep')\nWARNING:root:ic| 'eep': 'eep'\n```\n\n`argToStringFunction`, if provided, is called with argument values to be\nserialized to displayable strings. The default is PrettyPrint's\n[pprint.pformat()](https://docs.python.org/3/library/pprint.html#pprint.pformat),\nbut this can be changed to, for example, handle non-standard datatypes\nin a custom fashion.\n\n```pycon\n\u003e\u003e\u003e from icecream import ic\n\u003e\u003e\u003e\n\u003e\u003e\u003e def toString(obj):\n\u003e\u003e\u003e    if isinstance(obj, str):\n\u003e\u003e\u003e        return '[!string %r with length %i!]' % (obj, len(obj))\n\u003e\u003e\u003e    return repr(obj)\n\u003e\u003e\u003e\n\u003e\u003e\u003e ic.configureOutput(argToStringFunction=toString)\n\u003e\u003e\u003e ic(7, 'hello')\nic| 7: 7, 'hello': [!string 'hello' with length 5!]\n```\n\nThe default `argToStringFunction` is `icecream.argumentToString`, and\nhas methods to `register` and `unregister` functions to be dispatched\nfor specific classes using `functools.singledispatch`. It also has a\n`registry` property to view registered functions.\n\n```pycon\n\u003e\u003e\u003e from icecream import ic, argumentToString\n\u003e\u003e\u003e import numpy as np\n\u003e\u003e\u003e\n\u003e\u003e\u003e # Register a function to summarize numpy array\n\u003e\u003e\u003e @argumentToString.register(np.ndarray)\n\u003e\u003e\u003e def _(obj):\n\u003e\u003e\u003e     return f\"ndarray, shape={obj.shape}, dtype={obj.dtype}\"\n\u003e\u003e\u003e\n\u003e\u003e\u003e x = np.zeros((1, 2))\n\u003e\u003e\u003e ic(x)\nic| x: ndarray, shape=(1, 2), dtype=float64\n\u003e\u003e\u003e\n\u003e\u003e\u003e # View registered functions\n\u003e\u003e\u003e argumentToString.registry\nmappingproxy({object: \u003cfunction icecream.icecream.argumentToString(obj)\u003e,\n              numpy.ndarray: \u003cfunction __main__._(obj)\u003e})\n\u003e\u003e\u003e\n\u003e\u003e\u003e # Unregister a function and fallback to the default behavior\n\u003e\u003e\u003e argumentToString.unregister(np.ndarray)\n\u003e\u003e\u003e ic(x)\nic| x: array([[0., 0.]])\n```\n\n`includeContext`, if provided and True, adds the `ic()` call's filename,\nline number, and parent function to `ic()`'s output.\n\n```pycon\n\u003e\u003e\u003e from icecream import ic\n\u003e\u003e\u003e ic.configureOutput(includeContext=True)\n\u003e\u003e\u003e\n\u003e\u003e\u003e def foo():\n\u003e\u003e\u003e   i = 3\n\u003e\u003e\u003e   ic(i)\n\u003e\u003e\u003e foo()\nic| example.py:12 in foo()- i: 3\n```\n\n`includeContext` is False by default.\n\n`contextAbsPath`, if provided and True, outputs absolute filepaths, like\n`/path/to/foo.py`, over just filenames, like `foo.py`, when `ic()` is\ncalled with `includeContext == True`. This is useful when debugging\nmultiple files that share the same filename(s). Moreover, some editors,\nlike VSCode, turn absolute filepaths into clickable links that open the\nfile where `ic()` was called.\n\n```pycon\n\u003e\u003e\u003e from icecream import ic\n\u003e\u003e\u003e ic.configureOutput(includeContext=True, contextAbsPath=True)\n\u003e\u003e\u003e\n\u003e\u003e\u003e i = 3\n\u003e\u003e\u003e\n\u003e\u003e\u003e def foo():\n\u003e\u003e\u003e   ic(i)\n\u003e\u003e\u003e foo()\nic| /absolute/path/to/example.py:12 in foo()- i: 3\n\u003e\u003e\u003e\n\u003e\u003e\u003e ic.configureOutput(includeContext=True, contextAbsPath=False)\n\u003e\u003e\u003e\n\u003e\u003e\u003e def foo():\n\u003e\u003e\u003e   ic(i)\n\u003e\u003e\u003e foo()\nic| example.py:18 in foo()- i: 3\n```\n\n`contextAbsPath` is False by default.\n\nIf you want to use icecream with multiple log levels, like with Python’s\n`logging` module, you can use `ic.format()` to integrate icecream’s\ndebugging with your logger:\n\n```python\nimport logging\nfrom icecream import ic\n\nfoo = 'bar'\nlogging.debug(ic.format(foo))\n```\n\n❕ This is a bit clunky. Would you prefer built-in log level support in\nicecream? If so, please share your thoughts in\n[issue](https://github.com/gruns/icecream/issues/146).\n\n\n### Installation\n\nInstalling IceCream with pip is easy.\n\n```\n$ pip install icecream\n```\n\n\n### Related Python libraries\n\n`ic()` uses [**`executing`**](https://github.com/alexmojaki/executing)\nby [**@alexmojaki**](https://github.com/alexmojaki) to reliably locate\n`ic()` calls in Python source. It's magic.\n\n\n### IceCream in Other Languages\n\nDelicious IceCream should be enjoyed in every language.\n\n- Dart: [icecream](https://github.com/HallerPatrick/icecream)\n- Rust: [icecream-rs](https://github.com/ericchang00/icecream-rs)\n- Node.js: [node-icecream](https://github.com/jmerle/node-icecream)\n- C++: [IceCream-Cpp](https://github.com/renatoGarcia/icecream-cpp)\n- C99: [icecream-c](https://github.com/chunqian/icecream-c)\n- PHP: [icecream-php](https://github.com/ntzm/icecream-php)\n- Go: [icecream-go](https://github.com/WAY29/icecream-go)\n- Ruby: [Ricecream](https://github.com/nodai2hITC/ricecream)\n- Java: [icecream-java](https://github.com/Akshay-Thakare/icecream-java)\n- R: [icecream](https://github.com/lewinfox/icecream)\n- Lua: [icecream-lua](https://github.com/wlingze/icecream-lua)\n- Clojure(Script): [icecream-cljc](https://github.com/Eigenbahn/icecream-cljc)\n- Bash: [IceCream-Bash](https://github.com/jtplaarj/IceCream-Bash)\n- SystemVerilog: [icecream_sv](https://github.com/xver/icecream_sv)\n- GameMaker Language: [GMIceCream](https://github.com/dicksonlaw583/GMIceCream)\n\nIf you'd like a similar `ic()` function in your favorite language, please open a\npull request! IceCream's goal is to sweeten print debugging with a handy-dandy\n`ic()` function in every language.\n","funding_links":[],"categories":["Debugging Tools","Python","资源列表","调试工具","Python 程序","Debugging Tools [🔝](#readme)","Awesome Python","📦 Additional Python Libraries"],"sub_categories":["调试工具","Other dialects and variants","网络服务_其他","Debugging Tools","Code Quality \u0026 Development"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgruns%2Ficecream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgruns%2Ficecream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgruns%2Ficecream/lists"}