From 77cbb593c6ec181ec5ef28cb723f7f9f651a2337 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Vladim=C3=ADr=20Vondru=C5=A1?=
Date: Tue, 27 Aug 2019 13:14:21 +0200
Subject: [PATCH] documentation/python: parse more than just first docstring
paragraph.
Next step is to allow those to get processed using plugins.
---
doc/documentation/python.rst | 9 ++++---
documentation/python.py | 27 +++++++++++--------
.../test_python/content/content.html | 14 ++++++++++
.../test_python/content/content/__init__.py | 10 +++++++
.../test_python/inspect_annotations/math.html | 15 +++++++++--
.../inspect_annotations/math36.html | 15 +++++++++--
.../inspect_annotations/math373.html | 15 +++++++++--
7 files changed, 84 insertions(+), 21 deletions(-)
diff --git a/doc/documentation/python.rst b/doc/documentation/python.rst
index d21c5eb9..193f00d7 100644
--- a/doc/documentation/python.rst
+++ b/doc/documentation/python.rst
@@ -455,11 +455,14 @@ all found submodules in it are ignored.
The first paragraph of a module-level, class-level and function-level docstring
is used as a doc summary, copied as-is to the output without formatting it in
-any way.
+any way. What follows is put (again without formatting) paragraph-by-paragraph
+into detailed docs.
.. code:: py
- """Module summary"""
+ """Module summary
+
+ First paragraph of module detailed docs."""
class Foo:
"""Class summary"""
@@ -471,8 +474,6 @@ any way.
With the current approach, there are a few limitations:
- - Everything after the first paragraph is ignored (there's no way to have
- detailed documentation yet)
- Class and module-level variables can't have a docstring attached due to
how Python works
- Because not every Python API can be documented using docstrings, the
diff --git a/documentation/python.py b/documentation/python.py
index 6c70b9f3..4a49bb0e 100755
--- a/documentation/python.py
+++ b/documentation/python.py
@@ -776,6 +776,13 @@ def format_value(state: State, referrer_path: List[str], value: str) -> Optional
else:
return None
+# Assumes the content is a bunch of raw paragraphs, wrapping them in one
+# by one
+def split_summary_content(doc: str) -> str:
+ summary, _, content = doc.partition('\n\n')
+ content = content.strip()
+ return summary, ('\n'.join(['
{}
'.format(p) for p in content.split('\n\n')]) if content else None)
+
def extract_summary(state: State, external_docs, path: List[str], doc: str) -> str:
# Prefer external docs, if available
path_str = '.'.join(path)
@@ -793,20 +800,17 @@ def extract_docs(state: State, external_docs, path: List[str], doc: str) -> Tupl
else:
external_doc_entry = None
+ # some modules (xml.etree) have None as a docstring :(
+ # TODO: render as rst (config option for that)
+ summary, content = split_summary_content(html.escape(inspect.cleandoc(doc or '')))
+
# Summary. Prefer external docs, if available
if external_doc_entry and external_doc_entry['summary']:
summary = render_inline_rst(state, external_doc_entry['summary'])
- else:
- # some modules (xml.etree) have None as a docstring :(
- # TODO: render as rst (config option for that)
- summary = html.escape(inspect.cleandoc(doc or '').partition('\n\n')[0])
# Content
if external_doc_entry and external_doc_entry['content']:
content = render_rst(state, external_doc_entry['content'])
- else:
- # TODO: extract more than just a summary from the docstring
- content = None
# Mark the docs as used (so it can warn about unused docs at the end)
if external_doc_entry: external_doc_entry['used'] = True
@@ -980,7 +984,11 @@ def extract_enum_doc(state: State, entry: Empty):
elif state.config['PYBIND11_COMPATIBILITY']:
assert hasattr(entry.object, '__members__')
- out.summary, out.content = extract_docs(state, state.enum_docs, entry.path, entry.object.__doc__)
+ # Pybind 2.4 puts enum value docs inside the docstring. We don't parse
+ # that yet and it adds clutter to the output (especially if the values
+ # aren't documented), so cut that away
+ # TODO: implement this
+ out.summary, out.content = extract_docs(state, state.enum_docs, entry.path, entry.object.__doc__.partition('\n\n')[0])
out.has_details = bool(out.content)
out.base = None
@@ -989,9 +997,6 @@ def extract_enum_doc(state: State, entry: Empty):
value. name = name
value.id = state.config['ID_FORMATTER'](EntryType.ENUM_VALUE, entry.path[-1:] + [name])
value.value = int(v)
- # TODO: once https://github.com/pybind/pybind11/pull/1160 is
- # released, extract from class docs (until then the class
- # docstring is duplicated here, which is useless)
# TODO: external summary for enum values
value.summary = ''
out.values += [value]
diff --git a/documentation/test_python/content/content.html b/documentation/test_python/content/content.html
index 58fb5917..9ba7c10a 100644
--- a/documentation/test_python/content/content.html
+++ b/documentation/test_python/content/content.html
@@ -83,6 +83,10 @@ doesn't add any detailed block.
def foo_with_details(a, b)
This overwrites the docstring for content.foo_with_details()
.
+
+ def full_docstring(a, b) -> str
+
+ This function has a full docstring.
def function_with_summary()
@@ -151,6 +155,16 @@ doesn't add any detailed block.
This overwrites the docstring for content.foo_with_details()
.
Detailed docs for this function
+
+
+
+ def content.full_docstring(a, b) -> str
+
+
This function has a full docstring.
+
It takes one parameter and also another. The details are in two paragraphs,
+each wrapped in its own `<p>`, but not additionally formatted or parsed in any
+way.
+
Like this.
diff --git a/documentation/test_python/content/content/__init__.py b/documentation/test_python/content/content/__init__.py
index be50c537..8f8becbf 100644
--- a/documentation/test_python/content/content/__init__.py
+++ b/documentation/test_python/content/content/__init__.py
@@ -69,6 +69,16 @@ def param_docs(a: int, b, c: float) -> str:
def param_docs_wrong(a, b):
"""Should give warnings"""
+def full_docstring(a, b) -> str:
+ """This function has a full docstring.
+
+ It takes one parameter and also another. The details are in two paragraphs,
+ each wrapped in its own `
`, but not additionally formatted or parsed in any
+ way.
+
+ Like this.
+ """
+
CONSTANT: float = 3.14
DATA_WITH_DETAILS: str = 'heyoo'
diff --git a/documentation/test_python/inspect_annotations/math.html b/documentation/test_python/inspect_annotations/math.html
index 222af053..38078950 100644
--- a/documentation/test_python/inspect_annotations/math.html
+++ b/documentation/test_python/inspect_annotations/math.html
@@ -42,13 +42,24 @@ defined by the C standard.
def pow(x, y, /)
Return x**y (x to the power of y).
-
- def log(...)
+
+ def log(...)
log(x, [base=math.e])
Return the logarithm of x to the given base.
+
+ Function documentation
+
+
+ def math.log(...)
+
+
log(x, [base=math.e])
+Return the logarithm of x to the given base.
+
If the base not specified, returns the natural logarithm (base e) of x.
+
+
diff --git a/documentation/test_python/inspect_annotations/math36.html b/documentation/test_python/inspect_annotations/math36.html
index 66f3dcd5..333792b0 100644
--- a/documentation/test_python/inspect_annotations/math36.html
+++ b/documentation/test_python/inspect_annotations/math36.html
@@ -38,12 +38,23 @@ mathematical functions defined by the C standard.
- -
- def log(...)
+
-
+ def log(...)
- log(x[, base])
+
+ Function documentation
+
+
+ def math.log(...)
+
+
log(x[, base])
+
Return the logarithm of x to the given base.
+If the base not specified, returns the natural logarithm (base e) of x.
+
+
diff --git a/documentation/test_python/inspect_annotations/math373.html b/documentation/test_python/inspect_annotations/math373.html
index ebfe209d..660b6ce6 100644
--- a/documentation/test_python/inspect_annotations/math373.html
+++ b/documentation/test_python/inspect_annotations/math373.html
@@ -42,13 +42,24 @@ mathematical functions defined by the C standard.
def pow(x, y, /)
Return x**y (x to the power of y).
-
- def log(...)
+
+ def log(...)
log(x, [base=math.e])
Return the logarithm of x to the given base.
+
+ Function documentation
+
+
+ def math.log(...)
+
+
log(x, [base=math.e])
+Return the logarithm of x to the given base.
+
If the base not specified, returns the natural logarithm (base e) of x.
+
+
--
2.30.2