Skip to content

Commit 3d1239a

Browse files
authored
Merge branch 'main' into fix-ansi-color-dumb-terminal-v2
2 parents fc65237 + ea66804 commit 3d1239a

File tree

3 files changed

+2
-99
lines changed

3 files changed

+2
-99
lines changed

cmd2/rich_utils.py

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -484,64 +484,3 @@ def prepare_objects_for_rendering(*objects: Any) -> tuple[Any, ...]:
484484
object_list[i] = Text.from_ansi(renderable_as_str)
485485

486486
return tuple(object_list)
487-
488-
489-
###################################################################################
490-
# Rich Library Monkey Patches
491-
#
492-
# These patches fix specific bugs in the Rich library. They are conditional and
493-
# will only be applied if the bug is detected. When the bugs are fixed in a
494-
# future Rich release, these patches and their corresponding tests should be
495-
# removed.
496-
###################################################################################
497-
498-
###################################################################################
499-
# Text.from_ansi() monkey patch
500-
###################################################################################
501-
502-
# Save original Text.from_ansi() so we can call it in our patch
503-
_orig_text_from_ansi = Text.from_ansi
504-
505-
506-
@classmethod # type: ignore[misc]
507-
def _Text_from_ansi(cls: type[Text], text: str, *args: Any, **kwargs: Any) -> Text: # noqa: N802, ARG001
508-
r"""Wrap Text.from_ansi() to fix its trailing newline bug.
509-
510-
This wrapper handles an issue where Text.from_ansi() removes the
511-
trailing line break from a string (e.g. "Hello\n" becomes "Hello").
512-
513-
There is currently a pull request on Rich to fix this.
514-
https://github.com/Textualize/rich/pull/3793
515-
"""
516-
result = _orig_text_from_ansi(text, *args, **kwargs)
517-
518-
# If the original string ends with a recognized line break character,
519-
# then restore the missing newline. We use "\n" because Text.from_ansi()
520-
# converts all line breaks into newlines.
521-
# Source: https://docs.python.org/3/library/stdtypes.html#str.splitlines
522-
line_break_chars = {
523-
"\n", # Line Feed
524-
"\r", # Carriage Return
525-
"\v", # Vertical Tab
526-
"\f", # Form Feed
527-
"\x1c", # File Separator
528-
"\x1d", # Group Separator
529-
"\x1e", # Record Separator
530-
"\x85", # Next Line (NEL)
531-
"\u2028", # Line Separator
532-
"\u2029", # Paragraph Separator
533-
}
534-
if text and text[-1] in line_break_chars:
535-
result.append("\n")
536-
537-
return result
538-
539-
540-
def _from_ansi_has_newline_bug() -> bool:
541-
"""Check if Test.from_ansi() strips the trailing line break from a string."""
542-
return Text.from_ansi("\n") == Text.from_ansi("")
543-
544-
545-
# Only apply the monkey patch if the bug is present
546-
if _from_ansi_has_newline_bug():
547-
Text.from_ansi = _Text_from_ansi # type: ignore[assignment]

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ dependencies = [
3232
"backports.strenum; python_version == '3.10'",
3333
"prompt-toolkit>=3.0.52",
3434
"pyperclip>=1.8.2",
35-
"rich>=14.3.0",
36-
"rich-argparse>=1.7.1",
35+
"rich>=15.0.0",
36+
"rich-argparse>=1.7.2",
3737
"typing-extensions; python_version == '3.10'",
3838
]
3939

tests/test_rich_utils.py

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -115,42 +115,6 @@ def test_set_theme() -> None:
115115
assert ru.APP_THEME.styles[rich_style_key] == theme[rich_style_key]
116116

117117

118-
def test_from_ansi_patch() -> None:
119-
# Check if we are still patching Text.from_ansi(). If this check fails, then Rich
120-
# has fixed the bug. Therefore, we can remove this test function and ru._Text_from_ansi.
121-
assert Text.from_ansi.__func__ is ru._Text_from_ansi.__func__ # type: ignore[attr-defined]
122-
123-
# Line breaks recognized by str.splitlines().
124-
# Source: https://docs.python.org/3/library/stdtypes.html#str.splitlines
125-
line_breaks = {
126-
"\n", # Line Feed
127-
"\r", # Carriage Return
128-
"\r\n", # Carriage Return + Line Feed
129-
"\v", # Vertical Tab
130-
"\f", # Form Feed
131-
"\x1c", # File Separator
132-
"\x1d", # Group Separator
133-
"\x1e", # Record Separator
134-
"\x85", # Next Line (NEL)
135-
"\u2028", # Line Separator
136-
"\u2029", # Paragraph Separator
137-
}
138-
139-
# Test all line breaks
140-
for lb in line_breaks:
141-
input_string = f"Text{lb}"
142-
expected_output = input_string.replace(lb, "\n")
143-
assert Text.from_ansi(input_string).plain == expected_output
144-
145-
# Test string without trailing line break
146-
input_string = "No trailing\nline break"
147-
assert Text.from_ansi(input_string).plain == input_string
148-
149-
# Test empty string
150-
input_string = ""
151-
assert Text.from_ansi(input_string).plain == input_string
152-
153-
154118
def test_cmd2_base_console_print(mocker: MockerFixture) -> None:
155119
"""Test that Cmd2BaseConsole.print() calls prepare_objects_for_rendering()."""
156120
# Mock prepare_objects_for_rendering to return a specific value

0 commit comments

Comments
 (0)