Commit 1f6bd091 authored by Jason Madden's avatar Jason Madden Committed by GitHub

Merge pull request #1311 from gevent/issue1310

Make gevent.socket.getaddrinfo return enums on Python 3
parents a2c56938 b74209a7
......@@ -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: # pragma: no cover
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):
......
......@@ -383,13 +383,18 @@ class TestLocalhost(TestCase):
return result
if not greentest.RUNNING_ON_TRAVIS:
# ares fails here, for some reason, presumably a badly
# configured /etc/hosts
add(TestLocalhost, 'ip6-localhost')
# Beginning Dec 1 2017, ares started returning ip6-localhost
# instead of localhost
add(TestLocalhost, 'localhost')
add(
TestLocalhost, 'ip6-localhost',
skip=greentest.RUNNING_ON_TRAVIS,
skip_reason="ares fails here, for some reason, presumably a badly "
"configured /etc/hosts"
)
add(
TestLocalhost, 'localhost',
skip=greentest.RUNNING_ON_TRAVIS,
skip_reason="Beginning Dec 1 2017, ares started returning ip6-localhost "
"instead of localhost"
)
class TestNonexistent(TestCase):
......@@ -407,10 +412,12 @@ add(Test1234, '1.2.3.4')
class Test127001(TestCase):
pass
if not greentest.RUNNING_ON_TRAVIS:
# Beginning Dec 1 2017, ares started returning ip6-localhost
# instead of localhost
add(Test127001, '127.0.0.1')
add(Test127001, '127.0.0.1',
skip=greentest.RUNNING_ON_TRAVIS,
skip_reason="Beginning Dec 1 2017, ares started returning ip6-localhost "
"instead of localhost"
)
class TestBroadcast(TestCase):
......@@ -440,7 +447,7 @@ class SanitizedHostsFile(HostsFile):
# We get extra results from some impls, like OS X
# it returns DGRAM results
or name == 'localhost')):
continue
continue # pragma: no cover
if name.endswith('local'):
# These can only be found if bonjour is running,
# and are very slow to do so with the system resolver on OS X
......@@ -495,21 +502,6 @@ class TestFamily(TestCase):
cls._result = getattr(socket, 'getaddrinfo')(TestGeventOrg.HOSTNAME, None)
return cls._result
def assert_error(self, error, function, *args): # pylint:disable=arguments-differ
try:
result = function(*args)
raise AssertionError('%s: Expected to raise %s, instead returned %r' % (function, error, result))
except Exception as ex:
if isinstance(error, six.string_types):
repr_error = error
else:
repr_error = repr(error)
if type(ex) is not type(error):
raise
if repr(ex) == repr_error:
return
raise
def test_inet(self):
self.assertEqualResults(self.getresult(),
gevent_socket.getaddrinfo(TestGeventOrg.HOSTNAME, None, socket.AF_INET),
......@@ -564,6 +556,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
......@@ -615,7 +621,7 @@ class TestInterrupted_gethostbyname(gevent.testing.timing.AbstractGenericWaitTes
# gaierror: [Errno -2] Name or service not known
try:
gevent.get_hub().threadpool.join()
except Exception: # pylint:disable=broad-except
except Exception: # pylint:disable=broad-except pragma: no cover
traceback.print_exc()
......
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import print_function, absolute_import, division
import gevent.testing as greentest
import socket
from test__socket_dns import TestCase, add
from gevent.tests.test__socket_dns import TestCase, add
from gevent.testing.sysinfo import RESOLVER_NOT_SYSTEM
from gevent.testing.sysinfo import RESOLVER_DNSPYTHON
......
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