Kostya Krivomaz Kostya Krivomaz - 20 days ago 6
Python Question

Python tail-like file read

In test I redirected

stderr
into file and trying to read it in tail-like way.
So here is redirection:

class RedirectedEnv(object):
def __init__(self, stderr=None):
self._stderr = stderr or sys.stderr

def __enter__(self):
self.old_stderr = sys.stderr
self.old_stderr.flush()
self.old_exit = getattr(sys, 'exit')
sys.stderr = self._stderr

def mock_exit():
raise Exception
sys.exit = mock_exit

def __exit__(self, exc_type, exc_val, exc_tb):
self._stderr.flush()
sys.stderr = self.old_stderr
sys.exit = self.old_exit

self._stderr.close()


and usage of it:

def test_invalid_args(self):
with RedirectedEnv(stderr=tempfile.NamedTemporaryFile()):
for args in [['-id', '123456789.00'], ['-i'], ['-i', '0'], ['-i', '../some_invalid_path/not_exist.json']]:
try:
self.parser.parse(args)
except Exception:
sys.stderr.flush()
self.assertTrue(sys.stderr.readlines()[0].startswith("usage:")) <<-- here I need help


Is there some elegant way to do this? (Not making mess with
enumerate
and
tell()
with
seek()
) Maybe there some
FIFO queue
with file interface ?

Answer

You can just create a new file for each test and do a seek to the front to get its value. I moved to TemporaryFile since you don't use the file name.

def test_invalid_args(self):
    for args in [['-id', '123456789.00'], ['-i'], ['-i', '0'], ['-i', '../some_invalid_path/not_exist.json']]:
        with RedirectedEnv(stderr=tempfile.TemporaryFile()):
            try:
                self.parser.parse(args)
                raise AssertionError("should have failed")
            except Exception:
                sys.stderr.seek(0)
                self.assertTrue(sys.stderr.readline().startswith("usage:"))
Comments