Commit db7db6a5 authored by Jason Madden's avatar Jason Madden Committed by GitHub

Merge pull request #961 from gevent/issue960

Fix the name of the ``type`` param to gevent.socket.getaddrinfo on Python 3
parents 4b736917 7e6ed0ae
......@@ -14,8 +14,19 @@
``getaddrinfo`` when ``connect`` is called. Reported in :issue:`944`
by Bernie Hackett.
- Replace ``optparse`` module with ``argparse``. See :issue:`947`.
- Update to an unreleased version of ``tblib`` to fix :issue:`954`,
- Update to version 1.3.1 of ``tblib`` to fix :issue:`954`,
reported by ml31415.
- Fix the name of the ``type`` parameter to
:func:`gevent.socket.getaddrinfo` to be correct on Python 3. This
would cause callers using keyword arguments to raise a :exc:`TypeError`.
Reported in :issue:`960` by js6626069. Likewise, correct the
argument names for ``fromfd`` and ``socketpair`` on Python 2,
although they cannot be called wit keyword arguments under CPython.
.. note:: The ``gethost*`` functions take different argument names
under CPython and PyPy. gevent follows the CPython
convention, although these functions cannot be called with
keyword arguments on CPython.
1.2.1 (2017-01-12)
==================
......
......@@ -499,8 +499,9 @@ SocketType = socket
if hasattr(_socket, 'socketpair'):
def socketpair(*args):
one, two = _socket.socketpair(*args)
def socketpair(family=getattr(_socket, 'AF_UNIX', _socket.AF_INET),
type=_socket.SOCK_STREAM, proto=0):
one, two = _socket.socketpair(family, type, proto)
result = socket(_sock=one), socket(_sock=two)
if PYPY:
one._drop()
......@@ -511,8 +512,8 @@ elif 'socketpair' in __implements__:
if hasattr(_socket, 'fromfd'):
def fromfd(*args):
s = _socket.fromfd(*args)
def fromfd(fd, family, type, proto=0):
s = _socket.fromfd(fd, family, type, proto)
result = socket(_sock=s)
if PYPY:
s._drop()
......
......@@ -73,7 +73,7 @@ import sys
from gevent.hub import get_hub
from gevent.hub import ConcurrentObjectUseError
from gevent.timeout import Timeout
from gevent._compat import string_types, integer_types
from gevent._compat import string_types, integer_types, PY3
from gevent._util import copy_globals
from gevent._util import _NONE
......@@ -271,10 +271,24 @@ def getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0):
"""
return get_hub().resolver.getaddrinfo(host, port, family, socktype, proto, flags)
if PY3:
# The name of the socktype param changed to type in Python 3.
# See https://github.com/gevent/gevent/issues/960
# Using inspect here to directly detect the condition is painful because we have to
# wrap it with a try/except TypeError because not all Python 2
# versions can get the args of a builtin; we also have to use a with to suppress
# 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)
getaddrinfo.__doc__ = d
del d
def gethostbyaddr(ip_address):
"""
gethostbyaddr(host) -> (name, aliaslist, addresslist)
gethostbyaddr(ip_address) -> (name, aliaslist, addresslist)
Return the true host name, a list of aliases, and a list of IP addresses,
for a host. The host argument is a string giving a host name or IP number.
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -461,6 +461,50 @@ class TestCase(TestCaseMetaClass("NewBase", (BaseTestCase,), {})):
self.assertGreaterEqual(delay, min_time)
def assertMonkeyPatchedFuncSignatures(self, mod_name, func_names=(), exclude=()):
# We use inspect.getargspec because it's the only thing available
# in Python 2.7, but it is deprecated
# pylint:disable=deprecated-method
import inspect
import warnings
from gevent.monkey import get_original
# XXX: Very similar to gevent.monkey.patch_module. Should refactor?
gevent_module = getattr(__import__('gevent.' + mod_name), mod_name)
module_name = getattr(gevent_module, '__target__', mod_name)
funcs_given = True
if not func_names:
funcs_given = False
func_names = getattr(gevent_module, '__implements__')
for func_name in func_names:
if func_name in exclude:
continue
gevent_func = getattr(gevent_module, func_name)
if not inspect.isfunction(gevent_func) and not funcs_given:
continue
func = get_original(module_name, func_name)
try:
with warnings.catch_warnings():
warnings.simplefilter("ignore")
gevent_sig = inspect.getargspec(gevent_func)
sig = inspect.getargspec(func)
except TypeError:
if funcs_given:
raise
# Can't do this one. If they specifically asked for it,
# it's an error, otherwise it's not.
# Python 3 can check a lot more than Python 2 can.
continue
self.assertEqual(sig.args, gevent_sig.args, func_name)
# The next three might not actually matter?
self.assertEqual(sig.varargs, gevent_sig.varargs, func_name)
self.assertEqual(sig.keywords, gevent_sig.keywords, func_name)
self.assertEqual(sig.defaults, gevent_sig.defaults, func_name)
main = unittest.main
_original_Hub = gevent.hub.Hub
......@@ -547,6 +591,7 @@ class GenericWaitTestCase(_DelayWaitMixin, TestCase):
# and subject to jitter
_default_delay_max_adj = 1.5
@ignores_leakcheck # waiting checks can be very sensitive to timing
def test_returns_none_after_timeout(self):
result = self._wait_and_check()
# join and wait simply return after timeout expires
......
......@@ -336,6 +336,8 @@ class TestCreateConnection(greentest.TestCase):
class TestFunctions(greentest.TestCase):
@greentest.ignores_leakcheck
# Creating new types in the function takes a cycle to cleanup.
def test_wait_timeout(self):
# Issue #635
import gevent.socket
......@@ -360,8 +362,19 @@ class TestFunctions(greentest.TestCase):
finally:
gevent._socketcommon.get_hub = orig_get_hub
# Creating new types in the function takes a cycle to cleanup.
test_wait_timeout.ignore_leakcheck = True
def test_signatures(self):
# https://github.com/gevent/gevent/issues/960
exclude = []
if greentest.PYPY:
# Up through at least PyPy 5.7.1, they define these as
# gethostbyname(host), whereas the official CPython argument name
# is hostname. But cpython doesn't allow calling with keyword args.
# Likewise for gethostbyaddr: PyPy uses host, cpython uses ip_address
exclude.append('gethostbyname')
exclude.append('gethostbyname_ex')
exclude.append('gethostbyaddr')
self.assertMonkeyPatchedFuncSignatures('socket', exclude=exclude)
if __name__ == '__main__':
......
......@@ -535,7 +535,30 @@ class TestInterrupted_gethostbyname(greentest.GenericWaitTestCase):
raise AssertionError('Timeout was not raised')
def cleanup(self):
gevent.get_hub().threadpool.join()
# Depending on timing, this can raise:
# (This suddenly started happening on Apr 6 2016; www.x1000000.com
# is apparently no longer around)
# File "test__socket_dns.py", line 538, in cleanup
# gevent.get_hub().threadpool.join()
# File "/home/travis/build/gevent/gevent/src/gevent/threadpool.py", line 108, in join
# sleep(delay)
# File "/home/travis/build/gevent/gevent/src/gevent/hub.py", line 169, in sleep
# hub.wait(loop.timer(seconds, ref=ref))
# File "/home/travis/build/gevent/gevent/src/gevent/hub.py", line 651, in wait
# result = waiter.get()
# File "/home/travis/build/gevent/gevent/src/gevent/hub.py", line 899, in get
# return self.hub.switch()
# File "/home/travis/build/gevent/gevent/src/greentest/greentest.py", line 520, in switch
# return _original_Hub.switch(self, *args)
# File "/home/travis/build/gevent/gevent/src/gevent/hub.py", line 630, in switch
# return RawGreenlet.switch(self)
# gaierror: [Errno -2] Name or service not known
try:
gevent.get_hub().threadpool.join()
except Exception: # pylint:disable=broad-except
import traceback
traceback.print_exc()
# class TestInterrupted_getaddrinfo(greentest.GenericWaitTestCase):
......
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