297
297
'pd.options.display.encoding="utf8"'
298
298
]
299
299
300
+
301
+ # Add custom Documenter to handle attributes/methods of an AccessorProperty
302
+ # eg pandas.Series.str and pandas.Series.dt (see GH9322)
303
+
304
+ from sphinx .util import rpartition
305
+ from sphinx .ext .autodoc import Documenter , MethodDocumenter , AttributeDocumenter
306
+
307
+
308
+ class AccessorLevelDocumenter (Documenter ):
309
+ """
310
+ Specialized Documenter subclass for objects on accessor level (methods,
311
+ attributes).
312
+ """
313
+
314
+ # This is the simple straightforward version
315
+ # modname is None, base the last elements (eg 'hour')
316
+ # and path the part before (eg 'Series.dt')
317
+ # def resolve_name(self, modname, parents, path, base):
318
+ # modname = 'pandas'
319
+ # mod_cls = path.rstrip('.')
320
+ # mod_cls = mod_cls.split('.')
321
+ #
322
+ # return modname, mod_cls + [base]
323
+
324
+ def resolve_name (self , modname , parents , path , base ):
325
+ if modname is None :
326
+ if path :
327
+ mod_cls = path .rstrip ('.' )
328
+ else :
329
+ mod_cls = None
330
+ # if documenting a class-level object without path,
331
+ # there must be a current class, either from a parent
332
+ # auto directive ...
333
+ mod_cls = self .env .temp_data .get ('autodoc:class' )
334
+ # ... or from a class directive
335
+ if mod_cls is None :
336
+ mod_cls = self .env .temp_data .get ('py:class' )
337
+ # ... if still None, there's no way to know
338
+ if mod_cls is None :
339
+ return None , []
340
+ # HACK: this is added in comparison to ClassLevelDocumenter
341
+ # mod_cls still exists of class.accessor, so an extra
342
+ # rpartition is needed
343
+ modname , accessor = rpartition (mod_cls , '.' )
344
+ modname , cls = rpartition (modname , '.' )
345
+ parents = [cls , accessor ]
346
+ # if the module name is still missing, get it like above
347
+ if not modname :
348
+ modname = self .env .temp_data .get ('autodoc:module' )
349
+ if not modname :
350
+ modname = self .env .temp_data .get ('py:module' )
351
+ # ... else, it stays None, which means invalid
352
+ return modname , parents + [base ]
353
+
354
+
355
+ class AccessorAttributeDocumenter (AccessorLevelDocumenter , AttributeDocumenter ):
356
+
357
+ objtype = 'accessorattribute'
358
+ directivetype = 'attribute'
359
+
360
+
361
+ class AccessorMethodDocumenter (AccessorLevelDocumenter , MethodDocumenter ):
362
+
363
+ objtype = 'accessormethod'
364
+ directivetype = 'method'
365
+
366
+
300
367
# remove the docstring of the flags attribute (inherited from numpy ndarray)
301
368
# because these give doc build errors (see GH issue 5331)
302
369
def remove_flags_docstring (app , what , name , obj , options , lines ):
@@ -305,3 +372,5 @@ def remove_flags_docstring(app, what, name, obj, options, lines):
305
372
306
373
def setup (app ):
307
374
app .connect ("autodoc-process-docstring" , remove_flags_docstring )
375
+ app .add_autodocumenter (AccessorAttributeDocumenter )
376
+ app .add_autodocumenter (AccessorMethodDocumenter )
0 commit comments