diff options
author | Todd Leonhardt <todd.leonhardt@gmail.com> | 2018-09-23 18:51:30 -0400 |
---|---|---|
committer | Todd Leonhardt <todd.leonhardt@gmail.com> | 2018-09-23 18:51:30 -0400 |
commit | 35550e048bde73b08fad28c2a8d844dcbdea7f35 (patch) | |
tree | ac4781f9ac5e4abf97710b8dcd2d67187ffe1bc2 /cmd2/utils.py | |
parent | dbe485957b421f6fd973b3a493de7b264b363d54 (diff) | |
download | cmd2-git-35550e048bde73b08fad28c2a8d844dcbdea7f35.tar.gz |
Fixed several hack classes build to simulate file descriptors
Now there is a single class, StdSim in utils.py, which is intended to simulate stdout and stderr file objects.
This class replaced the following:
- pyscript_bridge.py::CopyStream
- transcript.py::OutputTrap
- conftest.py::StdOut
Diffstat (limited to 'cmd2/utils.py')
-rw-r--r-- | cmd2/utils.py | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/cmd2/utils.py b/cmd2/utils.py index 735221c8..83185603 100644 --- a/cmd2/utils.py +++ b/cmd2/utils.py @@ -246,3 +246,57 @@ def natural_sort(list_to_sort: List[str]) -> List[str]: :return: the list sorted naturally """ return sorted(list_to_sort, key=natural_keys) + + +class StdSim(object): + """Class to simulate behavior of sys.stdout or sys.stderr. + + Stores contents in internal buffer and optionally echos to the inner stream it is simulating. + """ + class ByteBuf(object): + """Inner class which stores an actual bytes buffer and does the actual output if echo is enabled.""" + def __init__(self, inner_stream, echo: bool = False) -> None: + self.byte_buf = b'' + self.inner_stream = inner_stream + self.echo = echo + + def write(self, b: bytes) -> None: + """Add bytes to internal bytes buffer and if echo is True, echo contents to inner stream.""" + self.byte_buf += b + if self.echo: + self.inner_stream.buffer.write(b) + + def __init__(self, inner_stream, echo: bool = False) -> None: + self.buffer = self.ByteBuf(inner_stream, echo) + self.inner_stream = inner_stream + + def write(self, s: str) -> None: + """Add str to internal bytes buffer and if echo is True, echo contents to inner stream.""" + b = s.encode() + self.buffer.write(b) + + def getvalue(self) -> str: + """Get the internal contents as a str. + + :return string from the internal contents + """ + return self.buffer.byte_buf.decode() + + def read(self) -> str: + """Read from the internal contents as a str and then clear them out. + + :return: string from the internal contents + """ + result = self.getvalue() + self.clear() + return result + + def clear(self) -> None: + """Clear the internal contents.""" + self.buffer.byte_buf = b'' + + def __getattr__(self, item: str): + if item in self.__dict__: + return self.__dict__[item] + else: + return getattr(self.inner_stream, item) |