I try to write some code to catch a Broken Pipe Error. The code should run in Python 2.x and Python 3.x.
In Python 2.x a broken pipe is represented by a socket.error
socket.error: [Errno 32] Broken pipe
This was changed in Python 3.x - a broken pipe now is a BrokenPipeError
BrokenPipeError: [Errno 32] Broken pipe
Also the syntax of exception handling has changed a bit (see https://stackoverflow.com/a/34463112/263589) so what I need to do would be 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's (at least) one remaining problem: In Python 2.x there is no BrokenPipeError
, so whenever there is an exception in do_something()
Python 2.x would throw another exception and complain that it doesn't know BrokenPipeError
. As socket.error
is deprecated in Python 3.x a similar problem could 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?
If all you care about are broken pipe errors, then you might want to catch socket.error
and simply check whether it's indeed a broken pipe error.
You can do so using the exception's errno
attribute, which is present in both Python 2 and Python 3, which means, you don't need different Python 2 vs. 3 logic (I'd argue the intent is a little clearer this way):
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 do care about more than broken pipes, thefourtheye's answer is appropriate and idiomatic.
You can try using BrokenPipeError
and if it throws a NameError
, then fall 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
来源:https://stackoverflow.com/questions/34718208/catch-broken-pipe-in-python-2-and-python-3