Commit 8d001495 authored by Jason Madden's avatar Jason Madden

Add backports.socketpair as test/recommended extra on Windows/Py2

We use it in our selector tests.
parent ae5d62d2
...@@ -40,6 +40,11 @@ environment: ...@@ -40,6 +40,11 @@ environment:
# a later point release. # a later point release.
# 64-bit # 64-bit
- PYTHON: "C:\\Python27-x64"
PYTHON_VERSION: "2.7.x" # currently 2.7.13
PYTHON_ARCH: "64"
PYTHON_EXE: python
- PYTHON: "C:\\Python38-x64" - PYTHON: "C:\\Python38-x64"
PYTHON_VERSION: "3.8.x" PYTHON_VERSION: "3.8.x"
PYTHON_ARCH: "64" PYTHON_ARCH: "64"
...@@ -50,11 +55,6 @@ environment: ...@@ -50,11 +55,6 @@ environment:
PYTHON_ARCH: "64" PYTHON_ARCH: "64"
PYTHON_EXE: python PYTHON_EXE: python
- PYTHON: "C:\\Python27-x64"
PYTHON_VERSION: "2.7.x" # currently 2.7.13
PYTHON_ARCH: "64"
PYTHON_EXE: python
- PYTHON: "C:\\Python36-x64" - PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.x" # currently 3.6.0 PYTHON_VERSION: "3.6.x" # currently 3.6.0
PYTHON_ARCH: "64" PYTHON_ARCH: "64"
......
...@@ -146,7 +146,13 @@ monitor ...@@ -146,7 +146,13 @@ monitor
build on all platforms.) build on all platforms.)
recommended recommended
A shortcut for installing suggested extras together. A shortcut for installing suggested extras together. This includes
the non-test extras defined here, plus:
- `backports.socketpair
<https://pypi.org/project/backports.socketpair/>`_ on Python
2/Windows (beginning with release 20.6.0);
- `selectors2 <https://pypi.org/project/selectors2/>`_ on Python 2 (beginning with release 20.6.0).
test test
Everything needed to run the complete gevent test suite. Everything needed to run the complete gevent test suite.
......
...@@ -317,6 +317,8 @@ EXTRA_RECOMMENDED = [ ...@@ -317,6 +317,8 @@ EXTRA_RECOMMENDED = [
CFFI_DEP, CFFI_DEP,
# Backport of selectors module to Python 2 # Backport of selectors module to Python 2
'selectors2 ; python_version == "2.7"', 'selectors2 ; python_version == "2.7"',
# Backport of socket.socketpair to Python 2; only needed on Windows
'backports.socketpair ; python_version == "2.7" and sys_platform == "win32"',
] + EXTRA_DNSPYTHON + EXTRA_EVENTS + EXTRA_MONITOR ] + EXTRA_DNSPYTHON + EXTRA_EVENTS + EXTRA_MONITOR
......
...@@ -194,6 +194,10 @@ class AbstractLinkable(object): ...@@ -194,6 +194,10 @@ class AbstractLinkable(object):
# The object itself becomes false in a boolean way as soon # The object itself becomes false in a boolean way as soon
# as this method returns. # as this method returns.
notifier = self._notifier notifier = self._notifier
if notifier is None:
# XXX: How did we get here?
self._check_and_notify()
return
# Early links are allowed to remove later links, and links # Early links are allowed to remove later links, and links
# are allowed to add more links, thus we must not # are allowed to add more links, thus we must not
# make a copy of our the ``_links`` list, we must traverse it and # make a copy of our the ``_links`` list, we must traverse it and
......
...@@ -460,7 +460,8 @@ class socket(_socketcommon.SocketMixin): ...@@ -460,7 +460,8 @@ class socket(_socketcommon.SocketMixin):
SocketType = socket SocketType = socket
if hasattr(_socket, 'socketpair'): if hasattr(_socket, 'socketpair'):
# The native, low-level socketpair returns
# low-level objects
def socketpair(family=getattr(_socket, 'AF_UNIX', _socket.AF_INET), def socketpair(family=getattr(_socket, 'AF_UNIX', _socket.AF_INET),
type=_socket.SOCK_STREAM, proto=0): type=_socket.SOCK_STREAM, proto=0):
one, two = _socket.socketpair(family, type, proto) one, two = _socket.socketpair(family, type, proto)
...@@ -469,6 +470,20 @@ if hasattr(_socket, 'socketpair'): ...@@ -469,6 +470,20 @@ if hasattr(_socket, 'socketpair'):
one._drop() one._drop()
two._drop() two._drop()
return result return result
elif hasattr(__socket__, 'socketpair'):
# The high-level backport uses high-level socket APIs. It works
# cooperatively automatically if we're monkey-patched,
# else we must do it ourself.
_orig_socketpair = __socket__.socketpair
def socketpair(*args, **kwargs):
one, two = _orig_socketpair(*args, **kwargs)
if not isinstance(one, socket):
one = socket(_sock=one)
two = socket(_sock=two)
if PYPY:
one._drop()
two._drop()
return one, two
elif 'socketpair' in __implements__: elif 'socketpair' in __implements__:
__implements__.remove('socketpair') __implements__.remove('socketpair')
......
...@@ -128,6 +128,11 @@ if is_macos: ...@@ -128,6 +128,11 @@ if is_macos:
import _socket import _socket
_realsocket = _socket.socket _realsocket = _socket.socket
import socket as __socket__ import socket as __socket__
try:
# Provide implementation of socket.socketpair on Windows < 3.5.
import backports.socketpair
except ImportError:
pass
_name = _value = None _name = _value = None
__imports__ = copy_globals(__socket__, globals(), __imports__ = copy_globals(__socket__, globals(),
......
...@@ -259,14 +259,6 @@ class Definitions(DefinitionsBase): ...@@ -259,14 +259,6 @@ class Definitions(DefinitionsBase):
when=APPVEYOR & PY3 when=APPVEYOR & PY3
) )
test__socketpair = Ignored(
"""
Py35 added socket.socketpair, all other releases
are missing it. No reason to even test it.
""",
when=WIN & PY2
)
test_ftplib = Flaky( test_ftplib = Flaky(
r""" r"""
could be a problem of appveyor - not sure could be a problem of appveyor - not sure
......
...@@ -15,6 +15,8 @@ class TestSocketpair(unittest.TestCase): ...@@ -15,6 +15,8 @@ class TestSocketpair(unittest.TestCase):
self.assertEqual(msg, read) self.assertEqual(msg, read)
y.close() y.close()
@unittest.skipUnless(hasattr(socket, 'fromfd'),
'Needs socket.fromfd')
def test_fromfd(self): def test_fromfd(self):
msg = b'hello world' msg = b'hello world'
x, y = socket.socketpair() x, y = socket.socketpair()
......
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