Skip to content

Commit 6fed8e8

Browse files
committed
Fail more gracefully in case the standard output streams aren't available
1 parent f91f15b commit 6fed8e8

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

stackprinter/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,20 @@ def show(thing=None, file='stderr', **kwargs):
175175
**kwargs:
176176
See `format`
177177
"""
178+
179+
# First, to handle a very rare edge case:
180+
# Apparently there are environments where sys.stdout and stderr
181+
# are None (like the pythonw.exe GUI https://stackoverflow.com/a/30313091).
182+
# In those cases, it's not clear where our output should go unless the user
183+
# specifies their own file for output. So I'll make a pragmatic assumption:
184+
# If `show` is called with the default 'stderr' argument but we are in an
185+
# environment where that stream doesn't exist, we're most likely running as
186+
# part of a library that's imported in someone's GUI project and there just
187+
# isn't any error logging (if there was, the user would've given us a file).
188+
# So the least annoying behavior for us is to return silently, not crashing.
189+
if file == 'stderr' and sys.stderr is None:
190+
return
191+
178192
if file == 'stderr':
179193
file = sys.stderr
180194
elif file == 'stdout':
@@ -227,6 +241,8 @@ def show_current_exception(file=sys.stderr, **kwargs):
227241
**kwargs:
228242
See `show`
229243
"""
244+
if file is None:
245+
return # see explanation in `show()`
230246
print(format_current_exception(**kwargs), file=file)
231247

232248

stackprinter/tracing.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def dosometing():
2525
depth_limit: int (default: 20)
2626
How many nested calls will be followed
2727
28-
print_function: callable (default: sys.stderr.write)
28+
print_function: callable (default: print)
2929
some function of your choice that accepts a string
3030
3131
stop_on_exception: bool (default: True)
@@ -68,7 +68,7 @@ class TracePrinter():
6868
depth_limit: int (default: 20)
6969
How many nested calls will be followed
7070
71-
print_function: callable (default: sys.stderr.write)
71+
print_function: callable (default: print)
7272
some function of your choice that accepts a string
7373
7474
stop_on_exception: bool (default: True)
@@ -79,7 +79,7 @@ class TracePrinter():
7979
def __init__(self,
8080
suppressed_paths=[],
8181
depth_limit=20,
82-
print_function=sys.stderr.write,
82+
print_function=print,
8383
stop_on_exception=True,
8484
**formatter_kwargs):
8585

0 commit comments

Comments
 (0)