This class is used to write output to stderr and overwrite the previous text as soon as new content needs to be written.
| 192 | |
| 193 | |
| 194 | class OverwritingStdErrOutputStream(object): |
| 195 | """This class is used to write output to stderr and overwrite the previous text as |
| 196 | soon as new content needs to be written.""" |
| 197 | |
| 198 | # ANSI Escape code for up. |
| 199 | UP = "\x1b[A" |
| 200 | |
| 201 | def __init__(self): |
| 202 | self.last_line_count = 0 |
| 203 | self.last_clean_text = "" |
| 204 | |
| 205 | def _clean_before(self): |
| 206 | sys.stderr.write(self.UP * self.last_line_count) |
| 207 | sys.stderr.write(self.last_clean_text) |
| 208 | |
| 209 | def write(self, data): |
| 210 | """This method will erase the previously printed text on screen by going |
| 211 | up as many new lines as the old text had and overwriting it with whitespace. |
| 212 | Afterwards, the new text will be printed.""" |
| 213 | self._clean_before() |
| 214 | new_line_count = data.count("\n") |
| 215 | sys.stderr.write(self.UP * min(new_line_count, self.last_line_count)) |
| 216 | sys.stderr.write(data) |
| 217 | |
| 218 | # Cache the line count and the old text where all text was replaced by |
| 219 | # whitespace. |
| 220 | self.last_line_count = new_line_count |
| 221 | self.last_clean_text = re.sub(r"[^\s]", " ", data) |
| 222 | |
| 223 | def clear(self): |
| 224 | sys.stderr.write(self.UP * self.last_line_count) |
| 225 | sys.stderr.write(self.last_clean_text) |
| 226 | sys.stderr.write(self.UP * self.last_line_count) |
| 227 | sys.stderr.flush() |
| 228 | self.last_line_count = 0 |
| 229 | self.last_clean_text = "" |