|
1 | 1 | """Per-test stdout/stderr capturing mechanism."""
|
2 |
| -import collections |
3 | 2 | import contextlib
|
| 3 | +import functools |
4 | 4 | import io
|
5 | 5 | import os
|
6 | 6 | import sys
|
@@ -488,7 +488,59 @@ def writeorg(self, data):
|
488 | 488 |
|
489 | 489 | # MultiCapture
|
490 | 490 |
|
491 |
| -CaptureResult = collections.namedtuple("CaptureResult", ["out", "err"]) |
| 491 | + |
| 492 | +# This class was a namedtuple, but due to mypy limitation[0] it could not be |
| 493 | +# made generic, so was replaced by a regular class which tries to emulate the |
| 494 | +# pertinent parts of a namedtuple. If the mypy limitation is ever lifted, can |
| 495 | +# make it a namedtuple again. |
| 496 | +# [0]: https://github.com/python/mypy/issues/685 |
| 497 | +@functools.total_ordering |
| 498 | +class CaptureResult: |
| 499 | + """The result of :method:`CaptureFixture.readouterr`.""" |
| 500 | + |
| 501 | + # Can't use slots in Python<3.5.3 due to https://bugs.python.org/issue31272 |
| 502 | + if sys.version_info >= (3, 5, 3): |
| 503 | + __slots__ = ("out", "err") |
| 504 | + |
| 505 | + def __init__(self, out, err) -> None: |
| 506 | + self.out = out |
| 507 | + self.err = err |
| 508 | + |
| 509 | + def __len__(self) -> int: |
| 510 | + return 2 |
| 511 | + |
| 512 | + def __iter__(self): |
| 513 | + return iter((self.out, self.err)) |
| 514 | + |
| 515 | + def __getitem__(self, item: int): |
| 516 | + return tuple(self)[item] |
| 517 | + |
| 518 | + def _replace(self, out=None, err=None) -> "CaptureResult": |
| 519 | + return CaptureResult( |
| 520 | + out=self.out if out is None else out, err=self.err if err is None else err |
| 521 | + ) |
| 522 | + |
| 523 | + def count(self, value) -> int: |
| 524 | + return tuple(self).count(value) |
| 525 | + |
| 526 | + def index(self, value) -> int: |
| 527 | + return tuple(self).index(value) |
| 528 | + |
| 529 | + def __eq__(self, other: object) -> bool: |
| 530 | + if not isinstance(other, (CaptureResult, tuple)): |
| 531 | + return NotImplemented |
| 532 | + return tuple(self) == tuple(other) |
| 533 | + |
| 534 | + def __hash__(self) -> int: |
| 535 | + return hash(tuple(self)) |
| 536 | + |
| 537 | + def __lt__(self, other: object) -> bool: |
| 538 | + if not isinstance(other, (CaptureResult, tuple)): |
| 539 | + return NotImplemented |
| 540 | + return tuple(self) < tuple(other) |
| 541 | + |
| 542 | + def __repr__(self) -> str: |
| 543 | + return "CaptureResult(out={!r}, err={!r})".format(self.out, self.err) |
492 | 544 |
|
493 | 545 |
|
494 | 546 | class MultiCapture:
|
|
0 commit comments