Commit faeecb66 authored by Jason Madden's avatar Jason Madden

Popen does work on win32 threads.

parent 4ee32532
""" """
Cooperative ``subprocess`` module. Cooperative ``subprocess`` module.
.. caution:: This module is not usable from native threads other than .. caution:: On POSIX platforms, this module is not usable from native
the main thread; attempting to do so will raise a :exc:`TypeError`. threads other than the main thread; attempting to do so will raise
This module depends on libev's fork watchers. On POSIX systems, a :exc:`TypeError`. This module depends on libev's fork watchers.
fork watchers are implemented using signals, and the thread to On POSIX systems, fork watchers are implemented using signals, and
which process-directed signals are delivered `is not defined`_. the thread to which process-directed signals are delivered `is not
Because each native thread has its own gevent/libev loop, this defined`_. Because each native thread has its own gevent/libev
means that a fork watcher registered with one loop (thread) may loop, this means that a fork watcher registered with one loop
never see the signal about a child it spawned if the signal is sent (thread) may never see the signal about a child it spawned if the
to a different thread. signal is sent to a different thread.
.. note:: The interface of this module is intended to match that of .. note:: The interface of this module is intended to match that of
the standard library :mod:`subprocess` module. There are some small the standard library :mod:`subprocess` module. There are some small
......
...@@ -199,30 +199,33 @@ class Test(greentest.TestCase): ...@@ -199,30 +199,33 @@ class Test(greentest.TestCase):
r = p.stdout.readline() r = p.stdout.readline()
self.assertEqual(r, b'foobar\n') self.assertEqual(r, b'foobar\n')
def test_subprocess_in_native_thread(self): if sys.platform != 'win32':
# gevent.subprocess doesn't work from a background
# native thread. See #688
from gevent import monkey
# must be a native thread; defend against monkey-patching def test_subprocess_in_native_thread(self):
ex = [] # gevent.subprocess doesn't work from a background
Thread = monkey.get_original('threading', 'Thread') # native thread. See #688
from gevent import monkey
def fn(): # must be a native thread; defend against monkey-patching
try: ex = []
gevent.subprocess.Popen('echo 123', shell=True) Thread = monkey.get_original('threading', 'Thread')
raise AssertionError("Should not be able to construct Popen")
except Exception as e: def fn():
ex.append(e) try:
gevent.subprocess.Popen('echo 123', shell=True)
raise AssertionError("Should not be able to construct Popen")
except Exception as e:
ex.append(e)
thread = Thread(target=fn) thread = Thread(target=fn)
thread.start() thread.start()
thread.join() thread.join()
self.assertEqual(len(ex), 1) self.assertEqual(len(ex), 1)
self.assertTrue(isinstance(ex[0], TypeError), ex) self.assertTrue(isinstance(ex[0], TypeError), ex)
self.assertEqual(ex[0].args[0], 'child watchers are only available on the default loop') self.assertEqual(ex[0].args[0], 'child watchers are only available on the default loop')
test_subprocess_in_native_thread.ignore_leakcheck = True
if __name__ == '__main__': if __name__ == '__main__':
greentest.main() greentest.main()
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