aiiie / cram

Functional tests for command line applications
GNU General Public License v2.0
199 stars 51 forks source link

BrokenPipeError when piping cram to head #27

Closed jan-matejka closed 2 years ago

jan-matejka commented 7 years ago
yac@remy % cat foo.t
  $ for i in {0..20}; do echo "y"; done
--------------------------------------------------------------------------------
~
yac@remy % cram foo.t | head -n 1
!
Traceback (most recent call last):
  File "/usr/bin/cram", line 7, in <module>
    sys.exit(cram.main(sys.argv[1:]))
  File "/usr/lib/python3.6/site-packages/cram/_main.py", line 195, in main
    for path, test in tests:
  File "/usr/lib/python3.6/site-packages/cram/_cli.py", line 132, in runcli
    _log('\n', None, verbose)
  File "/usr/lib/python3.6/site-packages/cram/_cli.py", line 50, in _log
    sys.stdout.flush()
BrokenPipeError: [Errno 32] Broken pipe
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe
pjeby commented 7 years ago

FWIW, I was able to fix this in my local install by adding these lines to the end of cram/__main__.py and the cram script:

except IOError as e:
    import errno
    if e.errno != errno.EPIPE:
        raise
jan-matejka commented 7 years ago

Makes sense. I have recently encountered similar problem but in zsh where I had to wrap my pipeline in sigpipe handler like

 sigpipe cat $file | tee foo

where sigpipe:

 function sigpipe {
   local rc
   $@ || {
     rc=$?
     test $rc -eq 141 ||
       test $rc -eq 0 ||
       fatal "failed with unexpected exitcode: $@"
   }
 }

So I think, @pjeby, your patch is correct solution. Though I suspect newer pythons might provide a subtype of IOError for the errno.EPIPE.

roman-neuhauser commented 4 years ago

Dram (https://git.sr.ht/~rne/dram) does not have this bug.