Skip to content

Commit ea66804

Browse files
authored
Removed Text.from_ansi() monkeypatch since it's no longer needed as of Rich 15.0.0. (#1632)
1 parent 1d6910a commit ea66804

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
@@ -479,64 +479,3 @@ def prepare_objects_for_rendering(*objects: Any) -> tuple[Any, ...]:
479479
object_list[i] = Text.from_ansi(renderable_as_str)
480480

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