Commit faeecb66 authored by Jason Madden's avatar Jason Madden

Popen does work on win32 threads.

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