Skip to content

Commit

Permalink
gh-104683: Argument Clinic: refactor format_docstring() (#107623)
Browse files Browse the repository at this point in the history
Extract helper methods for formatting the signature and parameter
sections, and clean up the remaining function body.

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
  • Loading branch information
3 people committed Aug 8, 2023
1 parent 0be3743 commit 7350738
Showing 1 changed file with 36 additions and 46 deletions.
82 changes: 36 additions & 46 deletions Tools/clinic/clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5506,23 +5506,11 @@ def state_function_docstring(self, line: str) -> None:

self.docstring_append(self.function, line)

def format_docstring(self) -> str:
f = self.function
assert f is not None

new_or_init = f.kind.new_or_init
if new_or_init and not f.docstring:
# don't render a docstring at all, no signature, nothing.
return f.docstring

def format_docstring_signature(
self, f: Function, parameters: list[Parameter]
) -> str:
text, add, output = _text_accumulator()
parameters = f.render_parameters

##
## docstring first line
##

if new_or_init:
if f.kind.new_or_init:
# classes get *just* the name of the class
# not __new__, not __init__, and not module.classname
assert f.cls
Expand Down Expand Up @@ -5685,35 +5673,39 @@ def add_parameter(text: str) -> None:
if not f.docstring_only:
add("\n" + sig_end_marker + "\n")

docstring_first_line = output()
signature_line = output()

# now fix up the places where the brackets look wrong
docstring_first_line = docstring_first_line.replace(', ]', ',] ')
return signature_line.replace(', ]', ',] ')

# okay. now we're officially building the "parameters" section.
# create substitution text for {parameters}
@staticmethod
def format_docstring_parameters(params: list[Parameter]) -> str:
"""Create substitution text for {parameters}"""
text, add, output = _text_accumulator()
spacer_line = False
for p in parameters:
if not p.docstring.strip():
for param in params:
docstring = param.docstring.strip()
if not docstring:
continue
if spacer_line:
add('\n')
else:
spacer_line = True
add(" ")
add(p.name)
add(param.name)
add('\n')
add(textwrap.indent(rstrip_lines(p.docstring.rstrip()), " "))
parameters_output = output()
if parameters_output:
parameters_output += '\n'

##
## docstring body
##
stripped = rstrip_lines(docstring)
add(textwrap.indent(stripped, " "))
if text:
add('\n')
return output()

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

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

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

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

# insert signature at front and params after the summary line
if not parameters_marker_count:
# insert after summary line
lines.insert(2, '{parameters}')
lines.insert(0, '{signature}')

# insert at front of docstring
lines.insert(0, docstring_first_line)

# finalize docstring
params = f.render_parameters
parameters = self.format_docstring_parameters(params)
signature = self.format_docstring_signature(f, params)
docstring = "\n".join(lines)

add(docstring)
docstring = output()

docstring = linear_format(docstring, parameters=parameters_output)
docstring = docstring.rstrip()

return docstring
return linear_format(docstring,
signature=signature,
parameters=parameters).rstrip()

def do_post_block_processing_cleanup(self, lineno: int) -> None:
"""
Expand Down

0 comments on commit 7350738

Please sign in to comment.