Skip to content

Commit 87296fb

Browse files
committed
Can disable the section headings in docstrings
1 parent 27b377f commit 87296fb

File tree

6 files changed

+82
-16
lines changed

6 files changed

+82
-16
lines changed

.github/CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ The valid options are:
9393
* `-DPYBIND11_NOPYTHON=ON`: Disable all Python searching (disables tests)
9494
* `-DBUILD_TESTING=ON`: Enable the tests
9595
* `-DDOWNLOAD_CATCH=ON`: Download catch to build the C++ tests
96-
* `-DOWNLOAD_EIGEN=ON`: Download Eigen for the NumPy tests
96+
* `-DDOWNLOAD_EIGEN=ON`: Download Eigen for the NumPy tests
9797
* `-DPYBIND11_INSTALL=ON/OFF`: Enable the install target (on by default for the
9898
master project)
9999
* `-DUSE_PYTHON_INSTALL_DIR=ON`: Try to install into the python dir

docs/advanced/misc.rst

+35-1
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,43 @@ 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+
362+
| A function which adds two numbers.
363+
|
364+
| Internally, a simple addition is performed.
365+
| Both numbers can be None, and None will be returned.
366+
367+
Not every overload must supply a docstring.
368+
You may find it easier for a single overload to supply the entire docstring.
335369

336370
.. [#f4] http://www.sphinx-doc.org
337371
.. [#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

+10-8
Original file line numberDiff line numberDiff line change
@@ -458,12 +458,15 @@ class cpp_function : public function {
458458
if (it->next != nullptr) signatures += " \\";
459459
signatures += "\n";
460460
}
461-
signatures += "\nOverloaded function.\n\n";
461+
if (options::show_section_headings())
462+
signatures += "\nOverloaded function.\n\n";
462463
}
463464
// Then specific overload signatures
464465
bool first_user_def = true;
466+
const bool show_signature_headings = options::show_function_signatures()
467+
&& options::show_section_headings();
465468
for (auto it = chain_start; it != nullptr; it = it->next) {
466-
if (options::show_function_signatures()) {
469+
if (show_signature_headings) {
467470
if (index > 0) signatures += "\n";
468471
if (chain)
469472
signatures += std::to_string(++index) + ". ";
@@ -474,13 +477,12 @@ class cpp_function : public function {
474477
if (it->doc && strlen(it->doc) > 0 && options::show_user_defined_docstrings()) {
475478
// If we're appending another docstring, and aren't printing function signatures, we
476479
// need to append a newline first:
477-
if (!options::show_function_signatures()) {
478-
if (first_user_def) first_user_def = false;
479-
else signatures += "\n";
480-
}
481-
if (options::show_function_signatures()) signatures += "\n";
480+
if (!show_signature_headings && first_user_def)
481+
first_user_def = false;
482+
else
483+
signatures += "\n";
482484
signatures += it->doc;
483-
if (options::show_function_signatures()) signatures += "\n";
485+
if (show_signature_headings) signatures += "\n";
484486
}
485487
}
486488

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

+12
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ def test_init_factory_signature(msg):
105105
""" # noqa: E501 line too long
106106
)
107107

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

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

0 commit comments

Comments
 (0)