Commits

Jason R. Coombs committed 58f31c7

Adding routine for reading from a subprocess in a nonblocking way

Comments (0)

Files changed (3)

jaraco/util/editor.py

-from __future__ import unicode_literals
+from __future__ import unicode_literals, absolute_import
 
 import tempfile
 import os

jaraco/util/subprocess.py

+from __future__ import absolute_import
+import sys
+import subprocess
+import threading
+import Queue as queue
+
+def enqueue_lines(stream, queue):
+	for line in iter(stream.readline, b''):
+		queue.put(line)
+	stream.close()
+
+# copy attribute for convenience
+PIPE=subprocess.PIPE
+
+def Popen_nonblocking(*args, **kwargs):
+	"""
+	Open a subprocess without blocking. Return a process handle with any
+	output streams replaced by queues of lines from that stream.
+
+	Usage:
+
+	proc = Popen_nonblocking(..., stdout=subprocess.PIPE)
+	try:
+		out_line = proc.stdout.get_nowait()
+	except queue.Empty:
+		"no output available"
+	else:
+		handle_output(out_line)
+	"""
+	kwargs.setdefault('close_fds', 'posix' in sys.builtin_module_names)
+	kwargs.setdefault('bufsize', 1)
+	proc = subprocess.Popen(*args, **kwargs)
+	if proc.stdout:
+		q = queue.Queue()
+		t = threading.Thread(target=enqueue_lines,
+			args=(proc.stdout, q))
+		proc.stdout = q
+		# thread dies with the parent
+		t.daemon = True
+		t.start()
+	if proc.stderr:
+		q = queue.Queue()
+		t = threading.Thread(target=enqueue_lines,
+			args=(proc.stderr, q))
+		proc.stderr = q
+		t.daemon = True
+		t.start()
+	return proc

jaraco/util/wallpaper.py

 Assumes Gnome or Windows.
 """
 
-from __future__ import division, print_function, unicode_literals
+from __future__ import (division, print_function, unicode_literals,
+	absolute_import,
+)
 
 import os
 import re