Commit cd77375f authored by Jason Madden's avatar Jason Madden

Fix #841

parent 75e0d3ca
...@@ -85,6 +85,11 @@ Stdlib Compatibility ...@@ -85,6 +85,11 @@ Stdlib Compatibility
and generally only exposes methods appropriate to the mode it is in. and generally only exposes methods appropriate to the mode it is in.
- ``FileObjectPosix`` supports a *bufsize* of 0 in binary write modes. - ``FileObjectPosix`` supports a *bufsize* of 0 in binary write modes.
Reported in :issue:`840` by Mike Lang. Reported in :issue:`840` by Mike Lang.
- Python 3: meth:`gevent.socket.connect_ex` was letting
``BlockingIOError`` (and possibly others) get raised instead of
returning the errno due to the refactoring of the exception
hierarchy in Python 3.3. Now the errno is returned. Reported in
:issue:`841` by Dana Powers.
Other Changes Other Changes
------------- -------------
......
...@@ -307,11 +307,17 @@ class socket(object): ...@@ -307,11 +307,17 @@ class socket(object):
return self.connect(address) or 0 return self.connect(address) or 0
except timeout: except timeout:
return EAGAIN return EAGAIN
except gaierror:
# gaierror/overflowerror/typerror is not silented by connect_ex;
# gaierror extends OSError (aka error) so catch it first
raise
except error as ex: except error as ex:
if type(ex) is error: # pylint:disable=unidiomatic-typecheck # error is now OSError and it has various subclasses.
return ex.args[0] # Only those that apply to actually connecting are silenced by
else: # connect_ex.
raise # gaierror is not silented by connect_ex if ex.errno:
return ex.errno
raise # pragma: no cover
def recv(self, *args): def recv(self, *args):
while True: while True:
......
...@@ -12,6 +12,7 @@ import _six as six ...@@ -12,6 +12,7 @@ import _six as six
# we use threading on purpose so that we can test both regular and gevent sockets with the same code # we use threading on purpose so that we can test both regular and gevent sockets with the same code
from threading import Thread as _Thread from threading import Thread as _Thread
errno_types = int
def wrap_error(func): def wrap_error(func):
...@@ -261,6 +262,28 @@ class TestTCP(greentest.TestCase): ...@@ -261,6 +262,28 @@ class TestTCP(greentest.TestCase):
s.close() s.close()
def test_connect_ex_nonblocking_bad_connection(self):
# Issue 841
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setblocking(False)
ret = s.connect_ex(('localhost', get_port()))
self.assertIsInstance(ret, errno_types)
s.close()
def test_connect_ex_gaierror(self):
# Issue 841
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
with self.assertRaises(socket.gaierror):
s.connect_ex(('foo.bar.fizzbuzz', get_port()))
s.close()
def test_connect_ex_nonblocking_overflow(self):
# Issue 841
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setblocking(False)
with self.assertRaises(OverflowError):
s.connect_ex(('localhost', 65539))
s.close()
def get_port(): def get_port():
tempsock = socket.socket() tempsock = socket.socket()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment