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 @@
reusable. In particular, the tests are now run with ``python -m
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)
==================
......
......@@ -204,11 +204,30 @@ if PY3:
# the deprecation warning.
d = getaddrinfo.__doc__
def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): # pylint:disable=function-redefined
return get_hub().resolver.getaddrinfo(host, port, family, type, proto, flags)
def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
# 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
del d
def _intenum_converter(value, enum_klass):
try:
return enum_klass(value)
except ValueError:
return value
def gethostbyaddr(ip_address):
"""
......
......@@ -4,18 +4,18 @@ from _socket import gaierror
from _socket import error
from _socket import getservbyname
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 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.
__all__ = []
......
from __future__ import print_function
import pickle
import sys
import gevent.testing as greentest
try:
from gevent.resolver.cares import ares_host_result
except ImportError as ex:
print(ex)
sys.exit(0)
except ImportError: # pragma: no cover
ares_host_result = None
@greentest.skipIf(ares_host_result is None,
"Must be able to import ares")
class TestPickle(greentest.TestCase):
# Issue 104: ares.ares_host_result unpickleable
......@@ -17,8 +17,9 @@ class TestPickle(greentest.TestCase):
r = ares_host_result('family', ('arg1', 'arg2', ))
dumped = pickle.dumps(r, protocol)
loaded = pickle.loads(dumped)
assert r == loaded, (r, loaded)
assert r.family == loaded.family, (r, loaded)
self.assertEqual(r, loaded)
self.assertEqual(r.family, loaded.family)
for i in range(0, pickle.HIGHEST_PROTOCOL):
def make_test(j):
......
......@@ -564,6 +564,20 @@ class Test_getaddrinfo(TestCase):
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):
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