|
18 | 18 | import array |
19 | 19 | import errno |
20 | 20 | import six |
| 21 | +import sys |
21 | 22 |
|
22 | 23 | __all__ = [ |
23 | 24 | 'Vt100_Output', |
@@ -380,6 +381,9 @@ class Vt100_Output(Output): |
380 | 381 | :param write_binary: Encode the output before writing it. If `True` (the |
381 | 382 | default), the `stdout` object is supposed to expose an `encoding` attribute. |
382 | 383 | """ |
| 384 | + _fds_not_a_terminal = set() # For the error messages. Only display "Output |
| 385 | + # is not a terminal" once per file descriptor. |
| 386 | + |
383 | 387 | def __init__(self, stdout, get_size, term=None, write_binary=True): |
384 | 388 | assert callable(get_size) |
385 | 389 | assert term is None or isinstance(term, six.text_type) |
@@ -409,11 +413,23 @@ def from_pty(cls, stdout, term=None): |
409 | 413 | (This will take the dimensions by reading the pseudo |
410 | 414 | terminal attributes.) |
411 | 415 | """ |
412 | | - assert stdout.isatty() |
| 416 | + # Normally, this requires a real TTY device, but people instantiate |
| 417 | + # this class often during unit tests as well. For convenience, we print |
| 418 | + # an error message, use standard dimensions, and go on. |
| 419 | + isatty = stdout.isatty() |
| 420 | + fd = stdout.fileno() |
| 421 | + |
| 422 | + if not isatty and fd not in cls._fds_not_a_terminal: |
| 423 | + msg = 'Warning: Output is not to a terminal (fd=%r).\n' |
| 424 | + sys.stderr.write(msg % fd) |
| 425 | + cls._fds_not_a_terminal.add(fd) |
413 | 426 |
|
414 | 427 | def get_size(): |
415 | | - rows, columns = _get_size(stdout.fileno()) |
416 | | - return Size(rows=rows, columns=columns) |
| 428 | + if isatty: |
| 429 | + rows, columns = _get_size(stdout.fileno()) |
| 430 | + return Size(rows=rows, columns=columns) |
| 431 | + else: |
| 432 | + return Size(rows=24, columns=80) |
417 | 433 |
|
418 | 434 | return cls(stdout, get_size, term=term) |
419 | 435 |
|
|
0 commit comments