@@ -301,6 +301,7 @@ def get_items(self, names: list[str]) -> list[tuple[str, str | None, str, str]]:
301301 )
302302 raise ValueError (msg )
303303
304+ document_settings = self .state .document .settings
304305 env = self .env
305306 config = env .config
306307 current_document = env .current_document
@@ -395,7 +396,7 @@ def get_items(self, names: list[str]) -> list[tuple[str, str | None, str, str]]:
395396 props = props ,
396397 options = opts ,
397398 )
398- summary = extract_summary (list (docstring_lines ), self . state . document )
399+ summary = extract_summary (list (docstring_lines ), document_settings )
399400
400401 items .append ((display_name , sig , summary , real_name ))
401402
@@ -537,51 +538,47 @@ def mangle_signature(sig: str, max_chars: int = 30) -> str:
537538 return '(%s)' % sig
538539
539540
540- def extract_summary (doc : list [str ], document : Any ) -> str :
541+ def extract_summary (doc : Sequence [str ], settings : Any ) -> str :
541542 """Extract summary from docstring."""
543+ # Find the first stanza (heading, sentence, paragraph, etc.).
544+ # If there's a blank line, then we can assume that the stanza has ended,
545+ # so anything after shouldn't be part of the summary.
546+ first_stanza = []
547+ content_started = False
548+ for line in doc :
549+ is_blank_line = not line or line .isspace ()
550+ if not content_started :
551+ # Skip any blank lines at the start
552+ if is_blank_line :
553+ continue
554+ content_started = True
555+ if content_started :
556+ if is_blank_line :
557+ break
558+ first_stanza .append (line )
542559
543- def parse (doc : list [str ], settings : Any ) -> nodes .document :
544- state_machine = RSTStateMachine (state_classes , 'Body' )
545- node = new_document ('' , settings )
546- node .reporter = NullReporter ()
547- state_machine .run (doc , node )
548-
549- return node
550-
551- # Skip a blank lines at the top
552- while doc and not doc [0 ].strip ():
553- doc .pop (0 )
554-
555- # If there's a blank line, then we can assume the first sentence /
556- # paragraph has ended, so anything after shouldn't be part of the
557- # summary
558- for i , piece in enumerate (doc ):
559- if not piece .strip ():
560- doc = doc [:i ]
561- break
562-
563- if doc == []:
560+ if not first_stanza :
564561 return ''
565562
566563 # parse the docstring
567- node = parse ( doc , document . settings )
564+ node = _parse_summary ( first_stanza , settings )
568565 if isinstance (node [0 ], nodes .section ):
569566 # document starts with a section heading, so use that.
570567 summary = node [0 ].astext ().strip ()
571568 elif not isinstance (node [0 ], nodes .paragraph ):
572569 # document starts with non-paragraph: pick up the first line
573- summary = doc [0 ].strip ()
570+ summary = first_stanza [0 ].strip ()
574571 else :
575572 # Try to find the "first sentence", which may span multiple lines
576- sentences = periods_re .split (' ' .join (doc ))
573+ sentences = periods_re .split (' ' .join (first_stanza ))
577574 if len (sentences ) == 1 :
578575 summary = sentences [0 ].strip ()
579576 else :
580577 summary = ''
581578 for i in range (len (sentences )):
582579 summary = '. ' .join (sentences [: i + 1 ]).rstrip ('.' ) + '.'
583580 node [:] = []
584- node = parse ( doc , document . settings )
581+ node = _parse_summary ( first_stanza , settings )
585582 if summary .endswith (WELL_KNOWN_ABBREVIATIONS ):
586583 pass
587584 elif not any (node .findall (nodes .system_message )):
@@ -594,6 +591,15 @@ def parse(doc: list[str], settings: Any) -> nodes.document:
594591 return summary
595592
596593
594+ def _parse_summary (doc : Sequence [str ], settings : Any ) -> nodes .document :
595+ state_machine = RSTStateMachine (state_classes , 'Body' )
596+ node = new_document ('' , settings )
597+ node .reporter = NullReporter ()
598+ state_machine .run (doc , node )
599+
600+ return node
601+
602+
597603def limited_join (
598604 sep : str , items : list [str ], max_chars : int = 30 , overflow_marker : str = '...'
599605) -> str :
0 commit comments