82 lines
2.3 KiB
Python
82 lines
2.3 KiB
Python
|
|
||
|
import thread
|
||
|
|
||
|
class ThreadOut(object):
|
||
|
""" A file like object that diverts writing operations
|
||
|
to per-thread writefuncs.
|
||
|
This is a py lib internal class and not meant for outer use
|
||
|
or modification.
|
||
|
"""
|
||
|
def __new__(cls, obj, attrname):
|
||
|
""" Divert file output to per-thread writefuncs.
|
||
|
the given obj and attrname describe the destination
|
||
|
of the file.
|
||
|
"""
|
||
|
current = getattr(obj, attrname)
|
||
|
if isinstance(current, cls):
|
||
|
current._used += 1
|
||
|
return current
|
||
|
self = object.__new__(cls)
|
||
|
self._tid2out = {}
|
||
|
self._used = 1
|
||
|
self._oldout = getattr(obj, attrname)
|
||
|
self._defaultwriter = self._oldout.write
|
||
|
self._address = (obj, attrname)
|
||
|
setattr(obj, attrname, self)
|
||
|
return self
|
||
|
|
||
|
def isatty(self):
|
||
|
# XXX
|
||
|
return False
|
||
|
|
||
|
def setdefaultwriter(self, writefunc):
|
||
|
self._defaultwriter = writefunc
|
||
|
|
||
|
def resetdefault(self):
|
||
|
self._defaultwriter = self._oldout.write
|
||
|
|
||
|
def softspace():
|
||
|
def fget(self):
|
||
|
return self._get()[0]
|
||
|
def fset(self, value):
|
||
|
self._get()[0] = value
|
||
|
return property(fget, fset, None, "software attribute")
|
||
|
softspace = softspace()
|
||
|
|
||
|
def deinstall(self):
|
||
|
self._used -= 1
|
||
|
x = self._used
|
||
|
if x <= 0:
|
||
|
obj, attrname = self._address
|
||
|
setattr(obj, attrname, self._oldout)
|
||
|
|
||
|
def setwritefunc(self, writefunc, tid=None):
|
||
|
assert callable(writefunc)
|
||
|
if tid is None:
|
||
|
tid = thread.get_ident()
|
||
|
self._tid2out[tid] = [0, writefunc]
|
||
|
|
||
|
def delwritefunc(self, tid=None, ignoremissing=True):
|
||
|
if tid is None:
|
||
|
tid = thread.get_ident()
|
||
|
try:
|
||
|
del self._tid2out[tid]
|
||
|
except KeyError:
|
||
|
if not ignoremissing:
|
||
|
raise
|
||
|
|
||
|
def _get(self):
|
||
|
tid = thread.get_ident()
|
||
|
try:
|
||
|
return self._tid2out[tid]
|
||
|
except KeyError:
|
||
|
return getattr(self._defaultwriter, 'softspace', 0), self._defaultwriter
|
||
|
|
||
|
def write(self, data):
|
||
|
softspace, out = self._get()
|
||
|
out(data)
|
||
|
|
||
|
def flush(self):
|
||
|
pass
|
||
|
|