diff --git a/README.md b/README.md index d553dd3..eef07cd 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,8 @@ except ImportError: # Graceful fallback if IceCream isn't installed. ### Configuration +By default, icecream will output to stderr unless the environment variable `PYTHON_ICECREAM_USE_STDOUT ` is true (i.e. if it case insensitively matches `1`, `y`, `yes`, `t` or `true`). It will also switch to the stdout if running inside Jupyter. + `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 diff --git a/icecream/icecream.py b/icecream/icecream.py index 5a7ae4c..051b3b4 100644 --- a/icecream/icecream.py +++ b/icecream/icecream.py @@ -11,8 +11,10 @@ # License: MIT # + from __future__ import print_function +import os import ast import inspect import pprint @@ -63,9 +65,8 @@ def supportTerminalColorsInWindows(): yield colorama.deinit() - -def stderrPrint(*args): - print(*args, file=sys.stderr) +def ICFilePrint(*args): + print(*args, file=DEFAULT_OUTPUT_FILE) def isLiteral(s): @@ -76,18 +77,27 @@ def isLiteral(s): return True -def colorizedStderrPrint(s): +def colorizedICFilePrint(s): colored = colorize(s) with supportTerminalColorsInWindows(): - stderrPrint(colored) + ICFilePrint(colored) DEFAULT_PREFIX = 'ic| ' DEFAULT_LINE_WRAP_WIDTH = 70 # Characters. DEFAULT_CONTEXT_DELIMITER = '- ' -DEFAULT_OUTPUT_FUNCTION = colorizedStderrPrint +DEFAULT_OUTPUT_FUNCTION = colorizedICFilePrint DEFAULT_ARG_TO_STRING_FUNCTION = pprint.pformat +def str2bool(v): + return str(v).lower() in ["yes", "true", "t", "1", "y"] + +def is_in_jupyter(): + try: + from IPython import get_ipython + return get_ipython() is not None + except ModuleNotFoundError: + return False class NoSourceAvailableError(OSError): """ @@ -329,5 +339,14 @@ def configureOutput(self, prefix=_absent, outputFunction=_absent, if includeContext is not _absent: self.includeContext = includeContext +def reload(): + global ic, DEFAULT_OUTPUT_FILE + + if is_in_jupyter() or str2bool(os.environ.get('PYTHON_ICECREAM_USE_STDOUT')): + DEFAULT_OUTPUT_FILE = sys.stdout + else: + DEFAULT_OUTPUT_FILE = sys.stderr + + ic = IceCreamDebugger() -ic = IceCreamDebugger() +reload() diff --git a/tests/test_icecream.py b/tests/test_icecream.py index 8c695ee..c602cf6 100644 --- a/tests/test_icecream.py +++ b/tests/test_icecream.py @@ -19,9 +19,12 @@ from contextlib import contextmanager from os.path import basename, splitext +import os import icecream -from icecream import ic, stderrPrint, NoSourceAvailableError +from icecream import ic, ICFilePrint, NoSourceAvailableError +# Ensure our tests don't fail because of a misconfigured environment +os.environ['PYTHON_ICECREAM_USE_STDOUT'] = 'False' TEST_PAIR_DELIMITER = '| ' MYFILENAME = basename(__file__) @@ -54,7 +57,7 @@ def isatty(self): def disableColoring(): originalOutputFunction = ic.outputFunction - ic.configureOutput(outputFunction=stderrPrint) + ic.configureOutput(outputFunction=ICFilePrint) yield ic.configureOutput(outputFunction=originalOutputFunction) @@ -92,8 +95,10 @@ def captureStandardStreams(): try: sys.stdout = newStdout sys.stderr = newStderr + icecream.reload() yield newStdout, newStderr finally: + icecream.reload() sys.stdout = realStdout sys.stderr = realStderr @@ -302,7 +307,7 @@ def testDifferentName(self): def testPrefixConfiguration(self): prefix = 'lolsup ' - with configureIcecreamOutput(prefix, stderrPrint): + with configureIcecreamOutput(prefix, ICFilePrint): with disableColoring(), captureStandardStreams() as (out, err): ic(a) pair = parseOutputIntoPairs(out, err, 1, prefix=prefix)[0][0]