@@ -225,18 +225,15 @@ def _convert_type_spec(
225225 combined_tokens = _recombine_set_tokens (tokens )
226226 types = [(token , _token_type (token , debug_location )) for token in combined_tokens ]
227227
228- converters = {
228+ converters : dict [ str , Callable [[ str ], str ]] = {
229229 'literal' : lambda x : f'``{ x } ``' ,
230230 'obj' : lambda x : _convert_type_spec_obj (x , translations ),
231231 'control' : lambda x : f'*{ x } *' ,
232232 'delimiter' : lambda x : x ,
233233 'reference' : lambda x : x ,
234234 }
235235
236- converted = '' .join (
237- converters .get (type_ )(token ) # type: ignore[misc]
238- for token , type_ in types
239- )
236+ converted = '' .join (converters [type_ ](token ) for token , type_ in types )
240237
241238 return converted
242239
@@ -1220,6 +1217,64 @@ def __init__(
12201217 self ._directive_sections = ['.. index::' ]
12211218 super ().__init__ (docstring , config , app , what , name , obj , options )
12221219
1220+ def _parse (self ) -> None :
1221+ self ._parsed_lines = self ._consume_empty ()
1222+
1223+ if self ._name and self ._what in {'attribute' , 'data' , 'property' }:
1224+ res : list [str ] = []
1225+ with contextlib .suppress (StopIteration ):
1226+ res = self ._parse_attribute_docstring ()
1227+
1228+ self ._parsed_lines .extend (res )
1229+ return
1230+
1231+ sections : list [tuple [str , list [str ]]] = []
1232+
1233+ while self ._lines :
1234+ if self ._is_section_header ():
1235+ try :
1236+ section = self ._consume_section_header ()
1237+ self ._is_in_section = True
1238+ self ._section_indent = self ._get_current_indent ()
1239+ if _directive_regex .match (section ):
1240+ lines = [section , * self ._consume_to_next_section ()]
1241+ sections .append ((section , lines ))
1242+ else :
1243+ lines = self ._sections [section .lower ()](section )
1244+ sections .append ((section .lower (), lines ))
1245+ finally :
1246+ self ._is_in_section = False
1247+ self ._section_indent = 0
1248+ else :
1249+ if not self ._parsed_lines and not sections :
1250+ lines = self ._consume_contiguous () + self ._consume_empty ()
1251+ self ._parsed_lines .extend (lines )
1252+ else :
1253+ lines = self ._consume_to_next_section ()
1254+ sections .append (('_msg' , lines ))
1255+
1256+ # Reorder sections: Attributes and Methods should come after Parameters
1257+ excluded_sections = {'attributes' , 'methods' }
1258+ attributes_secs = [s for s in sections if s [0 ] == 'attributes' ]
1259+ methods_secs = [s for s in sections if s [0 ] == 'methods' ]
1260+ other_secs = [s for s in sections if s [0 ] not in excluded_sections ]
1261+
1262+ insert_idx = 0
1263+ for i , (name , _section_lines ) in enumerate (other_secs ):
1264+ if name == 'parameters' :
1265+ insert_idx = i + 1
1266+ break
1267+
1268+ final_sections = (
1269+ other_secs [:insert_idx ]
1270+ + attributes_secs
1271+ + methods_secs
1272+ + other_secs [insert_idx :]
1273+ )
1274+
1275+ for _name , lines in final_sections :
1276+ self ._parsed_lines .extend (lines )
1277+
12231278 def _escape_args_and_kwargs (self , name : str ) -> str :
12241279 func = super ()._escape_args_and_kwargs
12251280
0 commit comments