In Python 3.3+, socket.error is no longer a distinct exception.
It is - as the docs say - "A deprecated alias of OSError". This
means that this check:
isinstance(e, socket.error)
is effectively equivalent to:
isinstance(e, OSError)
This is a problem, because requests.exceptions.ConnectionError
(another exception type we handle later in is_conn_error()) is
a subclass of OSError - so on Python 3 we never actually reach
the block that's intended to handle that exception type. We hit
the isinstance(e, socket.error) block at the start instead, and
of course the exception doesn't have an errno attribute, so we
just return False at that point.
There are a few different ways we could fix this; this commit
does it by ditching the isinstance checks, and dropping the
shortcut return False bailout from the early block. We'll still
ultimately return False unless the error is actually one of the
other types we handle; it just costs a couple more isinstance
checks.
I don't think replacing the isinstance socket.error checks is
really necessary at all. We can just check for an errno attr,
and if there is one and it's one of the values we check for...
that seems safe enough to treat as a connection error.
This also changes the second check to be a check of e2, not e - I'm fairly sure this is what's actually intended, and
the current code was a copy-paste error.
In Python 3.3+,
socket.erroris no longer a distinct exception.It is - as the docs say - "A deprecated alias of OSError". This
means that this check:
isinstance(e, socket.error)is effectively equivalent to:
isinstance(e, OSError)This is a problem, because
requests.exceptions.ConnectionError(another exception type we handle later in
is_conn_error()) isa subclass of
OSError- so on Python 3 we never actually reachthe block that's intended to handle that exception type. We hit
the
isinstance(e, socket.error)block at the start instead, andof course the exception doesn't have an
errnoattribute, so wejust return
Falseat that point.There are a few different ways we could fix this; this commit
does it by ditching the
isinstancechecks, and dropping theshortcut
return Falsebailout from the early block. We'll stillultimately return
Falseunless the error is actually one of theother types we handle; it just costs a couple more
isinstancechecks.
I don't think replacing the
isinstance socket.errorchecks isreally necessary at all. We can just check for an
errnoattr,and if there is one and it's one of the values we check for...
that seems safe enough to treat as a connection error.
This also changes the second check to be a check of
e2, note- I'm fairly sure this is what's actually intended, andthe current code was a copy-paste error.
Signed-off-by: Adam Williamson awilliam@redhat.com