diff options
| author | robot-piglet <[email protected]> | 2026-02-21 17:34:55 +0300 |
|---|---|---|
| committer | robot-piglet <[email protected]> | 2026-02-21 18:03:01 +0300 |
| commit | 4a2bb48a518e079622abeee860d5d3040a401bba (patch) | |
| tree | 4efcdbebaa32ad3c7e7abb57c1cbdd537d057148 /contrib/python/wcwidth/py3 | |
| parent | 274b52970ded8854a34077e3d0caa0164c359c76 (diff) | |
Intermediate changes
commit_hash:68b40ed025a133871e4c19d3a0290aa01d1c41c1
Diffstat (limited to 'contrib/python/wcwidth/py3')
| -rw-r--r-- | contrib/python/wcwidth/py3/.dist-info/METADATA | 7 | ||||
| -rw-r--r-- | contrib/python/wcwidth/py3/tests/test_textwrap.py | 186 | ||||
| -rw-r--r-- | contrib/python/wcwidth/py3/wcwidth/__init__.py | 2 | ||||
| -rw-r--r-- | contrib/python/wcwidth/py3/wcwidth/textwrap.py | 176 | ||||
| -rw-r--r-- | contrib/python/wcwidth/py3/ya.make | 2 |
5 files changed, 279 insertions, 94 deletions
diff --git a/contrib/python/wcwidth/py3/.dist-info/METADATA b/contrib/python/wcwidth/py3/.dist-info/METADATA index d8c25b9eee9..f6f0235df8f 100644 --- a/contrib/python/wcwidth/py3/.dist-info/METADATA +++ b/contrib/python/wcwidth/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: wcwidth -Version: 0.5.3 +Version: 0.6.0 Summary: Measures the displayed width of unicode strings in a terminal Project-URL: Homepage, https://github.com/jquast/wcwidth Author-email: Jeff Quast <[email protected]> @@ -486,6 +486,11 @@ languages. History ======= +0.6.0 *2026-02-06* + * **New** Parameters ``expand_tabs``, ``replace_whitespace``, ``fix_sentence_endings``, + ``drop_whitespace``, ``max_lines``, and ``placeholder`` for `wrap()`_, completing stdlib + `textwrap.wrap()`_ compatibility. + 0.5.3 *2026-01-30* * **Bugfix** Brahmic using Virama conjunct formation. `Issue #155`_, `PR #204`_. diff --git a/contrib/python/wcwidth/py3/tests/test_textwrap.py b/contrib/python/wcwidth/py3/tests/test_textwrap.py index e39c27cd269..094c8e56725 100644 --- a/contrib/python/wcwidth/py3/tests/test_textwrap.py +++ b/contrib/python/wcwidth/py3/tests/test_textwrap.py @@ -26,7 +26,6 @@ def mock_hyperlink_ids(monkeypatch): SGR_RED = '\x1b[31m' -SGR_BLUE = '\x1b[34m' SGR_BOLD = '\x1b[1m' SGR_RESET = '\x1b[0m' ATTRS = ('\x1b[31m', '\x1b[34m', '\x1b[4m', '\x1b[7m', '\x1b[41m', '\x1b[37m', '\x1b[107m') @@ -59,7 +58,7 @@ def _adjust_stdlib_result(expected, kwargs): """ if not expected: return expected - if kwargs.get('drop_whitespace'): + if kwargs.get('drop_whitespace', True): # Strip trailing whitespace from each line (old Python bug) expected = [line.rstrip() for line in expected] # Remove leading all-whitespace lines (old Python bug) @@ -77,15 +76,17 @@ def _colorize(text): ) -# Edge cases not covered by stdlib comparison -BASIC_EDGE_CASES = [ +EDGE_CASES = [ ('', 10, []), (' ', 10, []), ('\u5973', 0, ['\u5973']), + ('\u5973', 1, ['\u5973']), + (ZWJ_FAMILY, 1, [ZWJ_FAMILY]), + (HANGUL_GA, 1, [HANGUL_GA]), ] [email protected]('text,w,expected', BASIC_EDGE_CASES) [email protected]('text,w,expected', EDGE_CASES) def test_wrap_edge_cases(text, w, expected): assert wrap(text, w) == expected @@ -94,12 +95,6 @@ def test_wrap_initial_indent(): assert wrap('hello world', 10, initial_indent='> ') == ['> hello', 'world'] -def test_wrap_drops_trailing_whitespace(): - """Trailing whitespace stripped when drop_whitespace=True (CPython #140627).""" - result = wrap(' Z! a bc defghij', 3) - assert result[:3] == [' Z!', 'a', 'bc'] - - LONG_WORD_CASES = [ ('abcdefghij', 3, True, ['abc', 'def', 'ghi', 'j']), ('abcdefghij', 3, False, ['abcdefghij']), @@ -111,30 +106,19 @@ def test_wrap_long_words(text, w, break_long, expected): assert wrap(text, w, break_long_words=break_long) == expected -# Hyphen edge cases for long word breaking HYPHEN_LONG_WORD_CASES = [ - ('a-b-c-d', 3, True, ['a-', 'b-', 'c-d']), - ('a-b-c-d', 3, False, ['a-b', '-c-', 'd']), - ('---', 2, True, ['--', '-']), - ('a---b', 2, True, ['a-', '--', 'b']), - # With propagate_sgr=True, SGR continues to next line - ('a-\x1b[31mb', 2, True, ['a-\x1b[31m\x1b[0m', '\x1b[31mb\x1b[0m']), + ('a-b-c-d', 3, True, True, ['a-', 'b-', 'c-d']), + ('a-b-c-d', 3, False, True, ['a-b', '-c-', 'd']), + ('---', 2, True, True, ['--', '-']), + ('a---b', 2, True, True, ['a-', '--', 'b']), + ('a-\x1b[31mb', 2, True, True, ['a-\x1b[31m\x1b[0m', '\x1b[31mb\x1b[0m']), + ('a-\x1b[31mb', 2, True, False, ['a-\x1b[31m', 'b']), ] -HYPHEN_LONG_WORD_CASES_NO_PROPAGATE = [ - # With propagate_sgr=False, SGR stays where it is - ('a-\x1b[31mb', 2, True, ['a-\x1b[31m', 'b']), -] - [email protected]('text,w,break_hyphens,expected', HYPHEN_LONG_WORD_CASES) -def test_wrap_hyphen_long_words(text, w, break_hyphens, expected): - assert wrap(text, w, break_on_hyphens=break_hyphens) == expected - - [email protected]('text,w,break_hyphens,expected', HYPHEN_LONG_WORD_CASES_NO_PROPAGATE) -def test_wrap_hyphen_long_words_no_propagate(text, w, break_hyphens, expected): - assert wrap(text, w, break_on_hyphens=break_hyphens, propagate_sgr=False) == expected [email protected]('text,w,break_hyphens,propagate,expected', HYPHEN_LONG_WORD_CASES) +def test_wrap_hyphen_long_words(text, w, break_hyphens, propagate, expected): + assert wrap(text, w, break_on_hyphens=break_hyphens, propagate_sgr=propagate) == expected # Comprehensive stdlib compatibility @@ -147,6 +131,17 @@ TEXTWRAP_KWARGS = [ {'break_long_words': True, 'drop_whitespace': True, 'subsequent_indent': ' '}, {'break_long_words': True, 'drop_whitespace': True, 'break_on_hyphens': True}, {'break_long_words': True, 'drop_whitespace': True, 'break_on_hyphens': False}, + {'break_long_words': True, 'drop_whitespace': False, + 'subsequent_indent': '', 'max_lines': 4, 'placeholder': '~'}, + {'break_long_words': True, 'drop_whitespace': True, + 'max_lines': 3, 'placeholder': '...'}, + {'break_long_words': True, 'drop_whitespace': True, + 'max_lines': 1, 'placeholder': '...'}, + {'expand_tabs': False, 'break_long_words': True, 'drop_whitespace': True}, + {'replace_whitespace': False, 'break_long_words': True, + 'drop_whitespace': True}, + {'fix_sentence_endings': True, 'break_long_words': True, + 'drop_whitespace': True}, ] @@ -187,20 +182,6 @@ def test_wrap_multiline_matches_stdlib(): assert wrap(given, 30) == textwrap.wrap(given, 30) -# Wide characters that exceed width=1 (tests force-grapheme logic) -WIDE_CHAR_WIDTH_1_CASES = [ - ('\u5973', 1, ['\u5973']), - (ZWJ_FAMILY, 1, [ZWJ_FAMILY]), - (HANGUL_GA, 1, [HANGUL_GA]), -] - - [email protected]('text,w,expected', WIDE_CHAR_WIDTH_1_CASES) -def test_wrap_wide_char_width_1(text, w, expected): - assert wrap(text, w) == expected - - -# Unicode width-aware wrapping UNICODE_CASES = [ # CJK (2 cells each) ('\u4e2d\u6587\u5b57\u7b26', 4, ['\u4e2d\u6587', '\u5b57\u7b26']), @@ -244,24 +225,15 @@ SEQUENCE_CASES = [ ('abc\x1bdefghij', 3, ['abc\x1b', 'def', 'ghi', 'j']), ] -# Old behavior tests (propagate_sgr=False) SEQUENCE_CASES_NO_PROPAGATE = [ - (f'{SGR_RED}red{SGR_RESET} blue', 4, [f'{SGR_RED}red{SGR_RESET}', 'blue']), (f'hello{SGR_RED} world', 6, [f'hello{SGR_RED}', 'world']), - (f'{SGR_RED}{SGR_RESET}', 10, [f'{SGR_RED}{SGR_RESET}']), - (f'hello {SGR_RED}{SGR_RESET}world', 6, ['hello', f'{SGR_RED}{SGR_RESET}world']), - # Sequences preserved where they are, not propagated ('x\x1b[31mabcdefghij\x1b[0m', 3, ['x\x1b[31mab', 'cde', 'fgh', 'ij\x1b[0m']), ] @pytest.mark.parametrize('text,w,expected', SEQUENCE_CASES) def test_wrap_sequences(benchmark, text, w, expected): - result = benchmark(wrap, text, w) - if any('\x1b' in e or '\x00' <= e[0] < '\x20' for e in expected if e): - assert result == expected - else: - assert result == expected + assert benchmark(wrap, text, w) == expected @pytest.mark.parametrize('text,w,expected', SEQUENCE_CASES_NO_PROPAGATE) @@ -445,3 +417,107 @@ def test_wrap_hyperlink_word_boundary(text, w, expected): """OSC hyperlink sequences should act as word boundaries.""" result = wrap(text, w) assert result == expected + + +PLACEHOLDER_STDLIB_CASES = [ + ('The quick brown fox jumps over the lazy dog', + {'width': 10, 'max_lines': 3, 'placeholder': '...'}), + ('1234567890 1234567890 extra', + {'width': 10, 'max_lines': 2, 'placeholder': '...'}), + ('1234567890 1234567890', + {'width': 10, 'max_lines': 1, 'placeholder': '...'}), + ('short 1234567890 extra', + {'width': 10, 'max_lines': 2, 'placeholder': '...'}), + ('hello world', + {'width': 10, 'max_lines': 5, 'placeholder': '...'}), + ('hello world foo bar baz', + {'width': 8, 'max_lines': 2, 'placeholder': ' [...]'}), + ('a bb ccc', + {'width': 3, 'max_lines': 2, 'placeholder': '.'}), + ('a bb ccc dddd', + {'width': 4, 'max_lines': 3, 'placeholder': '~'}), + (' a ', {'width': 1, 'max_lines': 2, 'drop_whitespace': False, 'placeholder': '~'}), + ('hello world', {'width': 20, 'max_lines': 5}), + ('ab cd', {'width': 5, 'max_lines': 1}), + ('aaa bbb ccc', {'width': 3, 'max_lines': 2, 'placeholder': '...'}), + ('hello world foo bar', + {'width': 10, 'subsequent_indent': ' ', 'max_lines': 2, 'placeholder': '...'}), + ('hello world foo bar', + {'width': 10, 'initial_indent': '> ', 'max_lines': 2, 'placeholder': '...'}), +] + + [email protected]('text,kwargs', PLACEHOLDER_STDLIB_CASES) +def test_wrap_max_lines_matches_stdlib(text, kwargs): + expected = _adjust_stdlib_result(textwrap.wrap(text, **kwargs), kwargs) + assert wrap(text, **kwargs) == expected + + +def test_wrap_placeholder_too_large(): + with pytest.raises(ValueError, match="placeholder too large"): + wrap('hello', width=3, max_lines=1, placeholder='.....') + with pytest.raises(ValueError): + textwrap.wrap('fox', width=1, max_lines=3, placeholder='...') + + +MAX_LINES_SEQUENCE_CASES = [ + (f'{SGR_RED}hello world foo bar{SGR_RESET}', + 8, 2, '...', [f'{SGR_RED}hello{SGR_RESET}', f'{SGR_RED}world...{SGR_RESET}']), + (f'{SGR_RED}hello{SGR_RESET} world foo', + 8, 2, '...', [f'{SGR_RED}hello{SGR_RESET}', 'world...']), + (f'{SGR_RED}hello{SGR_RESET} world', + 6, 1, '.', [f'{SGR_RED}hello{SGR_RESET}.']), + ('\u4e2d\u6587 \u5b57\u7b26 hello', 5, 1, '~', ['\u4e2d\u6587~']), + ('\u4e2d\u6587 \u5b57\u7b26 hello world', 5, 2, '~', ['\u4e2d\u6587', '\u5b57\u7b26~']), + ('\u4e2d\u6587\u5b57\u7b26 hello', 12, 1, '...', ['\u4e2d\u6587\u5b57\u7b26...']), +] + + [email protected]('text,w,ml,ph,expected', MAX_LINES_SEQUENCE_CASES) +def test_wrap_max_lines_sequences(text, w, ml, ph, expected): + assert wrap(text, w, max_lines=ml, placeholder=ph) == expected + + +def test_wrap_max_lines_hyperlink_closed(): + """Truncation inside a hyperlink closes it before the placeholder.""" + text = f'{OSC_START_ST}Click here please{OSC_END_ST}' + result = wrap(text, 10, max_lines=1, placeholder='...') + assert len(result) == 1 + assert result[0].endswith(f'{OSC_END_ST}...') + assert OSC_START_ST in result[0] + + +def test_wrap_max_lines_hyperlink_close_on_prev_line(): + """Fallback to previous line preserves hyperlink close sequence.""" + text = f'{OSC_START_ST}ab{OSC_END_ST} cccccccccc ddddd' + result = wrap(text, 10, max_lines=2, placeholder='...') + assert result == [f'{OSC_START_ST}ab{OSC_END_ST}...'] + + +# -- expand_tabs, replace_whitespace, fix_sentence_endings -- + +STDLIB_PARAM_CASES = [ + ('hello\tworld', {'width': 20, 'expand_tabs': False, 'replace_whitespace': False}), + ('hello\tworld foo\tbar baz', {'width': 12, 'expand_tabs': False, 'tabsize': 8}), + ('hello\nworld', {'width': 20, 'replace_whitespace': False}), + ('a\t b\n c', {'width': 20, 'replace_whitespace': False}), + ('Hello world. This is a test. More text.', {'width': 20, 'fix_sentence_endings': True}), + ('Dr. Smith went to Washington. He left.', {'width': 20, 'fix_sentence_endings': True}), +] + + [email protected]('text,kwargs', STDLIB_PARAM_CASES) +def test_wrap_stdlib_params(text, kwargs): + assert wrap(text, **kwargs) == textwrap.wrap(text, **kwargs) + + +def test_wrap_expand_tabs_false_with_sequences(): + text = f'{SGR_RED}a\tb{SGR_RESET}' + result = wrap(text, 20, expand_tabs=False, replace_whitespace=False) + assert '\t' in _strip(result[0]) + + +def test_wrap_replace_whitespace_false_newlines_zero_width(): + """Newlines have zero display width, so more text fits per line than stdlib.""" + assert wrap('hello\nworld foo\nbar', 10, replace_whitespace=False) == [ + 'hello\nworld', 'foo\nbar'] diff --git a/contrib/python/wcwidth/py3/wcwidth/__init__.py b/contrib/python/wcwidth/py3/wcwidth/__init__.py index ffb13207b61..400c8a61935 100644 --- a/contrib/python/wcwidth/py3/wcwidth/__init__.py +++ b/contrib/python/wcwidth/py3/wcwidth/__init__.py @@ -40,4 +40,4 @@ __all__ = ('wcwidth', 'wcswidth', 'width', 'iter_sequences', 'iter_graphemes', # Using 'hatchling', it does not seem to provide the pyproject.toml nicety, "dynamic = ['version']" # like flit_core, maybe there is some better way but for now we have to duplicate it in both places -__version__ = '0.5.3' +__version__ = '0.6.0' diff --git a/contrib/python/wcwidth/py3/wcwidth/textwrap.py b/contrib/python/wcwidth/py3/wcwidth/textwrap.py index e6cca9161e8..4582cd5e089 100644 --- a/contrib/python/wcwidth/py3/wcwidth/textwrap.py +++ b/contrib/python/wcwidth/py3/wcwidth/textwrap.py @@ -228,6 +228,16 @@ class SequenceTextWrapper(textwrap.TextWrapper): if not chunks: return [] + if self.max_lines is not None: + if self.max_lines > 1: + indent = self.subsequent_indent + else: + indent = self.initial_indent + if (self._width(indent) + + self._width(self.placeholder.lstrip()) + > self.width): + raise ValueError("placeholder too large for max width") + lines: list[str] = [] is_first_line = True @@ -296,48 +306,90 @@ class SequenceTextWrapper(textwrap.TextWrapper): current_line[-1] = current_line[-1] + sequences if current_line: - line_content = ''.join(current_line) + # Check whether this is a normal append or max_lines + # truncation. Matches stdlib textwrap precedence: + # normal if max_lines not set, not yet reached, or no + # remaining visible content that would need truncation. + no_more_content = ( + not chunks or + self.drop_whitespace and + len(chunks) == 1 and + not self._strip_sequences(chunks[0]).strip() + ) + if (self.max_lines is None or + len(lines) + 1 < self.max_lines or + no_more_content + and current_width <= line_width): + line_content = ''.join(current_line) - # Track hyperlink state through this line's content - new_state = self._track_hyperlink_state(line_content, hyperlink_state) + # Track hyperlink state through this line's content + new_state = self._track_hyperlink_state(line_content, hyperlink_state) - # If we end inside a hyperlink, append close sequence - if new_state is not None: - # Ensure we have an id for continuation - if current_hyperlink_id is None: - if 'id=' in new_state.params: - current_hyperlink_id = new_state.params - elif new_state.params: - # Prepend id to existing params (per OSC 8 spec, params can have - # multiple key=value pairs separated by :) - current_hyperlink_id = ( - f'id={self._next_hyperlink_id()}:{new_state.params}') - else: - current_hyperlink_id = f'id={self._next_hyperlink_id()}' - line_content = line_content + _make_hyperlink_close(new_state.terminator) + # If we end inside a hyperlink, append close sequence + if new_state is not None: + # Ensure we have an id for continuation + if current_hyperlink_id is None: + if 'id=' in new_state.params: + current_hyperlink_id = new_state.params + elif new_state.params: + # Prepend id to existing params (per OSC 8 spec, params can have + # multiple key=value pairs separated by :) + current_hyperlink_id = ( + f'id={self._next_hyperlink_id()}:{new_state.params}') + else: + current_hyperlink_id = f'id={self._next_hyperlink_id()}' + line_content += _make_hyperlink_close(new_state.terminator) - # Also need to inject the id into the opening sequence if it didn't have one - if 'id=' not in new_state.params: - # Find and replace the original open sequence with one that has id - old_open = _make_hyperlink_open( - new_state.url, new_state.params, new_state.terminator) - new_open = _make_hyperlink_open( + # Also need to inject the id into the opening + # sequence if it didn't have one + if 'id=' not in new_state.params: + # Find and replace the original open sequence with one that has id + old_open = _make_hyperlink_open( + new_state.url, new_state.params, new_state.terminator) + new_open = _make_hyperlink_open( + new_state.url, current_hyperlink_id, new_state.terminator) + line_content = line_content.replace(old_open, new_open, 1) + + # Update state for next line, using computed id + hyperlink_state = _HyperlinkState( new_state.url, current_hyperlink_id, new_state.terminator) - line_content = line_content.replace(old_open, new_open, 1) + else: + hyperlink_state = None + current_hyperlink_id = None # Reset id when hyperlink closes - # Update state for next line, using computed id - hyperlink_state = _HyperlinkState( - new_state.url, current_hyperlink_id, new_state.terminator) + # Strip trailing whitespace when drop_whitespace is enabled + # (matches CPython #140627 fix behavior) + if self.drop_whitespace: + line_content = line_content.rstrip() + lines.append(indent + line_content) + is_first_line = False else: - hyperlink_state = None - current_hyperlink_id = None # Reset id when hyperlink closes - - # Strip trailing whitespace when drop_whitespace is enabled - # (matches CPython #140627 fix behavior) - if self.drop_whitespace: - line_content = line_content.rstrip() - lines.append(indent + line_content) - is_first_line = False + # max_lines reached with remaining content — + # pop chunks until placeholder fits, then break. + placeholder_w = self._width(self.placeholder) + while current_line: + last_text = self._strip_sequences(current_line[-1]) + if (last_text.strip() + and current_width + placeholder_w <= line_width): + line_content = ''.join(current_line) + new_state = self._track_hyperlink_state( + line_content, hyperlink_state) + if new_state is not None: + line_content += _make_hyperlink_close( + new_state.terminator) + lines.append(indent + line_content + self.placeholder) + break + current_width -= self._width(current_line[-1]) + del current_line[-1] + else: + if lines: + prev_line = self._rstrip_visible(lines[-1]) + if (self._width(prev_line) + placeholder_w + <= self.width): + lines[-1] = prev_line + self.placeholder + break + lines.append(indent + self.placeholder.lstrip()) + break return lines @@ -461,15 +513,40 @@ class SequenceTextWrapper(textwrap.TextWrapper): """Find the end position of the first grapheme.""" return len(next(iter_graphemes(text))) + def _rstrip_visible(self, text: str) -> str: + """Strip trailing visible whitespace, preserving trailing sequences.""" + segments = list(iter_sequences(text)) + last_vis = -1 + for i, (segment, is_seq) in enumerate(segments): + if not is_seq and segment.rstrip(): + last_vis = i + if last_vis == -1: + return '' + result = [] + for i, (segment, is_seq) in enumerate(segments): + if i < last_vis: + result.append(segment) + elif i == last_vis: + result.append(segment.rstrip()) + elif is_seq: + result.append(segment) + return ''.join(result) + def wrap(text: str, width: int = 70, *, control_codes: Literal['parse', 'strict', 'ignore'] = 'parse', tabsize: int = 8, + expand_tabs: bool = True, + replace_whitespace: bool = True, ambiguous_width: int = 1, initial_indent: str = '', subsequent_indent: str = '', + fix_sentence_endings: bool = False, break_long_words: bool = True, break_on_hyphens: bool = True, + drop_whitespace: bool = True, + max_lines: int | None = None, + placeholder: str = ' [...]', propagate_sgr: bool = True) -> list[str]: r""" Wrap text to fit within given width, returning a list of wrapped lines. @@ -482,12 +559,28 @@ def wrap(text: str, width: int = 70, *, :param width: Maximum line width in display cells. :param control_codes: How to handle terminal sequences (see :func:`~.width`). :param tabsize: Tab stop width for tab expansion. + :param expand_tabs: If True (default), tab characters are expanded + to spaces using ``tabsize``. + :param replace_whitespace: If True (default), each whitespace character + is replaced with a single space after tab expansion. When False, + control whitespace like ``\n`` has zero display width (unlike + :func:`textwrap.wrap` which counts ``len()``), so wrap points + may differ from stdlib for non-space whitespace characters. :param ambiguous_width: Width to use for East Asian Ambiguous (A) characters. Default is ``1`` (narrow). Set to ``2`` for CJK contexts. :param initial_indent: String prepended to first line. :param subsequent_indent: String prepended to subsequent lines. + :param fix_sentence_endings: If True, ensure sentences are always + separated by exactly two spaces. :param break_long_words: If True, break words longer than width. :param break_on_hyphens: If True, allow breaking at hyphens. + :param drop_whitespace: If True (default), whitespace at the beginning + and end of each line (after wrapping but before indenting) is dropped. + Set to False to preserve whitespace. + :param max_lines: If set, output contains at most this many lines, with + ``placeholder`` appended to the last line if the text was truncated. + :param placeholder: String appended to the last line when text is + truncated by ``max_lines``. Default is ``' [...]'``. :param propagate_sgr: If True (default), SGR (terminal styling) sequences are propagated across wrapped lines. Each line ends with a reset sequence and the next line begins with the active style restored. @@ -526,6 +619,10 @@ def wrap(text: str, width: int = 70, *, .. versionchanged:: 0.5.0 Added ``propagate_sgr`` parameter (default True). + .. versionchanged:: 0.6.0 + Added ``expand_tabs``, ``replace_whitespace``, ``fix_sentence_endings``, + ``drop_whitespace``, ``max_lines``, and ``placeholder`` parameters. + Example:: >>> from wcwidth import wrap @@ -534,15 +631,22 @@ def wrap(text: str, width: int = 70, *, >>> wrap('中文字符', 4) # CJK characters (2 cells each) ['中文', '字符'] """ + # pylint: disable=too-many-arguments,too-many-locals wrapper = SequenceTextWrapper( width=width, control_codes=control_codes, tabsize=tabsize, + expand_tabs=expand_tabs, + replace_whitespace=replace_whitespace, ambiguous_width=ambiguous_width, initial_indent=initial_indent, subsequent_indent=subsequent_indent, + fix_sentence_endings=fix_sentence_endings, break_long_words=break_long_words, break_on_hyphens=break_on_hyphens, + drop_whitespace=drop_whitespace, + max_lines=max_lines, + placeholder=placeholder, ) lines = wrapper.wrap(text) diff --git a/contrib/python/wcwidth/py3/ya.make b/contrib/python/wcwidth/py3/ya.make index 8ae72ce50be..c50d8fe4296 100644 --- a/contrib/python/wcwidth/py3/ya.make +++ b/contrib/python/wcwidth/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(0.5.3) +VERSION(0.6.0) LICENSE(MIT) |
