Skip to content

Commit 27b6e44

Browse files
committed
Can disable the section headings in docstrings
1 parent b04b110 commit 27b6e44

File tree

5 files changed

+83
-14
lines changed

5 files changed

+83
-14
lines changed

docs/advanced/misc.rst

+34-1
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,42 @@ For example:
329329
|
330330
| Add two floating points numbers together.
331331
332-
Calling ``options.disable_function_signatures()``, as shown previously,
332+
Calling ``options.disable_function_signatures()`` as shown previously,
333333
will cause docstrings to be generated without the prepended function signatures
334334
and without the section headings.
335+
To disable only the sections headings, use ``options.disable_section_headings()``:
336+
337+
.. code-block:: cpp
338+
339+
PYBIND11_MODULE(example, m) {
340+
py::options options;
341+
options.disable_section_headings();
342+
343+
m.def("add", [](int a, int b)->int { return a + b; },
344+
"A function which adds two numbers.\n"); // Note the additional newline here.
345+
m.def("add", [](float a, float b)->float { return a + b; },
346+
"Internally, a simple addition is performed.");
347+
m.def("add", [](py::none a, py::none b)->py::none { return py::none(); },
348+
"Both numbers can be None, and None will be returned.");
349+
}
350+
351+
The above example would produce the following docstring:
352+
353+
.. code-block:: pycon
354+
355+
>>> help(example.add)
356+
357+
add(...)
358+
| add(arg0: int, arg1: int) -> int
359+
| add(arg0: float, arg1: float) -> float
360+
| add(arg0: None, arg1: None) -> None
361+
| A function which adds two numbers.
362+
|
363+
| Internally, a simple addition is performed.
364+
| Both numbers can be None, and None will be returned.
365+
366+
Not every overload must supply a docstring.
367+
You may find it easier for a single overload to supply the entire docstring.
335368

336369
.. [#f4] http://www.sphinx-doc.org
337370
.. [#f5] http://github.com/pybind/python_example

include/pybind11/options.h

+7
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,18 @@ class options {
3838

3939
options& enable_function_signatures() & { global_state().show_function_signatures = true; return *this; }
4040

41+
options& disable_section_headings() & { global_state().show_section_headings = false; return *this; }
42+
43+
options& enable_section_headings() & { global_state().show_section_headings = true; return *this; }
44+
4145
// Getter methods (return the global state):
4246

4347
static bool show_user_defined_docstrings() { return global_state().show_user_defined_docstrings; }
4448

4549
static bool show_function_signatures() { return global_state().show_function_signatures; }
4650

51+
static bool show_section_headings() { return global_state().show_section_headings; }
52+
4753
// This type is not meant to be allocated on the heap.
4854
void* operator new(size_t) = delete;
4955

@@ -52,6 +58,7 @@ class options {
5258
struct state {
5359
bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings.
5460
bool show_function_signatures = true; //< Include auto-generated function signatures in docstrings.
61+
bool show_section_headings = true; //< Include section headings in docstrings.
5562
};
5663

5764
static state &global_state() {

include/pybind11/pybind11.h

+14-7
Original file line numberDiff line numberDiff line change
@@ -413,12 +413,16 @@ class cpp_function : public function {
413413
signatures += it->signature;
414414
signatures += "\n";
415415
}
416-
signatures += "Overloaded function.\n\n";
416+
if (options::show_section_headings()) {
417+
signatures += "Overloaded function.\n\n";
418+
}
417419
}
418420
// Then specific overload signatures
419421
bool first_user_def = true;
422+
const bool show_signature_headings = options::show_function_signatures()
423+
&& options::show_section_headings();
420424
for (auto it = chain_start; it != nullptr; it = it->next) {
421-
if (options::show_function_signatures()) {
425+
if (show_signature_headings) {
422426
if (index > 0) signatures += "\n";
423427
if (chain)
424428
signatures += std::to_string(++index) + ". ";
@@ -429,13 +433,16 @@ class cpp_function : public function {
429433
if (it->doc && strlen(it->doc) > 0 && options::show_user_defined_docstrings()) {
430434
// If we're appending another docstring, and aren't printing function signatures, we
431435
// need to append a newline first:
432-
if (!options::show_function_signatures()) {
433-
if (first_user_def) first_user_def = false;
434-
else signatures += "\n";
436+
if (!show_signature_headings && first_user_def) {
437+
first_user_def = false;
438+
}
439+
else {
440+
signatures += "\n";
435441
}
436-
if (options::show_function_signatures()) signatures += "\n";
437442
signatures += it->doc;
438-
if (options::show_function_signatures()) signatures += "\n";
443+
if (show_signature_headings) {
444+
signatures += "\n";
445+
}
439446
}
440447
}
441448

tests/test_factory_constructors.cpp

+17-6
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,23 @@ TEST_SUBMODULE(factory_constructors, m) {
171171
.def(py::init([](py::handle, int v, py::handle) { return TestFactoryHelper::construct1(v); }))
172172
.def_readwrite("value", &TestFactory1::value)
173173
;
174-
py::class_<TestFactory2>(m, "TestFactory2")
175-
.def(py::init([](pointer_tag, int v) { return TestFactoryHelper::construct2(v); }))
176-
.def(py::init([](unique_ptr_tag, std::string v) { return TestFactoryHelper::construct2(v); }))
177-
.def(py::init([](move_tag) { return TestFactoryHelper::construct2(); }))
178-
.def_readwrite("value", &TestFactory2::value)
179-
;
174+
{
175+
py::options options;
176+
options.disable_section_headings();
177+
178+
py::class_<TestFactory2>(m, "TestFactory2")
179+
.def(
180+
py::init([](pointer_tag, int v) { return TestFactoryHelper::construct2(v); }),
181+
"This is one part of the docstring."
182+
)
183+
.def(py::init([](unique_ptr_tag, std::string v) { return TestFactoryHelper::construct2(v); }))
184+
.def(
185+
py::init([](move_tag) { return TestFactoryHelper::construct2(); }),
186+
"This is the other part of the docstring."
187+
)
188+
.def_readwrite("value", &TestFactory2::value)
189+
;
190+
}
180191

181192
// Stateful & reused:
182193
int c = 1;

tests/test_factory_constructors.py

+11
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,17 @@ def test_init_factory_signature(msg):
104104
""" # noqa: E501 line too long
105105
)
106106

107+
assert (
108+
msg(m.TestFactory2.__init__.__doc__)
109+
== """
110+
__init__(self: m.factory_constructors.TestFactory2, arg0: m.factory_constructors.tag.pointer_tag, arg1: int) -> None
111+
__init__(self: m.factory_constructors.TestFactory2, arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: str) -> None
112+
__init__(self: m.factory_constructors.TestFactory2, arg0: m.factory_constructors.tag.move_tag) -> None
113+
This is one part of the docstring.
114+
This is the other part of the docstring.
115+
""" # noqa: E501 line too long
116+
)
117+
107118

108119
def test_init_factory_casting():
109120
"""Tests py::init_factory() wrapper with various upcasting and downcasting returns"""

0 commit comments

Comments
 (0)