I have a script which ends in the usual fashion:
if __name__ == "__main__":
sys.exit(main())
If I run that script like so:
% python ... | head
I get predictable errors about the broken pipe:
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/Users/skip/src/csvprogs/csvprogs/hull.py", line 144, in <module>
sys.exit(main())
^^^^^^
File "/Users/skip/src/csvprogs/csvprogs/hull.py", line 128, in main
wtr.writerow(row)
File "/Users/skip/miniconda3/envs/python312/lib/python3.12/csv.py", line 164, in writerow
return self.writer.writerow(self._dict_to_list(rowdict))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
BrokenPipeError: [Errno 32] Broken pipe
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
BrokenPipeError: [Errno 32] Broken pipe
This output is understandable, but in situations where a downstream pipeline element cuts it off at the knees, I don’t need/want that traceback. I embellished the script with this little context manager (similar to many examples in the contextlib
docs):
@contextmanager
def swallow_exceptions(exceptions):
"catch and swallow the tuple of exceptions"
try:
yield None
except exceptions:
pass
finally:
pass
like so:
if __name__ == "__main__":
with swallow_exceptions((BrokenPipeError, KeyboardInterrupt)):
sys.exit(main())
Running it a second time gets rid of most of the error output, but not all of it:
% python ... | head
...
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
BrokenPipeError: [Errno 32] Broken pipe
This is a simple single-threaded Python script (running using Conda Python 3.12.3 on a Mac, if that matters). I’ve clearly attempted to suppress the BrokenPipeError
, but only partially succeeded.
Looking through the 3.12 source I find what I think to be the culprit in .../Python/errors.c
, but don’t understand the logic which goes into reaching this spot.
What am I doing wrong to keep my script from complete silence in the face of a broken pipe?