Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/blurb/_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ def prnt(msg: str = '', /):
if int(issue_number):
body = f'bpo-{issue_number}: {body}'

body = f'- {body}'
text = textwrap_body(body, subsequent_indent=' ')
text = textwrap_body(body, initial_indent='- ', subsequent_indent=' ')
prnt(text)
prnt()
prnt('**(For information about older versions, consult the HISTORY file.)**')
Expand Down
14 changes: 12 additions & 2 deletions src/blurb/_utils/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
from collections.abc import Iterable


def textwrap_body(body: str | Iterable[str], *, subsequent_indent: str = '') -> str:
def textwrap_body(
body: str | Iterable[str],
*,
initial_indent: str = '',
subsequent_indent: str = '',
) -> str:
"""Wrap body text.

Accepts either a string or an iterable of strings.
Expand All @@ -34,12 +39,14 @@ def textwrap_body(body: str | Iterable[str], *, subsequent_indent: str = '') ->
paragraphs = text.split('\n\n')
paragraphs2 = []
kwargs: dict[str, object] = {'break_long_words': False, 'break_on_hyphens': False}
if initial_indent:
kwargs['initial_indent'] = initial_indent
if subsequent_indent:
kwargs['subsequent_indent'] = subsequent_indent
dont_reflow = False
for paragraph in paragraphs:
# don't reflow bulleted / numbered lists
dont_reflow = dont_reflow or paragraph.startswith(('* ', '1. ', '#. '))
dont_reflow = dont_reflow or paragraph.startswith(('* ', '- ', '1. ', '#. '))
Comment thread
StanFromIreland marked this conversation as resolved.
if dont_reflow:
initial = kwargs.get('initial_indent', '')
subsequent = kwargs.get('subsequent_indent', '')
Expand Down Expand Up @@ -91,6 +98,9 @@ def textwrap_body(body: str | Iterable[str], *, subsequent_indent: str = '') ->
paragraph = '\n'.join(
textwrap.wrap(paragraph.strip(), width=76, **kwargs)
).rstrip()
# Remove the initial indent added by the first pass,
# otherwise the second pass would add it again.
paragraph = paragraph.removeprefix(initial_indent)
paragraph = '\n'.join(
textwrap.wrap(paragraph.strip(), width=76, **kwargs)
).rstrip()
Expand Down
50 changes: 50 additions & 0 deletions tests/test_utils_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,57 @@
' * Item 1\n'
' * Item 2\n',
),
(
'This is a test of the textwrap_body function with a dashed list and subsequent indent. The list should not be wrapped.\n'
'\n'
'- Item 1\n'
'- Item 2\n',
' ',
'This is a test of the textwrap_body function with a dashed list and\n'
' subsequent indent. The list should not be wrapped.\n'
'\n'
' - Item 1\n'
' - Item 2\n',
),
(
'The following `threading` methods are now deprecated and should be replaced:\n'
'\n'
'- `threading.activeCount` => :func:`threading.active_count`\n'
'\n'
'- `threading.Condition.notifyAll` =>\n'
' :meth:`threading.Condition.notify_all`\n',
' ',
'The following `threading` methods are now deprecated and should be replaced:\n'
'\n'
' - `threading.activeCount` => :func:`threading.active_count`\n'
'\n'
' - `threading.Condition.notifyAll` =>\n'
' :meth:`threading.Condition.notify_all`\n',
),
),
)
def test_textwrap_body(body, subsequent_indent, expected):
assert textwrap_body(body, subsequent_indent=subsequent_indent) == expected


@pytest.mark.parametrize(
'body, expected',
(
(
'gh-123456: This is a long sentence that keeps going on and on so that it must wrap when\n'
'merged into the NEWS file.\n',
'- gh-123456: This is a long sentence that keeps going on and on so that it\n'
' must wrap when merged into the NEWS file.\n',
),
(
'First paragraph.\n\nSecond paragraph.\n',
'- First paragraph.\n\n Second paragraph.\n',
),
(
'Some changes:\n\n- Item 1\n- Item 2\n',
'- Some changes:\n\n - Item 1\n - Item 2\n',
),
),
)
def test_textwrap_body_initial_indent(body, expected):
assert textwrap_body(body, initial_indent='- ', subsequent_indent=' ') == expected
Loading