From 509b59614e74db3b207a91f5239191388d7c65fd Mon Sep 17 00:00:00 2001 From: Chip Kent Date: Wed, 16 Oct 2024 11:21:15 -0600 Subject: [PATCH 1/3] Upgraded sphinx version. --- sphinx/sphinx.gradle | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sphinx/sphinx.gradle b/sphinx/sphinx.gradle index 7042abd47fa..b7cd381870d 100644 --- a/sphinx/sphinx.gradle +++ b/sphinx/sphinx.gradle @@ -39,14 +39,9 @@ def sphinxDockerfile = tasks.register('sphinxDockerfile', Dockerfile) { environmentVariable 'DEEPHAVEN_PROPFILE', 'dh-defaults.prop' environmentVariable 'DEEPHAVEN_VERSION', project.version - // For the time being we lock the sphinx version to 7.1.2 - // This works around the bug described in - // https://github.com/sphinx-doc/sphinx/issues/11605 - // We should leave this here until 'breathe' updates their code to be - // compatible with the breaking sphinx change. runCommand '''set -eux; \\ mkdir /tmp/workspace; \\ - python -m pip install sphinx==7.1.2 sphinx-autodoc-typehints pyarrow protobuf grpcio bitstring /wheel/*.whl breathe furo + python -m pip install sphinx==8.1.3 sphinx-autodoc-typehints pyarrow protobuf grpcio bitstring /wheel/*.whl breathe furo ''' } From 81be3c767b85ed8c53c93d8f276d19749914b274 Mon Sep 17 00:00:00 2001 From: Chip Kent Date: Wed, 16 Oct 2024 11:22:06 -0600 Subject: [PATCH 2/3] Added a docs test package --- py/server/deephaven/testdocs.py | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 py/server/deephaven/testdocs.py diff --git a/py/server/deephaven/testdocs.py b/py/server/deephaven/testdocs.py new file mode 100644 index 00000000000..648266abe55 --- /dev/null +++ b/py/server/deephaven/testdocs.py @@ -0,0 +1,35 @@ + +"""A module with classes for testing the documentation generator.""" + +from typing import TypeVar, Generic + +T = TypeVar('T') +""" A type variable for use in generic classes. """ + +class GenericClass(Generic[T]): + """A generic class that takes a type parameter.""" + def __init__(self, value: T): + self.value = value + + def get_value(self) -> T: + """Return the value stored in the class.""" + return self.value + + def to_str(self, s: str) -> str: + """Return a string representation of the value stored in the class.""" + + return str(self.value) + s + +class ChildClass(GenericClass[str]): + """A child class of GenericClass that uses a string type parameter.""" + + def print_value(self): + """Print the value stored in the class.""" + print(self.get_value()) + +class Table(GenericClass[str]): + """A child class of GenericClass that uses a string type parameter.""" + + def print_value(self): + """Print the value stored in the class.""" + print(self.get_value()) \ No newline at end of file From 09a27dff4a8edd6f3485ebc2c86a6d9abbeec7b1 Mon Sep 17 00:00:00 2001 From: Chip Kent Date: Wed, 16 Oct 2024 11:24:28 -0600 Subject: [PATCH 3/3] Added an experimental documenter --- sphinx/source/conf.py | 18 +++++-- .../documenters/experimental_documenter.py | 47 +++++++++++++++++++ 2 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 sphinx/source/documenters/experimental_documenter.py diff --git a/sphinx/source/conf.py b/sphinx/source/conf.py index b735b38838d..51772ad5113 100644 --- a/sphinx/source/conf.py +++ b/sphinx/source/conf.py @@ -9,10 +9,10 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) + +import os +import sys +sys.path.insert(0, os.path.abspath('.') + "/documenters") # -- Project information ----------------------------------------------------- @@ -28,7 +28,7 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.todo', 'sphinx.ext.viewcode', "sphinx_autodoc_typehints"] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.todo', 'sphinx.ext.viewcode', "sphinx_autodoc_typehints", "experimental_documenter"] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -69,6 +69,14 @@ autodoc_typehints = 'none' autoclass_content = 'both' +autodoc_inherit_docstrings = True + +autodoc_default_options = { + 'inherited-members': True, + 'member-order': 'groupwise', +} + + ######################################################################################################################################################################### diff --git a/sphinx/source/documenters/experimental_documenter.py b/sphinx/source/documenters/experimental_documenter.py new file mode 100644 index 00000000000..19053d8835c --- /dev/null +++ b/sphinx/source/documenters/experimental_documenter.py @@ -0,0 +1,47 @@ +import inspect +from sphinx.ext.autodoc import ClassDocumenter + + +class ExperimentalDocumenter(ClassDocumenter): + # See: https://pydoc.dev/sphinx/latest/sphinx.ext.autodoc.ClassDocumenter.html?private=1 + + objtype = 'table' + directivetype = 'class' + priority = 10 # Higher than ClassDocumenter's priority (10) + + @classmethod + def can_document_member(cls, member, membername, isattr, parent): + # handle functions in the deephaven.testdocs module that are inherited + return ( + inspect.isfunction(member) + and member.__module__ == 'deephaven.testdocs' + and member.__qualname__.split('.')[0] != parent.object.__name__ + ) + + def process_doc(self, docstrings): + def class_details(member): + return (member, member.__module__, member.__name__, member.__qualname__, member.__class__, member.__bases__, + dir(member)) + + print(f"CALLING process_doc: {self.parent} {self.object} {docstrings}") + print(f"PARENT: {class_details(self.parent)}") + print(f"PARENT_PARENT: {class_details(self.parent.__bases__[0])}") + + orig_doc = list(super().process_doc(docstrings)) + new_doc = ["*** This is an inherited method ***", ""] + orig_doc + + print(f"DOCSTRINGS: {docstrings}") + print(f"ORIG_DOC: {orig_doc}") + print(f"NEW_DOC: {new_doc}") + + return new_doc + + +def setup(app): + app.add_autodocumenter(ExperimentalDocumenter) + + return { + 'version': '0.1', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + }