Commit 6e0ef748 authored by Jason Madden's avatar Jason Madden

Make gevent.socket.getaddrinfo return enums on Python 3

Fixes #1310
parent a2c56938
...@@ -46,6 +46,10 @@ ...@@ -46,6 +46,10 @@
reusable. In particular, the tests are now run with ``python -m reusable. In particular, the tests are now run with ``python -m
gevent.tests``. See :issue:`1293`. gevent.tests``. See :issue:`1293`.
- Make a monkey-patched ``socket.getaddrinfo`` return socket module
enums instead of plain integers for the socket type and address
family on Python 3. See :issue:`1310` reported by TheYOSH.
1.3.7 (2018-10-12) 1.3.7 (2018-10-12)
================== ==================
......
...@@ -204,11 +204,30 @@ if PY3: ...@@ -204,11 +204,30 @@ if PY3:
# the deprecation warning. # the deprecation warning.
d = getaddrinfo.__doc__ d = getaddrinfo.__doc__
def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): # pylint:disable=function-redefined def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
return get_hub().resolver.getaddrinfo(host, port, family, type, proto, flags) # pylint:disable=function-redefined, undefined-variable
# Also, on Python 3, we need to translate into the special enums.
# Our lower-level resolvers, including the thread and blocking, which use _socket,
# function simply with integers.
addrlist = get_hub().resolver.getaddrinfo(host, port, family, type, proto, flags)
result = [
(_intenum_converter(af, AddressFamily),
_intenum_converter(socktype, SocketKind),
proto, canonname, sa)
for af, socktype, proto, canonname, sa
in addrlist
]
return result
getaddrinfo.__doc__ = d getaddrinfo.__doc__ = d
del d del d
def _intenum_converter(value, enum_klass):
try:
return enum_klass(value)
except ValueError:
return value
def gethostbyaddr(ip_address): def gethostbyaddr(ip_address):
""" """
......
...@@ -4,18 +4,18 @@ from _socket import gaierror ...@@ -4,18 +4,18 @@ from _socket import gaierror
from _socket import error from _socket import error
from _socket import getservbyname from _socket import getservbyname
from _socket import getaddrinfo from _socket import getaddrinfo
from _socket import SOCK_STREAM
from _socket import SOCK_DGRAM
from _socket import SOL_TCP
from _socket import AI_CANONNAME
from _socket import EAI_SERVICE
from _socket import AF_INET
from _socket import AI_PASSIVE
from gevent._compat import string_types from gevent._compat import string_types
from gevent._compat import integer_types from gevent._compat import integer_types
from gevent.socket import SOCK_STREAM
from gevent.socket import SOCK_DGRAM
from gevent.socket import SOL_TCP
from gevent.socket import AI_CANONNAME
from gevent.socket import EAI_SERVICE
from gevent.socket import AF_INET
from gevent.socket import AI_PASSIVE
# Nothing public here. # Nothing public here.
__all__ = [] __all__ = []
......
from __future__ import print_function from __future__ import print_function
import pickle import pickle
import sys
import gevent.testing as greentest import gevent.testing as greentest
try: try:
from gevent.resolver.cares import ares_host_result from gevent.resolver.cares import ares_host_result
except ImportError as ex: except ImportError: # pragma: no cover
print(ex) ares_host_result = None
sys.exit(0)
@greentest.skipIf(ares_host_result is None,
"Must be able to import ares")
class TestPickle(greentest.TestCase): class TestPickle(greentest.TestCase):
# Issue 104: ares.ares_host_result unpickleable # Issue 104: ares.ares_host_result unpickleable
...@@ -17,8 +17,9 @@ class TestPickle(greentest.TestCase): ...@@ -17,8 +17,9 @@ class TestPickle(greentest.TestCase):
r = ares_host_result('family', ('arg1', 'arg2', )) r = ares_host_result('family', ('arg1', 'arg2', ))
dumped = pickle.dumps(r, protocol) dumped = pickle.dumps(r, protocol)
loaded = pickle.loads(dumped) loaded = pickle.loads(dumped)
assert r == loaded, (r, loaded) self.assertEqual(r, loaded)
assert r.family == loaded.family, (r, loaded) self.assertEqual(r.family, loaded.family)
for i in range(0, pickle.HIGHEST_PROTOCOL): for i in range(0, pickle.HIGHEST_PROTOCOL):
def make_test(j): def make_test(j):
......
...@@ -564,6 +564,20 @@ class Test_getaddrinfo(TestCase): ...@@ -564,6 +564,20 @@ class Test_getaddrinfo(TestCase):
return self._test_getaddrinfo('google.com', 'http', socket.AF_INET6) return self._test_getaddrinfo('google.com', 'http', socket.AF_INET6)
@greentest.skipIf(PY2, "Enums only on Python 3.4+")
def test_enums(self):
# https://github.com/gevent/gevent/issues/1310
# On Python 3, getaddrinfo does special things to make sure that
# the fancy enums are returned.
gai = gevent_socket.getaddrinfo('example.com', 80,
socket.AF_INET,
socket.SOCK_STREAM, socket.IPPROTO_TCP)
af, socktype, _proto, _canonname, _sa = gai[0]
self.assertIs(socktype, socket.SOCK_STREAM)
self.assertIs(af, socket.AF_INET)
class TestInternational(TestCase): class TestInternational(TestCase):
pass pass
......
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