Commit 4dee4ad5 authored by Irina.Fediaeva's avatar Irina.Fediaeva Committed by intellij-monorepo-bot
Browse files

PY-43035: Fix multiline sections in section-based docstrings

Now when parse docstring we take into account the block type. For OPTIONAL_TYPE sections such as Returns and Yields we don't require additional indent for lines following the summary.

IJ-MR-95356

(cherry picked from commit 5dd7adf5f9042204a29b731a3a7379cc3c743af9)

GitOrigin-RevId: 0393ed61220358c62b4b5d5b0547be6d12e2090c
parent 3f511c44
Showing with 61 additions and 4 deletions
+61 -4
......@@ -150,11 +150,9 @@ public class GoogleCodeStyleDocString extends SectionBasedDocString {
}
if (description != null) {
// parse line with indentation at least one space greater than indentation of the field
final Pair<List<Substring>, Integer> pair = parseIndentedBlock(lineNum + 1, getLineIndentSize(lineNum));
final Pair<List<Substring>, Integer> pair = parseFieldContinuation(lineNum, fieldType);
final List<Substring> nestedBlock = pair.getFirst();
if (!nestedBlock.isEmpty()) {
//noinspection ConstantConditions
description = description.union(ContainerUtil.getLastItem(nestedBlock));
}
description = description.trim();
......
......@@ -140,7 +140,7 @@ public class NumpyDocString extends SectionBasedDocString {
if (namesPart == null && !isValidType(type.toString())) {
return Pair.create(null, lineNum);
}
final Pair<List<Substring>, Integer> parsedDescription = parseIndentedBlock(lineNum + 1, getLineIndentSize(lineNum));
final Pair<List<Substring>, Integer> parsedDescription = parseFieldContinuation(lineNum, kind);
final List<Substring> descriptionLines = parsedDescription.getFirst();
if (!descriptionLines.isEmpty()) {
description = descriptionLines.get(0).union(descriptionLines.get(descriptionLines.size() - 1));
......
......@@ -30,6 +30,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.regex.Pattern;
import static com.jetbrains.python.documentation.docstrings.SectionBasedDocString.FieldType.OPTIONAL_TYPE;
/**
* Common base class for docstring styles supported by Napoleon Sphinx extension.
*
......@@ -221,6 +223,13 @@ public abstract class SectionBasedDocString extends DocStringLineParser implemen
isSectionStart(lineNum);
}
@NotNull
protected Pair<List<Substring>, Integer> parseFieldContinuation(int lineNum, @NotNull FieldType fieldType) {
int indent = getLineIndentSize(lineNum);
// we don't need additional indentation for Yields and Returns sections
return parseIndentedBlock(lineNum + 1, fieldType == OPTIONAL_TYPE ? indent - 1 : indent);
}
/**
* Consumes all lines that are indented more than {@code blockIndent} and don't contain start of a new section.
* Trailing empty lines (e.g. due to indentation of closing triple quotes) are omitted in result.
......
<html><body><div class='definition'><pre><a href="psi_element://#module#MultilineReturnSectionGoogle">MultilineReturnSectionGoogle</a><br>def <b>foo</b>() -&gt; <a href="psi_element://#typename#bool">bool</a></pre></div><div class='content'>Unittest placeholder</div><table class='sections'><tr><td valign='top' class='section'><p>Returns:</td><td valign='top'>True if successful, False otherwise.
The return type is optional and may be specified at the beginning of
the Returns section followed by a colon.
The Returns section may span multiple lines and paragraphs.
Following lines should be indented to match the first line.</td></table></body></html>
\ No newline at end of file
def fo<the_ref>o():
"""
Returns:
bool: True if successful, False otherwise.
The return type is optional and may be specified at the beginning of
the Returns section followed by a colon.
The Returns section may span multiple lines and paragraphs.
Following lines should be indented to match the first line.
"""
pass
\ No newline at end of file
<html><body><div class='definition'><pre><a href="psi_element://#module#MultilineReturnSectionNumpy">MultilineReturnSectionNumpy</a><br>def <b>foo</b>() -&gt; <a href="psi_element://#typename#bool">bool</a></pre></div><div class='content'>Unittest placeholder</div><table class='sections'><tr><td valign='top' class='section'><p>Returns:</td><td valign='top'>True if successful, False otherwise.
The return type is optional and may be specified at the beginning of
the Returns section followed by a colon.
The Returns section may span multiple lines and paragraphs.
Following lines should be indented to match the first line.</td></table></body></html>
\ No newline at end of file
def fo<the_ref>o():
"""
Returns
-------
bool
True if successful, False otherwise.
The return type is optional and may be specified at the beginning of
the Returns section followed by a colon.
The Returns section may span multiple lines and paragraphs.
Following lines should be indented to match the first line.
"""
pass
\ No newline at end of file
......@@ -721,6 +721,16 @@ public class PyQuickDocTest extends LightMarkedTestCase {
checkHTMLOnly();
}
// PY-43035
public void testMultilineReturnSectionGoogle() {
checkHTMLOnly();
}
// PY-43035
public void testMultilineReturnSectionNumpy() {
checkHTMLOnly();
}
@Override
protected String getTestDataPath() {
return super.getTestDataPath() + "/quickdoc/";
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment