Skip to content

Commit 408b5c8

Browse files
committed
Can disable the section headings in docstrings
1 parent 958c114 commit 408b5c8

File tree

6 files changed

+84
-15
lines changed

6 files changed

+84
-15
lines changed

Diff for: .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

Diff for: 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

Diff for: 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() {

Diff for: include/pybind11/pybind11.h

+14-7
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,16 @@ class cpp_function : public function {
414414
if (it->next != nullptr) signatures += " \\";
415415
signatures += "\n";
416416
}
417-
signatures += "Overloaded function.\n\n";
417+
if (options::show_section_headings()) {
418+
signatures += "Overloaded function.\n\n";
419+
}
418420
}
419421
// Then specific overload signatures
420422
bool first_user_def = true;
423+
const bool show_signature_headings = options::show_function_signatures()
424+
&& options::show_section_headings();
421425
for (auto it = chain_start; it != nullptr; it = it->next) {
422-
if (options::show_function_signatures()) {
426+
if (show_signature_headings) {
423427
if (index > 0) signatures += "\n";
424428
if (chain)
425429
signatures += std::to_string(++index) + ". ";
@@ -430,13 +434,16 @@ class cpp_function : public function {
430434
if (it->doc && strlen(it->doc) > 0 && options::show_user_defined_docstrings()) {
431435
// If we're appending another docstring, and aren't printing function signatures, we
432436
// need to append a newline first:
433-
if (!options::show_function_signatures()) {
434-
if (first_user_def) first_user_def = false;
435-
else signatures += "\n";
437+
if (!show_signature_headings && first_user_def) {
438+
first_user_def = false;
439+
}
440+
else {
441+
signatures += "\n";
436442
}
437-
if (options::show_function_signatures()) signatures += "\n";
438443
signatures += it->doc;
439-
if (options::show_function_signatures()) signatures += "\n";
444+
if (show_signature_headings) {
445+
signatures += "\n";
446+
}
440447
}
441448
}
442449

Diff for: 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;

Diff for: 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)