Skip to content

Commit 7350738

Browse files
erlend-aaslandAlexWaygoodAA-Turner
authored
gh-104683: Argument Clinic: refactor format_docstring() (#107623)
Extract helper methods for formatting the signature and parameter sections, and clean up the remaining function body. Co-authored-by: Alex Waygood <[email protected]> Co-authored-by: Adam Turner <[email protected]>
1 parent 0be3743 commit 7350738

File tree

1 file changed

+36
-46
lines changed

1 file changed

+36
-46
lines changed

Tools/clinic/clinic.py

+36-46
Original file line numberDiff line numberDiff line change
@@ -5506,23 +5506,11 @@ def state_function_docstring(self, line: str) -> None:
55065506

55075507
self.docstring_append(self.function, line)
55085508

5509-
def format_docstring(self) -> str:
5510-
f = self.function
5511-
assert f is not None
5512-
5513-
new_or_init = f.kind.new_or_init
5514-
if new_or_init and not f.docstring:
5515-
# don't render a docstring at all, no signature, nothing.
5516-
return f.docstring
5517-
5509+
def format_docstring_signature(
5510+
self, f: Function, parameters: list[Parameter]
5511+
) -> str:
55185512
text, add, output = _text_accumulator()
5519-
parameters = f.render_parameters
5520-
5521-
##
5522-
## docstring first line
5523-
##
5524-
5525-
if new_or_init:
5513+
if f.kind.new_or_init:
55265514
# classes get *just* the name of the class
55275515
# not __new__, not __init__, and not module.classname
55285516
assert f.cls
@@ -5685,35 +5673,39 @@ def add_parameter(text: str) -> None:
56855673
if not f.docstring_only:
56865674
add("\n" + sig_end_marker + "\n")
56875675

5688-
docstring_first_line = output()
5676+
signature_line = output()
56895677

56905678
# now fix up the places where the brackets look wrong
5691-
docstring_first_line = docstring_first_line.replace(', ]', ',] ')
5679+
return signature_line.replace(', ]', ',] ')
56925680

5693-
# okay. now we're officially building the "parameters" section.
5694-
# create substitution text for {parameters}
5681+
@staticmethod
5682+
def format_docstring_parameters(params: list[Parameter]) -> str:
5683+
"""Create substitution text for {parameters}"""
5684+
text, add, output = _text_accumulator()
56955685
spacer_line = False
5696-
for p in parameters:
5697-
if not p.docstring.strip():
5686+
for param in params:
5687+
docstring = param.docstring.strip()
5688+
if not docstring:
56985689
continue
56995690
if spacer_line:
57005691
add('\n')
57015692
else:
57025693
spacer_line = True
57035694
add(" ")
5704-
add(p.name)
5695+
add(param.name)
57055696
add('\n')
5706-
add(textwrap.indent(rstrip_lines(p.docstring.rstrip()), " "))
5707-
parameters_output = output()
5708-
if parameters_output:
5709-
parameters_output += '\n'
5710-
5711-
##
5712-
## docstring body
5713-
##
5697+
stripped = rstrip_lines(docstring)
5698+
add(textwrap.indent(stripped, " "))
5699+
if text:
5700+
add('\n')
5701+
return output()
57145702

5715-
docstring = f.docstring.rstrip()
5716-
lines = [line.rstrip() for line in docstring.split('\n')]
5703+
def format_docstring(self) -> str:
5704+
assert self.function is not None
5705+
f = self.function
5706+
if f.kind.new_or_init and not f.docstring:
5707+
# don't render a docstring at all, no signature, nothing.
5708+
return f.docstring
57175709

57185710
# Enforce the summary line!
57195711
# The first line of a docstring should be a summary of the function.
@@ -5727,6 +5719,7 @@ def add_parameter(text: str) -> None:
57275719
# Guido said Clinic should enforce this:
57285720
# http://mail.python.org/pipermail/python-dev/2013-June/127110.html
57295721

5722+
lines = f.docstring.split('\n')
57305723
if len(lines) >= 2:
57315724
if lines[1]:
57325725
fail(f"Docstring for {f.full_name!r} does not have a summary line!\n"
@@ -5738,26 +5731,23 @@ def add_parameter(text: str) -> None:
57385731
# between it and the {parameters} we're about to add.
57395732
lines.append('')
57405733

5741-
parameters_marker_count = len(docstring.split('{parameters}')) - 1
5734+
parameters_marker_count = len(f.docstring.split('{parameters}')) - 1
57425735
if parameters_marker_count > 1:
57435736
fail('You may not specify {parameters} more than once in a docstring!')
57445737

5738+
# insert signature at front and params after the summary line
57455739
if not parameters_marker_count:
5746-
# insert after summary line
57475740
lines.insert(2, '{parameters}')
5741+
lines.insert(0, '{signature}')
57485742

5749-
# insert at front of docstring
5750-
lines.insert(0, docstring_first_line)
5751-
5743+
# finalize docstring
5744+
params = f.render_parameters
5745+
parameters = self.format_docstring_parameters(params)
5746+
signature = self.format_docstring_signature(f, params)
57525747
docstring = "\n".join(lines)
5753-
5754-
add(docstring)
5755-
docstring = output()
5756-
5757-
docstring = linear_format(docstring, parameters=parameters_output)
5758-
docstring = docstring.rstrip()
5759-
5760-
return docstring
5748+
return linear_format(docstring,
5749+
signature=signature,
5750+
parameters=parameters).rstrip()
57615751

57625752
def do_post_block_processing_cleanup(self, lineno: int) -> None:
57635753
"""

0 commit comments

Comments
 (0)