Skip to content
Browse files

Remove select.poll and improve subprocess

green select: Delete unpatched poll once again


Previously attempted in f63165c, had to be reverted in 8ea9df6 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.
  • Loading branch information
jstasiak authored and temoto committed May 20, 2016
1 parent d3db9f5 commit 614a20462aebfe85a54ce35a7daaf1a7dbde44a7
@@ -6,9 +6,7 @@

__patched__ = ['select']
# FIXME: must also delete `poll`, but it breaks subprocess `communicate()`
__deleted__ = ['devpoll', 'epoll', 'kqueue', 'kevent']
__deleted__ = ['devpoll', 'poll', 'epoll', 'kqueue', 'kevent']

def get_fileno(obj):
@@ -9,14 +9,15 @@
from import six

__patched__ = ['call', 'check_call', 'Popen']
to_patch = [('select', select), ('threading', threading), ('time', time)]

if sys.version_info > (3, 4):
from import selectors
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 @@ def wait(self, timeout=None, check_interval=0.01):
except AttributeError:

# Borrow and check_call(), but patch them so they reference
# OUR Popen class rather than subprocess.Popen.
call = FunctionType(six.get_function_code(, 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(
check_call = patched_function(subprocess_orig.check_call)
# check_output is Python 2.7+
if hasattr(subprocess_orig, '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', 'subprocess'))
# To make sure only one of them is passed here
assert not ('__builtin__' in on and 'builtins' in on)
@@ -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 import subprocess
return [('subprocess', subprocess)]

def _green_thread_modules():
from import Queue
from import thread
@@ -6,6 +6,14 @@
from 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([
assert m.connect == gm.connect
@@ -11,9 +11,7 @@
# *
# *
import select
# FIXME: must also delete `poll`, but it breaks subprocess `communicate()`
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 @@ def assert_boolean_logic(self, call, expected, not_expected=''):

def test_boolean(self):

def test_boolean_all(self):

def test_boolean_all_single(self):
self.assert_boolean_logic("patcher.monkey_patch(all=True, socket=True)",

def test_boolean_all_negative(self):
@@ -210,11 +210,11 @@ def test_boolean_double(self):

def test_boolean_negative(self):

def test_boolean_negative2(self):
self.assert_boolean_logic("patcher.monkey_patch(socket=False, time=False)",

def test_conflicting_specifications(self):
self.assert_boolean_logic("patcher.monkey_patch(socket=False, select=True)",

0 comments on commit 614a204

Please sign in to comment.