pvl.syslog.tail: split into pvl.syslog.file/tail, clarify line/None/EOFError behaviour
"""
Iterate over lines in file-like objects (without buffering lines!), write (flushing output).
"""
import logging; log = logging.getLogger('pvl.syslog.file')
class File (object) :
"""
Follow a file-like object, reading lines until no more are available. Never raises EOFError.
Works with python file objects that buffer readlines() when using e.g. `tail -f ... | python -u ...`.
readline() may block once there is no more input available, or may return None for evermore.
There is no fileno(), this is not pollable. At all. Don't even iterate on this with a timeout.
XXX: should this really return None? Might really be better to raise EOFError.. except that readlines() should return normally at EOF...
"""
@classmethod
def open (cls, path, mode='r', **opts) :
return cls(open(path, mode), **opts)
EOL = '\n'
def __init__ (self, file) :
log.debug("%s", file)
self.file = file
def readline (self) :
"""
Reads a line from the file, without trailing \n.
Returns None on EOF.
"""
line = self.file.readline()
if not line :
line = None
else :
line = line.rstrip('\r\n')
log.debug("%s", line)
return line
def readlines (self) :
"""
Reads any available lines from the file.
"""
while True :
line = self.readline()
if line is None :
return
else :
yield line
__iter__ = readlines
def writeline (self, line, eol=EOL) :
"""
Write out line, flushing.
"""
self.file.write(line)
self.file.write(eol)
self.file.flush()
__call__ = writeline