|
3 | 3 | import argparse |
4 | 4 | import re |
5 | 5 | import sys |
6 | | -from collections.abc import Iterator |
| 6 | +from collections.abc import ( |
| 7 | + Iterable, |
| 8 | + Iterator, |
| 9 | +) |
7 | 10 | from enum import Enum |
8 | 11 | from typing import ( |
9 | 12 | IO, |
|
14 | 17 | runtime_checkable, |
15 | 18 | ) |
16 | 19 |
|
| 20 | +from rich.ansi import AnsiDecoder |
17 | 21 | from rich.box import SIMPLE_HEAD |
18 | 22 | from rich.console import ( |
19 | 23 | Console, |
@@ -672,3 +676,38 @@ def prepare_objects_for_rendering(*objects: Any) -> tuple[Any, ...]: |
672 | 676 | object_list[i] = Text.from_ansi(renderable_as_str) |
673 | 677 |
|
674 | 678 | return tuple(object_list) |
| 679 | + |
| 680 | + |
| 681 | +################################################################################### |
| 682 | +# Rich Library Monkey Patches |
| 683 | +# |
| 684 | +# These patches fix specific bugs in the Rich library. They are conditional and |
| 685 | +# will only be applied if the bug is detected. When the bugs are fixed in a |
| 686 | +# future Rich release, these patches and their corresponding tests should be |
| 687 | +# removed. |
| 688 | +################################################################################### |
| 689 | + |
| 690 | +################################################################################### |
| 691 | +# AnsiDecoder.decode() monkey patch |
| 692 | +################################################################################### |
| 693 | + |
| 694 | + |
| 695 | +def _AnsiDecoder_decode(self: AnsiDecoder, terminal_text: str) -> Iterable[Text]: # noqa: N802 |
| 696 | + """Patch AnsiDecoder.decode() to properly handle CRLF. |
| 697 | +
|
| 698 | + There is currently a pull request on Rich to fix this. |
| 699 | + https://github.com/Textualize/rich/pull/4143 |
| 700 | + """ |
| 701 | + for line in re.split(r"(?<=\n)", terminal_text): |
| 702 | + # Strip off any remaining line break characters from the end |
| 703 | + yield self.decode_line(line.rstrip("\r\n")) |
| 704 | + |
| 705 | + |
| 706 | +def _decode_has_linebreak_bug() -> bool: |
| 707 | + """Check if AnsiDecoder.decode() properly handles CRLF.""" |
| 708 | + return Text.from_ansi("hello\r\nworld").plain == "\nworld" |
| 709 | + |
| 710 | + |
| 711 | +# Only apply the monkey patch if the bug is present |
| 712 | +if _decode_has_linebreak_bug(): |
| 713 | + AnsiDecoder.decode = _AnsiDecoder_decode # type: ignore[assignment] |
0 commit comments