IceCream
Debugging print statement replacement for Python — ic() prints variable names, types, and values with context (file, line, parent function). IceCream features: ic(var) prints 'ic| filename.py:10 in func()- var: value', ic() without args prints caller location, ic.disable() to suppress in production, ic.enable() to re-enable, ic.configureOutput() for custom prefix/output function, ic.includeContext for toggling context display, supports any expression not just variables, and returns its argument for inline use. Drop-in upgrade over print() for debugging Python agents.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
CRITICAL: ic() prints variable values to stderr — if variables contain secrets (API keys, passwords, PII), ic() exposes them in output. Always call ic.disable() in production. Never commit code with ic() calls that may print sensitive data without ic.disable() guard. ic() output is not encrypted or access-controlled.
⚡ Reliability
Best When
Quick interactive debugging of Python agent code during development — ic() shows variable names and values automatically, saving time over print() and providing file/line context.
Avoid When
You need production logging (use loguru), structured output, automated assertions, or performance profiling.
Use Cases
- • Agent variable inspection — from icecream import ic; agent_response = llm.generate(prompt); ic(agent_response) — prints 'ic| agent.py:15 in process()- agent_response: {"action": "search", ...}' with file/line context; agent developer sees variable name automatically; no more print('agent_response:', agent_response)
- • Agent inline debugging — from icecream import ic; result = ic(process_response(ic(llm_call(prompt)))) — ic() returns its argument for inline use; agent code inspects intermediate values in expression chain without breaking into multiple lines; each ic() shows its value with automatic label
- • Agent conditional debugging — from icecream import ic; ic.disable(); # in production; ic.enable() # in debug mode; @agent_handler; def handle(request): ic(request.headers); result = process(request); ic(result) — disable all ic() calls without removing them; agent production code has ic() calls pre-placed for debugging; toggle with environment variable: ic.disable() if os.getenv('ENV') == 'prod' else ic.enable()
- • Agent location tracing — from icecream import ic; ic() # no args — prints only 'ic| myagent.py:42 in execute_step()' with no value; agent developer traces execution path without adding values; determine which branch was taken without boolean variables
- • Agent custom output — from icecream import ic; import logging; ic.configureOutput(prefix='DEBUG| ', outputFunction=logging.debug) — redirect ic() output to logger instead of stderr; agent logging integration: ic() sends to structured log instead of terminal; prefix identifies ic output in log stream
Not For
- • Production logging — ic() is for development debugging; for structured production logging use loguru or structlog
- • Performance profiling — ic() adds string formatting overhead; for performance measurement use py-spy or viztracer
- • Automated testing assertions — ic() is visual inspection not programmatic assertion; use assert or pytest assertions for test validation
Interface
Authentication
No auth — local debugging library.
Pricing
IceCream is MIT licensed. Free for all use.
Agent Metadata
Known Gotchas
- ⚠ ic() output goes to stderr not stdout — ic(value) writes to sys.stderr by default; agent code capturing stdout misses ic() output; redirecting stdout does not capture ic() output; use ic.configureOutput(outputFunction=print) to redirect to stdout; or ic.configureOutput(outputFunction=logging.debug) for log integration
- ⚠ ic.disable() is global not per-instance — from icecream import ic; ic.disable() disables all ic() calls in all modules; agent code with separate debug contexts cannot disable selectively; ic() is a module-level singleton; for per-module control create separate instances: from icecream import IceCreamDebugger; my_ic = IceCreamDebugger(); my_ic.disable()
- ⚠ Large objects format slowly — ic(huge_dataframe) formats entire DataFrame repr for output; 100K-row DataFrame ic() call takes seconds; agent code using ic() in loops with large objects should: ic(df.shape) not ic(df); or ic.configureOutput(prefix='', outputFunction=lambda s: None) to suppress temporarily
- ⚠ includeContext=True requires inspect overhead — ic() by default includes file/line/function context via Python's inspect module; this adds ~0.05ms per call; agent hot paths should: ic.configureOutput(includeContext=False) for minimal overhead when context not needed; context is most valuable for location tracing not value inspection
- ⚠ ic() in comprehensions shows expression not variable — ic([x for x in range(3)]) shows 'ic| list comprehension result: [0,1,2]' not individual x values; agent code wanting per-iteration ic() must unroll: for x in range(3): ic(x); ic() inside comprehension shows final result only
- ⚠ Jupyter notebooks show duplicate output — in Jupyter, ic() outputs to stderr which appears inline with cell output; combined with cell's normal output creates duplicate display; agent Jupyter notebook debugging should use ic.configureOutput(outputFunction=print) for cleaner Jupyter display or use IPython display() for rich object inspection
Alternatives
Full Evaluation Report
Comprehensive deep-dive: security analysis, reliability audit, agent experience review, cost modeling, competitive positioning, and improvement roadmap for IceCream.
AI-powered analysis · PDF + markdown · Delivered within 30 minutes
Package Brief
Quick verdict, integration guide, cost projections, gotchas with workarounds, and alternatives comparison.
Delivered within 10 minutes
Score Monitoring
Get alerted when this package's AF, security, or reliability scores change significantly. Stay ahead of regressions.
Continuous monitoring
Scores are editorial opinions as of 2026-03-06.