Catch Broken Pipe in Python 2 and Python 3

I am trying to write some code to catch a Broken Pipe error. The code should work in Python 2.x and Python 3.x.

In Python 2.x, a broken pipe is represented by socket.error

 socket.error: [Errno 32] Broken pipe 

This has been changed in Python 3.x - a broken pipe now represents a BrokenPipeError

 BrokenPipeError: [Errno 32] Broken pipe 

Also, the syntax of exception handling has changed a bit (see https://stackoverflow.com/a/126328/ ... ), so I needed something like:

 try: do_something() except BrokenPipeError as e: # implies Python 3.x resolve_for_python2() except socket.error as e: if sys.version_info[0] == 2: # this is necessary, as in Python >=3.3 # socket.error is an alias of OSError # https://docs.python.org/3/library/socket.html#socket.error resolve_for_python3() else: raise 

There is (at least) one remaining problem: Python 2.x does not have BrokenPipeError , so whenever there is an exception in do_something() , Python 2.x throws another exception and complains that it does not know BrokenPipeError . Since socket.error deprecated in Python 3.x, a similar problem may arise in Python 3.x in the near future.

What can I do to make this code run in Python 2.x and Python 3.x?

+5
source share
2 answers

If all you care about is clipping pipe errors, you might want to catch socket.error and just check if it really is a broken pipe error.

You can do this using the exception errno attribute, which is present in both Python 2 and Python 3, which means you don't need other Python 2 logic vs. 3 (I would say intention is a little clearer):

 import socket import errno try: do_something() except socket.error as e: if e.errno != errno.EPIPE: # Not a broken pipe raise do_something_about_the_broken_pipe() 

If you care about more than broken pipes, then their answer is also idiomatic.

+3
source

You can try using BrokenPipeError , and if he NameError , go back to socket.error , like this

 import socket try: expected_error = BrokenPipeError except NameError: expected_error = socket.error 

And then use it like this:

 try: 1 == 2 except expected_error as ex: # Handle the actual exception here 
+1
source

Source: https://habr.com/ru/post/1240325/


All Articles