Skip to content

Commit 640f168

Browse files
committed
Replace custom autodoc parser with a dedicated directive
1 parent 90c5fd0 commit 640f168

File tree

5 files changed

+40
-68
lines changed

5 files changed

+40
-68
lines changed

.github/workflows/linkcheck.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
python-version: "3.12"
2828

2929
- name: Install deps
30-
run: pip install -r docs/requirements.txt
30+
run: pip install . -r docs/requirements.txt
3131

3232
- name: make linkcheck
3333
run: |

.readthedocs.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ build:
1414

1515
python:
1616
install:
17+
- path: .
1718
- requirements: docs/requirements.txt

docs/extensions/serverprocess_documenter.py

Lines changed: 36 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,56 @@
11
"""
2-
A modified version of https://github.com/jupyterhub/autodoc-traits/tree/1.2.2
3-
for documenting trait fields that are used to configure another object, but
4-
where the traitlet cannot be set directly.
5-
6-
This is used to generate the Server Process options documentation:
2+
A custom Sphinx directive to generate the Server Process options documentation:
73
https://github.com/jupyterhub/jupyter-server-proxy/blob/main/docs/source/server-process.md
84
"""
95

6+
import importlib
7+
from textwrap import dedent
8+
9+
from docutils import nodes
1010
from sphinx.application import Sphinx
11-
from sphinx.ext.autodoc import (
12-
SUPPRESS,
13-
AttributeDocumenter,
14-
ClassDocumenter,
15-
ObjectMember,
16-
)
11+
from sphinx.util.docutils import SphinxDirective
1712
from sphinx.util.typing import ExtensionMetadata
18-
from traitlets import MetaHasTraits, TraitType, Undefined
19-
20-
21-
class ServerProcessConfigurableDocumenter(ClassDocumenter):
22-
"""
23-
A modified version of autodoc_traits.ConfigurableDocumenter that only documents
24-
the traits in this class, not the inherited traits.
25-
https://github.com/jupyterhub/autodoc-traits/blob/1.2.2/autodoc_traits.py#L20-L122
26-
"""
27-
28-
objtype = "serverprocessconfigurable"
29-
directivetype = "class"
30-
priority = 100 # higher priority than ClassDocumenter's 10
31-
32-
@classmethod
33-
def can_document_member(cls, member, membername, isattr, parent):
34-
return isinstance(member, MetaHasTraits)
35-
36-
def get_object_members(self, want_all):
37-
"""
38-
Only document members in this class
39-
"""
40-
config_trait_members = self.object.class_traits(config=True).items()
41-
members = [ObjectMember(name, trait) for (name, trait) in config_trait_members]
42-
return False, members
13+
from traitlets import Undefined
4314

44-
def should_suppress_directive_header():
45-
return True
4615

47-
def add_directive_header(self, sig):
48-
print(f"{sig=}")
49-
self.options.annotation = SUPPRESS
50-
super().add_directive_header(sig)
16+
class ServerProcessDirective(SphinxDirective):
17+
"""A directive to say hello!"""
5118

19+
required_arguments = 2
5220

53-
class ServerProcessTraitDocumenter(AttributeDocumenter):
54-
"""
55-
A modified version of autodoc_traits.TraitDocumenter that omits the c.ClassName prefix
56-
https://github.com/jupyterhub/autodoc-traits/blob/1.2.2/autodoc_traits.py#L125-L203
57-
"""
21+
def run(self) -> list[nodes.Node]:
22+
module = importlib.import_module(self.arguments[0], ".")
23+
cls = getattr(module, self.arguments[1])
24+
config_trait_members = cls.class_traits(config=True).items()
5825

59-
objtype = "serverprocesstrait"
60-
directivetype = "attribute"
61-
priority = 100 # AttributeDocumenter has 10
62-
member_order = 0 # AttributeDocumenter has 60
26+
doc = []
6327

64-
@classmethod
65-
def can_document_member(cls, member, membername, isattr, parent):
66-
return isinstance(member, TraitType)
28+
for name, trait in config_trait_members:
29+
default_value = trait.default_value
30+
if default_value is Undefined:
31+
default_value = ""
32+
else:
33+
default_value = repr(default_value)
34+
traitlets_type = trait.__class__.__name__
6735

68-
def add_directive_header(self, sig):
69-
default_value = self.object.default_value
70-
if default_value is Undefined:
71-
default_value = ""
72-
else:
73-
default_value = repr(default_value)
36+
help = self.parse_text_to_nodes(dedent(trait.metadata.get("help", "")))
7437

75-
traitlets_type = self.object.__class__.__name__
76-
self.options.annotation = f"{traitlets_type}({default_value})"
77-
super().add_directive_header(sig)
38+
definition = nodes.definition_list_item(
39+
"",
40+
nodes.term(
41+
"",
42+
"",
43+
nodes.strong(text=f"{name}"),
44+
nodes.emphasis(text=f" {traitlets_type}({default_value})"),
45+
),
46+
nodes.definition("", *help),
47+
)
48+
doc.append(nodes.definition_list("", definition))
49+
return doc
7850

7951

8052
def setup(app: Sphinx) -> ExtensionMetadata:
81-
app.setup_extension("sphinx.ext.autodoc")
82-
app.add_autodocumenter(ServerProcessConfigurableDocumenter)
83-
app.add_autodocumenter(ServerProcessTraitDocumenter)
53+
app.add_directive("serverprocess", ServerProcessDirective)
8454
return {
8555
"version": "0.1",
8656
"parallel_read_safe": True,

docs/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
myst-parser
2+
sphinx>=7.4
23
sphinx-autobuild
34
sphinx-book-theme
45
sphinx-copybutton

docs/source/server-process.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pairs.
1717

1818
```{eval-rst}
1919
20-
.. autoserverprocessconfigurable:: jupyter_server_proxy.config.ServerProcess
20+
.. serverprocess:: jupyter_server_proxy.config ServerProcess
2121
```
2222

2323
## Specifying config via traitlets

0 commit comments

Comments
 (0)