summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES1
-rw-r--r--sphinx/ext/autosummary/__init__.py24
-rw-r--r--tests/test_ext_autosummary.py19
3 files changed, 34 insertions, 10 deletions
diff --git a/CHANGES b/CHANGES
index 4b1f4b17a..39606e301 100644
--- a/CHANGES
+++ b/CHANGES
@@ -32,6 +32,7 @@ Bugs fixed
* autosummary: The interface of ``sphinx.ext.autosummary.get_documenter()`` has
been changed
* #4630: Have order on msgids in sphinx.pot deterministic
+* #4563: autosummary: Incorrect end of line punctuation detection
Testing
--------
diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py
index 63ca10483..1334084e2 100644
--- a/sphinx/ext/autosummary/__init__.py
+++ b/sphinx/ext/autosummary/__init__.py
@@ -64,6 +64,7 @@ from typing import TYPE_CHECKING
from docutils import nodes
from docutils.parsers.rst import Directive, directives
+from docutils.parsers.rst.states import RSTStateMachine, state_classes
from docutils.statemachine import ViewList
from six import string_types
from six import text_type
@@ -77,6 +78,7 @@ from sphinx.ext.autodoc.directive import DocumenterBridge, Options
from sphinx.ext.autodoc.importer import import_module
from sphinx.pycode import ModuleAnalyzer, PycodeError
from sphinx.util import import_object, rst, logging
+from sphinx.util.docutils import new_document
if TYPE_CHECKING:
from typing import Any, Dict, List, Tuple, Type, Union # NOQA
@@ -340,7 +342,7 @@ class Autosummary(Directive):
# -- Grab the summary
documenter.add_content(None)
- summary = extract_summary(self.result.data[:])
+ summary = extract_summary(self.result.data[:], self.state.document)
items.append((display_name, sig, summary, real_name))
@@ -447,8 +449,8 @@ def mangle_signature(sig, max_chars=30):
return u"(%s)" % sig
-def extract_summary(doc):
- # type: (List[unicode]) -> unicode
+def extract_summary(doc, document):
+ # type: (List[unicode], Any) -> unicode
"""Extract summary from docstring."""
# Skip a blank lines at the top
@@ -464,13 +466,19 @@ def extract_summary(doc):
break
# Try to find the "first sentence", which may span multiple lines
- m = re.search(r"^([A-Z].*?\.)(?:\s|$)", " ".join(doc).strip())
- if m:
- summary = m.group(1).strip()
- elif doc:
- summary = doc[0].strip()
+ sentences = " ".join(doc).split('.')
+ if len(sentences) == 1:
+ summary = sentences[0].strip()
else:
summary = ''
+ state_machine = RSTStateMachine(state_classes, 'Body')
+ while sentences:
+ summary += sentences.pop(0) + '.'
+ node = new_document('', document.settings)
+ state_machine.run([summary], node)
+ if not node.traverse(nodes.system_message):
+ # considered as that splitting by period does not break inline markups
+ break
return summary
diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py
index 11ee442d2..f9e217801 100644
--- a/tests/test_ext_autosummary.py
+++ b/tests/test_ext_autosummary.py
@@ -56,11 +56,26 @@ def test_mangle_signature():
def test_extract_summary():
+ from sphinx.util.docutils import new_document
+ from mock import Mock
+ settings = Mock(language_code='',
+ id_prefix='',
+ auto_id_prefix='',
+ pep_reference=False,
+ rfc_reference=False)
+ document = new_document('', settings)
+
+ # normal case
doc = ['',
'This is a first sentence. And second one.',
'',
'Second block is here']
- assert extract_summary(doc) == 'This is a first sentence.'
+ assert extract_summary(doc, document) == 'This is a first sentence.'
+
+ # inliner case
+ doc = ['This sentence contains *emphasis text having dots.*,',
+ 'it does not break sentence.']
+ assert extract_summary(doc, document) == ' '.join(doc)
@pytest.mark.sphinx('dummy', **default_kw)
@@ -101,7 +116,7 @@ def test_get_items_summary(make_app, app_params):
expected_values = {
'withSentence': 'I have a sentence which spans multiple lines.',
- 'noSentence': "this doesn't start with a",
+ 'noSentence': "this doesn't start with a capital.",
'emptyLine': "This is the real summary",
'module_attr': 'This is a module attribute',
'C.class_attr': 'This is a class attribute',