File: pipedprocess.py

package info (click to toggle)
ipython 0.13.1-2%2Bdeb7u1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 15,752 kB
  • sloc: python: 69,537; makefile: 355; lisp: 272; sh: 80; objc: 37
file content (74 lines) | stat: -rw-r--r-- 2,527 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# encoding: utf-8
"""
Object for encapsulating process execution by using callbacks for stdout,
stderr and stdin.
"""
__docformat__ = "restructuredtext en"

#-------------------------------------------------------------------------------
#  Copyright (C) 2008-2011  The IPython Development Team
#
#  Distributed under the terms of the BSD License.  The full license is in
#  the file COPYING, distributed as part of this software.
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
# Imports
#-------------------------------------------------------------------------------
from killableprocess import Popen, PIPE
from threading import Thread
from time import sleep
import os

class PipedProcess(Thread):
    """ Class that encapsulates process execution by using callbacks for
        stdout, stderr and stdin, and providing a reliable way of
        killing it.
    """

    def __init__(self, command_string, out_callback,
                        end_callback=None,):
        """ command_string: the command line executed to start the
        process.

        out_callback: the python callable called on stdout/stderr.

        end_callback: an optional callable called when the process
        finishes.

        These callbacks are called from a different thread as the
        thread from which is started.
        """
        self.command_string = command_string
        self.out_callback = out_callback
        self.end_callback = end_callback
        Thread.__init__(self)


    def run(self):
        """ Start the process and hook up the callbacks.
        """
        env = os.environ
        env['TERM'] = 'xterm'
        process = Popen(self.command_string + ' 2>&1', shell=True,
                                env=env,
                                universal_newlines=True,
                                stdout=PIPE, stdin=PIPE, )
        self.process = process
        while True:
            out_char = process.stdout.read(1)
            if out_char == '':
                if process.poll() is not None:
                    # The process has finished
                    break
                else:
                    # The process is not giving any interesting
                    # output. No use polling it immediatly.
                    sleep(0.1)
            else:
                self.out_callback(out_char)

        if self.end_callback is not None:
            self.end_callback()