Skip to content

Commit 8996056

Browse files
authored
docs: fix formatting of docstring with lists (#1687)
* add test to show issue with lists * apply fix * work around click issue with mypy * style * apply more fixes for lists * formatting * add comment * style * coverage * move tests to test_lines * coverage * style * add test
1 parent db1633d commit 8996056

File tree

3 files changed

+89
-5
lines changed

3 files changed

+89
-5
lines changed

packages/gapic-generator/gapic/utils/lines.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,12 @@ def wrap(text: str, width: int, *, offset: Optional[int] = None, indent: int = 0
8686
break_on_hyphens=False,
8787
)
8888
# Strip the first \n from the text so it is not misidentified as an
89-
# intentionally short line below.
90-
text = text.replace('\n', ' ', 1)
89+
# intentionally short line below, except when the text contains `:`
90+
# as the new line is required for lists.
91+
if '\n' in text:
92+
initial_text = text.split('\n')[0]
93+
if ":" not in initial_text:
94+
text = text.replace('\n', ' ', 1)
9195

9296
# Save the new `first` line.
9397
first = f'{initial[0]}\n'
@@ -100,6 +104,10 @@ def wrap(text: str, width: int, *, offset: Optional[int] = None, indent: int = 0
100104
tokens = []
101105
token = ''
102106
for line in text.split('\n'):
107+
# Ensure that lines that start with a hyphen are always on a new line
108+
if line.strip().startswith('-') and token:
109+
tokens.append(token)
110+
token = ''
103111
token += line + '\n'
104112
if len(line) < width * 0.75:
105113
tokens.append(token)
@@ -115,7 +123,9 @@ def wrap(text: str, width: int, *, offset: Optional[int] = None, indent: int = 0
115123
text='\n'.join([textwrap.fill(
116124
break_long_words=False,
117125
initial_indent=' ' * indent,
118-
subsequent_indent=' ' * indent,
126+
# ensure that subsequent lines for lists are indented 2 spaces
127+
subsequent_indent=' ' * indent + \
128+
(' ' if token.strip().startswith('-') else ''),
119129
text=token,
120130
width=width,
121131
break_on_hyphens=False,

packages/gapic-generator/noxfile.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,13 @@ def docs(session):
436436
@nox.session(python=NEWEST_PYTHON)
437437
def mypy(session):
438438
"""Perform typecheck analysis."""
439-
440-
session.install("mypy", "types-protobuf<=3.19.7", "types-PyYAML", "types-dataclasses")
439+
# Pin to click==8.1.3 to workaround https://github.com/pallets/click/issues/2558
440+
session.install(
441+
"mypy",
442+
"types-protobuf<=3.19.7",
443+
"types-PyYAML",
444+
"types-dataclasses",
445+
"click==8.1.3",
446+
)
441447
session.install(".")
442448
session.run("mypy", "gapic")

packages/gapic-generator/tests/unit/utils/test_lines.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,71 @@ def test_wrap_short_line_preserved():
9191

9292
def test_wrap_does_not_break_hyphenated_word():
9393
assert lines.wrap('do-not-break', width=5) == 'do-not-break'
94+
95+
96+
def test_wrap_with_short_lines():
97+
input = """The hail in Wales falls mainly on the snails. The hail in Wales falls mainly
98+
on the snails."""
99+
expected = """The hail in Wales falls mainly on the snails. The hail in
100+
Wales falls mainly on the snails."""
101+
assert lines.wrap(input, width=60) == expected
102+
103+
104+
def test_list_each_item_in_list_has_new_line():
105+
s = """Type of weather:
106+
- Hail
107+
- Rain Rain Rain Rain Rain Rain Rain Rain Rain Rain Rain Rain
108+
- Snow"""
109+
assert lines.wrap(s, width=80) == s
110+
111+
112+
def test_list_items_are_indented():
113+
input = """Type of weather.
114+
Some types of weather:
115+
116+
- A mix of hail and snow, followed by rain clouds, then finally clear sky
117+
- Rain
118+
- Snow"""
119+
expected = """Type of weather.
120+
Some types of weather:
121+
122+
- A mix of hail and snow, followed by rain clouds, then
123+
finally clear sky
124+
- Rain
125+
- Snow"""
126+
assert lines.wrap(input, width=60) == expected
127+
128+
129+
def test_list_new_line_preserved_after_colon():
130+
input = """Today's forecast will have different types of weather:
131+
132+
- A mix of hail and snow, followed by rain clouds, then finally clear sky
133+
- Rain
134+
- Snow"""
135+
expected = """Today's forecast will have different types
136+
of weather:
137+
138+
- A mix of hail and snow, followed by rain
139+
clouds, then finally clear sky
140+
- Rain
141+
- Snow"""
142+
assert lines.wrap(input, width=60, indent=16) == expected
143+
144+
145+
def test_list_items_longer_text_before_list():
146+
input = """Weather Weather Weather Weather Weather Weather Weather
147+
Weather Weather Weather Weather Weather Weather Weather
148+
Type of weather:
149+
150+
- Hail
151+
- Rain Rain Rain Rain Rain Rain Rain Rain Rain Rain Rain Rain
152+
- Snow"""
153+
expected = """Weather Weather Weather Weather Weather Weather Weather
154+
Weather Weather Weather Weather Weather Weather Weather Type
155+
of weather:
156+
157+
- Hail
158+
- Rain Rain Rain Rain Rain Rain Rain Rain Rain Rain Rain
159+
Rain
160+
- Snow"""
161+
assert lines.wrap(input, width=60) == expected

0 commit comments

Comments
 (0)