root/galaxy-central/eggs/Paste-1.6-py2.6.egg/paste/util/threadedprint.py @ 3

リビジョン 3, 7.4 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
2# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
3
4"""
5threadedprint.py
6================
7
8:author: Ian Bicking
9:date: 12 Jul 2004
10
11Multi-threaded printing; allows the output produced via print to be
12separated according to the thread.
13
14To use this, you must install the catcher, like::
15
16    threadedprint.install()
17
18The installation optionally takes one of three parameters:
19
20default
21    The default destination for print statements (e.g., ``sys.stdout``).
22factory
23    A function that will produce the stream for a thread, given the
24    thread's name.
25paramwriter
26    Instead of writing to a file-like stream, this function will be
27    called like ``paramwriter(thread_name, text)`` for every write.
28
29The thread name is the value returned by
30``threading.currentThread().getName()``, a string (typically something
31like Thread-N).
32
33You can also submit file-like objects for specific threads, which will
34override any of these parameters.  To do this, call ``register(stream,
35[threadName])``.  ``threadName`` is optional, and if not provided the
36stream will be registered for the current thread.
37
38If no specific stream is registered for a thread, and no default has
39been provided, then an error will occur when anything is written to
40``sys.stdout`` (or printed).
41
42Note: the stream's ``write`` method will be called in the thread the
43text came from, so you should consider thread safety, especially if
44multiple threads share the same writer.
45
46Note: if you want access to the original standard out, use
47``sys.__stdout__``.
48
49You may also uninstall this, via::
50
51    threadedprint.uninstall()
52
53TODO
54----
55
56* Something with ``sys.stderr``.
57* Some default handlers.  Maybe something that hooks into `logging`.
58* Possibly cache the results of ``factory`` calls.  This would be a
59  semantic change.
60
61"""
62
63import threading
64import sys
65from paste.util import filemixin
66
67class PrintCatcher(filemixin.FileMixin):
68
69    def __init__(self, default=None, factory=None, paramwriter=None,
70                 leave_stdout=False):
71        assert len(filter(lambda x: x is not None,
72                          [default, factory, paramwriter])) <= 1, (
73            "You can only provide one of default, factory, or paramwriter")
74        if leave_stdout:
75            assert not default, (
76                "You cannot pass in both default (%r) and "
77                "leave_stdout=True" % default)
78            default = sys.stdout
79        if default:
80            self._defaultfunc = self._writedefault
81        elif factory:
82            self._defaultfunc = self._writefactory
83        elif paramwriter:
84            self._defaultfunc = self._writeparam
85        else:
86            self._defaultfunc = self._writeerror
87        self._default = default
88        self._factory = factory
89        self._paramwriter = paramwriter
90        self._catchers = {}
91
92    def write(self, v, currentThread=threading.currentThread):
93        name = currentThread().getName()
94        catchers = self._catchers
95        if not catchers.has_key(name):
96            self._defaultfunc(name, v)
97        else:
98            catcher = catchers[name]
99            catcher.write(v)
100
101    def _writedefault(self, name, v):
102        self._default.write(v)
103
104    def _writefactory(self, name, v):
105        self._factory(name).write(v)
106
107    def _writeparam(self, name, v):
108        self._paramwriter(name, v)
109
110    def _writeerror(self, name, v):
111        assert False, (
112            "There is no PrintCatcher output stream for the thread %r"
113            % name)
114
115    def register(self, catcher, name=None,
116                 currentThread=threading.currentThread):
117        if name is None:
118            name = currentThread().getName()
119        self._catchers[name] = catcher
120
121    def deregister(self, name=None,
122                   currentThread=threading.currentThread):
123        if name is None:
124            name = currentThread().getName()
125        assert self._catchers.has_key(name), (
126            "There is no PrintCatcher catcher for the thread %r" % name)
127        del self._catchers[name]
128
129_printcatcher = None
130_oldstdout = None
131
132def install(**kw):
133    global _printcatcher, _oldstdout, register, deregister
134    if not _printcatcher:
135        _oldstdout = sys.stdout
136        _printcatcher = sys.stdout = PrintCatcher(**kw)
137        register = _printcatcher.register
138        deregister = _printcatcher.deregister
139
140def uninstall():
141    global _printcatcher, _oldstdout, register, deregister
142    if _printcatcher:
143        sys.stdout = _oldstdout
144        _printcatcher = _oldstdout = None
145        register = not_installed_error
146        deregister = not_installed_error
147
148def not_installed_error(*args, **kw):
149    assert False, (
150        "threadedprint has not yet been installed (call "
151        "threadedprint.install())")
152
153register = deregister = not_installed_error
154
155class StdinCatcher(filemixin.FileMixin):
156
157    def __init__(self, default=None, factory=None, paramwriter=None):
158        assert len(filter(lambda x: x is not None,
159                          [default, factory, paramwriter])) <= 1, (
160            "You can only provide one of default, factory, or paramwriter")
161        if default:
162            self._defaultfunc = self._readdefault
163        elif factory:
164            self._defaultfunc = self._readfactory
165        elif paramwriter:
166            self._defaultfunc = self._readparam
167        else:
168            self._defaultfunc = self._readerror
169        self._default = default
170        self._factory = factory
171        self._paramwriter = paramwriter
172        self._catchers = {}
173
174    def read(self, size=None, currentThread=threading.currentThread):
175        name = currentThread().getName()
176        catchers = self._catchers
177        if not catchers.has_key(name):
178            self._defaultfunc(name, size)
179        else:
180            catcher = catchers[name]
181            catcher.read(size)
182
183    def _readdefault(self, name, size):
184        self._default.read(size)
185
186    def _readfactory(self, name, size):
187        self._factory(name).read(size)
188
189    def _readparam(self, name, size):
190        self._paramreader(name, size)
191
192    def _readerror(self, name, size):
193        assert False, (
194            "There is no StdinCatcher output stream for the thread %r"
195            % name)
196
197    def register(self, catcher, name=None,
198                 currentThread=threading.currentThread):
199        if name is None:
200            name = currentThread.getName()
201        self._catchers[name] = catcher
202
203    def deregister(self, catcher, name=None,
204                   currentThread=threading.currentThread):
205        if name is None:
206            name = currentThread().getName()
207        assert self._catchers.has_key(name), (
208            "There is no StdinCatcher catcher for the thread %r" % name)
209        del self._catchers[name]
210
211_stdincatcher = None
212_oldstdin = None
213
214def install_stdin(**kw):
215    global _stdincatcher, _oldstdin, register_stdin, deregister_stdin
216    if not _stdincatcher:
217        _oldstdin = sys.stdin
218        _stdincatcher = sys.stdin = StdinCatcher(**kw)
219        register_stdin = _stdincatcher.register
220        deregister_stdin = _stdincatcher.deregister
221
222def uninstall():
223    global _stdincatcher, _oldstin, register_stdin, deregister_stdin
224    if _stdincatcher:
225        sys.stdin = _oldstdin
226        _stdincatcher = _oldstdin = None
227        register_stdin = deregister_stdin = not_installed_error_stdin
228
229def not_installed_error_stdin(*args, **kw):
230    assert False, (
231        "threadedprint has not yet been installed for stdin (call "
232        "threadedprint.install_stdin())")
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。