Remove select.poll and improve subprocess
green select: Delete unpatched poll once again https://github.com/eventlet/eventlet/pull/317 Previously attempted inf63165c
, had to be reverted in8ea9df6
because subprocess was failing after monkey patching. Turns out we haven't been monkey patching the subprocess module at all, this patch adds that in order for the tests to pass. This part is changed because otherwise Popen class instantiation would cause an infinite loop when monkey patching is applied: -subprocess_orig = __import__("subprocess") +subprocess_orig = patcher.original("subprocess") This patch is contributed by Smarkets Limited. * green subprocess: Provide green check_output This patch is contributed by Smarkets Limited.
This commit is contained in:

committed by
Sergey Shepelev

parent
d3db9f5064
commit
614a20462a
@@ -6,9 +6,7 @@ from eventlet.support import six
|
||||
|
||||
|
||||
__patched__ = ['select']
|
||||
# FIXME: must also delete `poll`, but it breaks subprocess `communicate()`
|
||||
# https://github.com/eventlet/eventlet/issues/290
|
||||
__deleted__ = ['devpoll', 'epoll', 'kqueue', 'kevent']
|
||||
__deleted__ = ['devpoll', 'poll', 'epoll', 'kqueue', 'kevent']
|
||||
|
||||
|
||||
def get_fileno(obj):
|
||||
|
@@ -9,6 +9,7 @@ from eventlet.green import select, threading, time
|
||||
from eventlet.support import six
|
||||
|
||||
|
||||
__patched__ = ['call', 'check_call', 'Popen']
|
||||
to_patch = [('select', select), ('threading', threading), ('time', time)]
|
||||
|
||||
if sys.version_info > (3, 4):
|
||||
@@ -16,7 +17,7 @@ if sys.version_info > (3, 4):
|
||||
to_patch.append(('selectors', selectors))
|
||||
|
||||
patcher.inject('subprocess', globals(), *to_patch)
|
||||
subprocess_orig = __import__("subprocess")
|
||||
subprocess_orig = patcher.original("subprocess")
|
||||
mswindows = sys.platform == "win32"
|
||||
|
||||
|
||||
@@ -114,7 +115,17 @@ class Popen(subprocess_orig.Popen):
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
# Borrow subprocess.call() and check_call(), but patch them so they reference
|
||||
# OUR Popen class rather than subprocess.Popen.
|
||||
call = FunctionType(six.get_function_code(subprocess_orig.call), globals())
|
||||
check_call = FunctionType(six.get_function_code(subprocess_orig.check_call), globals())
|
||||
def patched_function(function):
|
||||
return FunctionType(six.get_function_code(function), globals())
|
||||
|
||||
|
||||
call = patched_function(subprocess_orig.call)
|
||||
check_call = patched_function(subprocess_orig.check_call)
|
||||
# check_output is Python 2.7+
|
||||
if hasattr(subprocess_orig, 'check_output'):
|
||||
__patched__.append('check_output')
|
||||
check_output = patched_function(subprocess_orig.check_output)
|
||||
del patched_function
|
||||
|
@@ -224,7 +224,7 @@ def monkey_patch(**on):
|
||||
"""
|
||||
accepted_args = set(('os', 'select', 'socket',
|
||||
'thread', 'time', 'psycopg', 'MySQLdb',
|
||||
'builtins'))
|
||||
'builtins', 'subprocess'))
|
||||
# To make sure only one of them is passed here
|
||||
assert not ('__builtin__' in on and 'builtins' in on)
|
||||
try:
|
||||
@@ -262,6 +262,7 @@ def monkey_patch(**on):
|
||||
('time', _green_time_modules),
|
||||
('MySQLdb', _green_MySQLdb),
|
||||
('builtins', _green_builtins),
|
||||
('subprocess', _green_subprocess_modules),
|
||||
]:
|
||||
if on[name] and not already_patched.get(name):
|
||||
modules_to_patch += modules_function()
|
||||
@@ -401,6 +402,11 @@ def _green_socket_modules():
|
||||
return [('socket', socket)]
|
||||
|
||||
|
||||
def _green_subprocess_modules():
|
||||
from eventlet.green import subprocess
|
||||
return [('subprocess', subprocess)]
|
||||
|
||||
|
||||
def _green_thread_modules():
|
||||
from eventlet.green import Queue
|
||||
from eventlet.green import thread
|
||||
|
@@ -6,6 +6,14 @@ if __name__ == '__main__':
|
||||
from eventlet.green import MySQLdb as gm
|
||||
patcher.monkey_patch(all=True, MySQLdb=True)
|
||||
patched_set = set(patcher.already_patched) - set(['psycopg'])
|
||||
assert patched_set == frozenset(['MySQLdb', 'os', 'select', 'socket', 'thread', 'time'])
|
||||
assert patched_set == frozenset([
|
||||
'MySQLdb',
|
||||
'os',
|
||||
'select',
|
||||
'socket',
|
||||
'subprocess',
|
||||
'thread',
|
||||
'time',
|
||||
])
|
||||
assert m.connect == gm.connect
|
||||
print('pass')
|
||||
|
@@ -11,9 +11,7 @@ if __name__ == '__main__':
|
||||
# * https://bitbucket.org/eventlet/eventlet/issues/167
|
||||
# * https://github.com/eventlet/eventlet/issues/169
|
||||
import select
|
||||
# FIXME: must also delete `poll`, but it breaks subprocess `communicate()`
|
||||
# https://github.com/eventlet/eventlet/issues/290
|
||||
for name in ['devpoll', 'epoll', 'kqueue', 'kevent']:
|
||||
for name in ['devpoll', 'poll', 'epoll', 'kqueue', 'kevent']:
|
||||
assert not hasattr(select, name), name
|
||||
|
||||
import sys
|
||||
|
@@ -185,15 +185,15 @@ print("already_patched {0}".format(",".join(sorted(patcher.already_patched.keys(
|
||||
|
||||
def test_boolean(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch()",
|
||||
'os,select,socket,thread,time')
|
||||
'os,select,socket,subprocess,thread,time')
|
||||
|
||||
def test_boolean_all(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch(all=True)",
|
||||
'os,select,socket,thread,time')
|
||||
'os,select,socket,subprocess,thread,time')
|
||||
|
||||
def test_boolean_all_single(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch(all=True, socket=True)",
|
||||
'os,select,socket,thread,time')
|
||||
'os,select,socket,subprocess,thread,time')
|
||||
|
||||
def test_boolean_all_negative(self):
|
||||
self.assert_boolean_logic(
|
||||
@@ -210,11 +210,11 @@ print("already_patched {0}".format(",".join(sorted(patcher.already_patched.keys(
|
||||
|
||||
def test_boolean_negative(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch(socket=False)",
|
||||
'os,select,thread,time')
|
||||
'os,select,subprocess,thread,time')
|
||||
|
||||
def test_boolean_negative2(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch(socket=False, time=False)",
|
||||
'os,select,thread')
|
||||
'os,select,subprocess,thread')
|
||||
|
||||
def test_conflicting_specifications(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch(socket=False, select=True)",
|
||||
|
Reference in New Issue
Block a user