Issue
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?
Solution
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.
Answered By - Thomas Orozco
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.