Repository: mosaicml/composer

Issue:
Docs Nit: Hide the base class when the base is `object`
If the base class is `object`, then let's not show that in the docs build. We should be able to adjust a setting or use a hook in `conf.py`.

_Originally posted by @ravi-mosaicml in https://github.com/mosaicml/composer/pull/632#discussion_r817238607_


Discussion:

Resolving patch:
diff --git a/docs/source/conf.py b/docs/source/conf.py
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -18,9 +18,12 @@
 from typing import Any, List, Optional, Tuple, Type, Union, Dict
 import json
 
+import torch.nn
+
 import sphinx.application
 import sphinx.ext.autodoc
 import sphinx.util.logging
+from sphinx.ext.autodoc import ClassDocumenter, _
 import yahp as hp
 
 sys.path.insert(0, os.path.abspath('..'))
@@ -125,14 +128,14 @@
 autodoc_default_options = {
     # don't document the forward() method. Because of how torch.nn.Module.forward is defined in the
     # base class, sphinx does not realize that forward overrides an inherited method.
-    'exclude-members': 'forward, hparams_registry'
+    'exclude-members': 'hparams_registry'
 }
 autodoc_inherit_docstrings = False
 
-# Monkeypatch yahp so we don't document the hparams registry
-
+# Monkeypatch some objects as to exclude their docstrings
 hp.Hparams.__doc__ = ""
 hp.Hparams.initialize_object.__doc__ = ""
+torch.nn.Module.forward.__doc__ = ""
 
 pygments_style = "manni"
 pygments_dark_style = "monokai"
@@ -391,8 +394,36 @@ def get_algorithms_metadata() -> Dict[str, Dict[str, str]]:
 
 html_context = {'metadata': get_algorithms_metadata()}
 
+# ClassDocumenter.add_directive_header uses ClassDocumenter.add_line to
+#   write the class documentation.
+# We'll monkeypatch the add_line method and intercept lines that begin
+#   with "Bases:".
+# In order to minimize the risk of accidentally intercepting a wrong line,
+#   we'll apply this patch inside of the add_directive_header method.
+# From https://stackoverflow.com/questions/46279030/how-can-i-prevent-sphinx-from-listing-object-as-a-base-class
+add_line = ClassDocumenter.add_line
+line_to_delete = _('Bases: %s') % u':py:class:`object`'
+
+def add_line_no_object_base(self, text, *args, **kwargs):
+    if text.strip() == line_to_delete:
+        return
+
+    add_line(self, text, *args, **kwargs)
+
+add_directive_header = ClassDocumenter.add_directive_header
+
+def add_directive_header_no_object_base(self, *args, **kwargs):
+    self.add_line = add_line_no_object_base.__get__(self)
+
+    result = add_directive_header(self, *args, **kwargs)
+
+    del self.add_line
+
+    return result
+
+ClassDocumenter.add_directive_header = add_directive_header_no_object_base
 
 def setup(app: sphinx.application.Sphinx):
     app.connect('autodoc-skip-member', skip_redundant_namedtuple_attributes)
     app.connect('autodoc-process-docstring', add_module_summary_tables)
-    app.connect('source-read', rstjinja)
\ No newline at end of file
+    app.connect('source-read', rstjinja)
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -78,7 +78,8 @@ def package_files(directory: str):
     'pytest-timeout>=1.4.2',
     'pyright==1.1.224.post1',
     'recommonmark==0.7.1',
-    'sphinx>=4.2.0',
+    'sphinx>=4.4.0',
+    'docutils>=0.17',
     'sphinx_copybutton==0.5.0',
     'sphinx_markdown_tables==0.0.15',
     'sphinx-argparse==0.3.1',


Test patch: