@@ -79,21 +79,136 @@ def _str_returns(self, name='Returns'):
7979 out += ['' ]
8080 return out
8181
82- def _str_param_list (self , name ):
82+ def _process_param (self , param , desc , autosum ):
83+ """Determine how to display a parameter
84+
85+ Emulates autosummary behavior if autosum is not None.
86+
87+ Parameters
88+ ----------
89+ param : str
90+ The name of the parameter
91+ desc : list of str
92+ The parameter description as given in the docstring. This is
93+ ignored when autosummary logic applies.
94+ autosum : list or None
95+ If a list, autosummary-style behaviour will apply for params
96+ that are attributes of the class and have a docstring.
97+ Names for autosummary generation will be appended to this list.
98+
99+ If None, autosummary is disabled.
100+
101+ Returns
102+ -------
103+ display_param : str
104+ The marked up parameter name for display. This may include a link
105+ to the corresponding attribute's own documentation.
106+ desc : list of str
107+ A list of description lines. This may be identical to the input
108+ ``desc``, if ``autosum is None`` or ``param`` is not a class
109+ attribute, or it will be a summary of the class attribute's
110+ docstring.
111+
112+ Notes
113+ -----
114+ This does not have the autosummary functionality to display a method's
115+ signature, and hence is not used to format methods. It may be
116+ complicated to incorporate autosummary's signature mangling, as it
117+ relies on Sphinx's plugin mechanism.
118+ """
119+ param = param .strip ()
120+ display_param = '**%s**' % param
121+
122+ if autosum is None :
123+ return display_param , desc
124+
125+ param_obj = getattr (self ._obj , param , None )
126+ if not (callable (param_obj )
127+ or isinstance (param_obj , property )
128+ or inspect .isgetsetdescriptor (param_obj )):
129+ param_obj = None
130+ obj_doc = pydoc .getdoc (param_obj )
131+
132+ if not (param_obj and obj_doc ):
133+ return display_param , desc
134+
135+ prefix = getattr (self , '_name' , '' )
136+ if prefix :
137+ autosum_prefix = '~%s.' % prefix
138+ link_prefix = '%s.' % prefix
139+ else :
140+ autosum_prefix = ''
141+ link_prefix = ''
142+
143+ # Referenced object has a docstring
144+ autosum .append (" %s%s" % (autosum_prefix , param ))
145+ display_param = ':obj:`%s <%s%s>`' % (param ,
146+ link_prefix ,
147+ param )
148+ if obj_doc :
149+ # Overwrite desc. Take summary logic of autosummary
150+ desc = re .split ('\n \s*\n ' , obj_doc .strip (), 1 )[0 ]
151+ # XXX: Should this have DOTALL?
152+ # It does not in autosummary
153+ m = re .search (r"^([A-Z].*?\.)(?:\s|$)" ,
154+ ' ' .join (desc .split ()))
155+ if m :
156+ desc = m .group (1 ).strip ()
157+ else :
158+ desc = desc .partition ('\n ' )[0 ]
159+ desc = desc .split ('\n ' )
160+ return display_param , desc
161+
162+ def _str_param_list (self , name , fake_autosummary = False ):
163+ """Generate RST for a listing of parameters or similar
164+
165+ Parameter names are displayed as bold text, and descriptions
166+ are in blockquotes. Descriptions may therefore contain block
167+ markup as well.
168+
169+ Parameters
170+ ----------
171+ name : str
172+ Section name (e.g. Parameters)
173+ fake_autosummary : bool
174+ When True, the parameter names may correspond to attributes of the
175+ object beign documented, usually ``property`` instances on a class.
176+ In this case, names will be linked to fuller descriptions.
177+
178+ Returns
179+ -------
180+ rst : list of str
181+ """
83182 out = []
84183 if self [name ]:
184+ if fake_autosummary :
185+ autosum = []
186+ else :
187+ autosum = None
188+
85189 out += self ._str_field_list (name )
86190 out += ['' ]
87191 for param , param_type , desc in self [name ]:
192+ display_param , desc = self ._process_param (param , desc , autosum )
193+
88194 if param_type :
89- out += self ._str_indent (['**%s** : %s' % (param . strip () ,
90- param_type )])
195+ out += self ._str_indent (['%s : %s' % (display_param ,
196+ param_type )])
91197 else :
92- out += self ._str_indent (['**%s**' % param . strip () ])
198+ out += self ._str_indent ([display_param ])
93199 if desc :
94- out += ['' ]
200+ out += ['' ] # produces a blockquote, rather than a dt/dd
95201 out += self ._str_indent (desc , 8 )
96202 out += ['' ]
203+
204+ if fake_autosummary and autosum :
205+ if self .class_members_toctree :
206+ autosum .insert (0 , ' :toctree:' )
207+ autosum .insert (0 , '.. autosummary::' )
208+ out += ['..' , ' HACK to make autogen generate docs:' ]
209+ out += self ._str_indent (autosum , 4 )
210+ out += ['' ]
211+
97212 return out
98213
99214 @property
@@ -130,7 +245,7 @@ def _str_member_list(self, name):
130245 or inspect .isgetsetdescriptor (param_obj )):
131246 param_obj = None
132247
133- if param_obj and ( pydoc .getdoc (param_obj ) or not desc ):
248+ if param_obj and pydoc .getdoc (param_obj ):
134249 # Referenced object has a docstring
135250 autosum += [" %s%s" % (prefix , param )]
136251 else :
@@ -250,7 +365,8 @@ def __str__(self, indent=0, func_role="obj"):
250365 'notes' : self ._str_section ('Notes' ),
251366 'references' : self ._str_references (),
252367 'examples' : self ._str_examples (),
253- 'attributes' : self ._str_member_list ('Attributes' ),
368+ 'attributes' : self ._str_param_list ('Attributes' ,
369+ fake_autosummary = True ),
254370 'methods' : self ._str_member_list ('Methods' ),
255371 }
256372 ns = dict ((k , '\n ' .join (v )) for k , v in ns .items ())
0 commit comments