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.

Functions

-
- 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