Skip to content

Commit afcc5c5

Browse files
authored
Merge pull request #3535 from Textualize/regex-error
Regex error
2 parents 0f2f51b + 60f3b61 commit afcc5c5

File tree

5 files changed

+37
-3
lines changed

5 files changed

+37
-3
lines changed

Diff for: CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
9+
## [13.9.3] - 2024-10-22
10+
11+
### Fixed
12+
13+
- Fixed broken regex that may have resulted in poor performance. https://github.com/Textualize/rich/pull/3535
14+
815
## [13.9.2] - 2024-10-04
916

1017
### Fixed
@@ -2097,6 +2104,7 @@ Major version bump for a breaking change to `Text.stylize signature`, which corr
20972104

20982105
- First official release, API still to be stabilized
20992106

2107+
[13.9.3]: https://github.com/textualize/rich/compare/v13.9.2...v13.9.3
21002108
[13.9.2]: https://github.com/textualize/rich/compare/v13.9.1...v13.9.2
21012109
[13.9.1]: https://github.com/textualize/rich/compare/v13.9.0...v13.9.1
21022110
[13.9.0]: https://github.com/textualize/rich/compare/v13.8.1...v13.9.0

Diff for: pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "rich"
33
homepage = "https://github.com/Textualize/rich"
44
documentation = "https://rich.readthedocs.io/en/latest/"
5-
version = "13.9.2"
5+
version = "13.9.3"
66
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
77
authors = ["Will McGugan <[email protected]>"]
88
license = "MIT"

Diff for: rich/cells.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
from ._cell_widths import CELL_WIDTHS
88

99
# Regex to match sequence of the most common character ranges
10-
_is_single_cell_widths = re.compile("^[\u0020-\u006f\u00a0\u02ff\u0370-\u0482]*$").match
10+
_is_single_cell_widths = re.compile(
11+
"^[\u0020-\u007e\u00a0-\u02ff\u0370-\u0482\u2500-\u25FF]*$"
12+
).match
1113

1214

1315
@lru_cache(4096)

Diff for: rich/segment.py

+4
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,14 @@ def split_cells(self, cut: int) -> Tuple["Segment", "Segment"]:
161161
If the cut point falls in the middle of a 2-cell wide character then it is replaced
162162
by two spaces, to preserve the display width of the parent segment.
163163
164+
Args:
165+
cut (int): Offset within the segment to cut.
166+
164167
Returns:
165168
Tuple[Segment, Segment]: Two segments.
166169
"""
167170
text, style, control = self
171+
assert cut >= 0
168172

169173
if _is_single_cell_widths(text):
170174
# Fast path with all 1 cell characters

Diff for: tests/test_cells.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import string
2+
13
from rich import cells
2-
from rich.cells import chop_cells
4+
from rich.cells import _is_single_cell_widths, chop_cells
35

46

57
def test_cell_len_long_string():
@@ -59,3 +61,21 @@ def test_chop_cells_mixed_width():
5961
"""Mixed single and double-width characters."""
6062
text = "あ1り234が5と6う78"
6163
assert chop_cells(text, 3) == ["あ1", "り2", "34", "が5", "と6", "う7", "8"]
64+
65+
66+
def test_is_single_cell_widths() -> None:
67+
# Check _is_single_cell_widths reports correctly
68+
for character in string.printable:
69+
if ord(character) >= 32:
70+
assert _is_single_cell_widths(character)
71+
72+
BOX = "┌─┬┐│ ││├─┼┤│ ││├─┼┤├─┼┤│ ││└─┴┘"
73+
74+
for character in BOX:
75+
assert _is_single_cell_widths(character)
76+
77+
for character in "💩😽":
78+
assert not _is_single_cell_widths(character)
79+
80+
for character in "わさび":
81+
assert not _is_single_cell_widths(character)

0 commit comments

Comments
 (0)