mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 06:35:12 +00:00
Add option for enable/disable enum members in docstring. (#2768)
* Add option for enable/disable enum members in docstring * Add tests for disable enum members docstring option * Add docstring options to documentation * style: pre-commit fixes * Fix typos in documentation * Improve documentation wording * Apply suggestions by @Skylion007 Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ralf W. Grosse-Kunstleve <rwgk@google.com>
This commit is contained in:
parent
65374c8e62
commit
00126859a5
@ -324,6 +324,15 @@ The class ``options`` allows you to selectively suppress auto-generated signatur
|
|||||||
m.def("add", [](int a, int b) { return a + b; }, "A function which adds two numbers");
|
m.def("add", [](int a, int b) { return a + b; }, "A function which adds two numbers");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pybind11 also appends all members of an enum to the resulting enum docstring.
|
||||||
|
This default behavior can be disabled by using the ``disable_enum_members_docstring()``
|
||||||
|
function of the ``options`` class.
|
||||||
|
|
||||||
|
With ``disable_user_defined_docstrings()`` all user defined docstrings of
|
||||||
|
``module_::def()``, ``class_::def()`` and ``enum_()`` are disabled, but the
|
||||||
|
function signatures and enum members are included in the docstring, unless they
|
||||||
|
are disabled separately.
|
||||||
|
|
||||||
Note that changes to the settings affect only function bindings created during the
|
Note that changes to the settings affect only function bindings created during the
|
||||||
lifetime of the ``options`` instance. When it goes out of scope at the end of the module's init function,
|
lifetime of the ``options`` instance. When it goes out of scope at the end of the module's init function,
|
||||||
the default settings are restored to prevent unwanted side effects.
|
the default settings are restored to prevent unwanted side effects.
|
||||||
|
@ -47,6 +47,16 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options &disable_enum_members_docstring() & {
|
||||||
|
global_state().show_enum_members_docstring = false;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
options &enable_enum_members_docstring() & {
|
||||||
|
global_state().show_enum_members_docstring = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// Getter methods (return the global state):
|
// Getter methods (return the global state):
|
||||||
|
|
||||||
static bool show_user_defined_docstrings() {
|
static bool show_user_defined_docstrings() {
|
||||||
@ -55,6 +65,10 @@ public:
|
|||||||
|
|
||||||
static bool show_function_signatures() { return global_state().show_function_signatures; }
|
static bool show_function_signatures() { return global_state().show_function_signatures; }
|
||||||
|
|
||||||
|
static bool show_enum_members_docstring() {
|
||||||
|
return global_state().show_enum_members_docstring;
|
||||||
|
}
|
||||||
|
|
||||||
// This type is not meant to be allocated on the heap.
|
// This type is not meant to be allocated on the heap.
|
||||||
void *operator new(size_t) = delete;
|
void *operator new(size_t) = delete;
|
||||||
|
|
||||||
@ -63,6 +77,8 @@ private:
|
|||||||
bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings.
|
bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings.
|
||||||
bool show_function_signatures = true; //< Include auto-generated function signatures
|
bool show_function_signatures = true; //< Include auto-generated function signatures
|
||||||
// in docstrings.
|
// in docstrings.
|
||||||
|
bool show_enum_members_docstring = true; //< Include auto-generated member list in enum
|
||||||
|
// docstrings.
|
||||||
};
|
};
|
||||||
|
|
||||||
static state &global_state() {
|
static state &global_state() {
|
||||||
|
@ -1972,29 +1972,35 @@ struct enum_base {
|
|||||||
name("name"),
|
name("name"),
|
||||||
is_method(m_base));
|
is_method(m_base));
|
||||||
|
|
||||||
m_base.attr("__doc__") = static_property(
|
if (options::show_enum_members_docstring()) {
|
||||||
cpp_function(
|
m_base.attr("__doc__") = static_property(
|
||||||
[](handle arg) -> std::string {
|
cpp_function(
|
||||||
std::string docstring;
|
[](handle arg) -> std::string {
|
||||||
dict entries = arg.attr("__entries");
|
std::string docstring;
|
||||||
if (((PyTypeObject *) arg.ptr())->tp_doc) {
|
dict entries = arg.attr("__entries");
|
||||||
docstring += std::string(((PyTypeObject *) arg.ptr())->tp_doc) + "\n\n";
|
if (((PyTypeObject *) arg.ptr())->tp_doc) {
|
||||||
}
|
docstring += std::string(
|
||||||
docstring += "Members:";
|
reinterpret_cast<PyTypeObject *>(arg.ptr())->tp_doc);
|
||||||
for (auto kv : entries) {
|
docstring += "\n\n";
|
||||||
auto key = std::string(pybind11::str(kv.first));
|
|
||||||
auto comment = kv.second[int_(1)];
|
|
||||||
docstring += "\n\n " + key;
|
|
||||||
if (!comment.is_none()) {
|
|
||||||
docstring += " : " + (std::string) pybind11::str(comment);
|
|
||||||
}
|
}
|
||||||
}
|
docstring += "Members:";
|
||||||
return docstring;
|
for (auto kv : entries) {
|
||||||
},
|
auto key = std::string(pybind11::str(kv.first));
|
||||||
name("__doc__")),
|
auto comment = kv.second[int_(1)];
|
||||||
none(),
|
docstring += "\n\n ";
|
||||||
none(),
|
docstring += key;
|
||||||
"");
|
if (!comment.is_none()) {
|
||||||
|
docstring += " : ";
|
||||||
|
docstring += pybind11::str(comment).cast<std::string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return docstring;
|
||||||
|
},
|
||||||
|
name("__doc__")),
|
||||||
|
none(),
|
||||||
|
none(),
|
||||||
|
"");
|
||||||
|
}
|
||||||
|
|
||||||
m_base.attr("__members__") = static_property(cpp_function(
|
m_base.attr("__members__") = static_property(cpp_function(
|
||||||
[](handle arg) -> dict {
|
[](handle arg) -> dict {
|
||||||
|
@ -85,4 +85,57 @@ TEST_SUBMODULE(docstring_options, m) {
|
|||||||
&DocstringTestFoo::setValue,
|
&DocstringTestFoo::setValue,
|
||||||
"This is a property docstring");
|
"This is a property docstring");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
enum class DocstringTestEnum1 { Member1, Member2 };
|
||||||
|
|
||||||
|
py::enum_<DocstringTestEnum1>(m, "DocstringTestEnum1", "Enum docstring")
|
||||||
|
.value("Member1", DocstringTestEnum1::Member1)
|
||||||
|
.value("Member2", DocstringTestEnum1::Member2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
py::options options;
|
||||||
|
options.enable_enum_members_docstring();
|
||||||
|
|
||||||
|
enum class DocstringTestEnum2 { Member1, Member2 };
|
||||||
|
|
||||||
|
py::enum_<DocstringTestEnum2>(m, "DocstringTestEnum2", "Enum docstring")
|
||||||
|
.value("Member1", DocstringTestEnum2::Member1)
|
||||||
|
.value("Member2", DocstringTestEnum2::Member2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
py::options options;
|
||||||
|
options.disable_enum_members_docstring();
|
||||||
|
|
||||||
|
enum class DocstringTestEnum3 { Member1, Member2 };
|
||||||
|
|
||||||
|
py::enum_<DocstringTestEnum3>(m, "DocstringTestEnum3", "Enum docstring")
|
||||||
|
.value("Member1", DocstringTestEnum3::Member1)
|
||||||
|
.value("Member2", DocstringTestEnum3::Member2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
py::options options;
|
||||||
|
options.disable_user_defined_docstrings();
|
||||||
|
|
||||||
|
enum class DocstringTestEnum4 { Member1, Member2 };
|
||||||
|
|
||||||
|
py::enum_<DocstringTestEnum4>(m, "DocstringTestEnum4", "Enum docstring")
|
||||||
|
.value("Member1", DocstringTestEnum4::Member1)
|
||||||
|
.value("Member2", DocstringTestEnum4::Member2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
py::options options;
|
||||||
|
options.disable_user_defined_docstrings();
|
||||||
|
options.disable_enum_members_docstring();
|
||||||
|
|
||||||
|
enum class DocstringTestEnum5 { Member1, Member2 };
|
||||||
|
|
||||||
|
py::enum_<DocstringTestEnum5>(m, "DocstringTestEnum5", "Enum docstring")
|
||||||
|
.value("Member1", DocstringTestEnum5::Member1)
|
||||||
|
.value("Member2", DocstringTestEnum5::Member2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,3 +39,26 @@ def test_docstring_options():
|
|||||||
# Suppression of user-defined docstrings for non-function objects
|
# Suppression of user-defined docstrings for non-function objects
|
||||||
assert not m.DocstringTestFoo.__doc__
|
assert not m.DocstringTestFoo.__doc__
|
||||||
assert not m.DocstringTestFoo.value_prop.__doc__
|
assert not m.DocstringTestFoo.value_prop.__doc__
|
||||||
|
|
||||||
|
# Check existig behaviour of enum docstings
|
||||||
|
assert (
|
||||||
|
m.DocstringTestEnum1.__doc__
|
||||||
|
== "Enum docstring\n\nMembers:\n\n Member1\n\n Member2"
|
||||||
|
)
|
||||||
|
|
||||||
|
# options.enable_enum_members_docstring()
|
||||||
|
assert (
|
||||||
|
m.DocstringTestEnum2.__doc__
|
||||||
|
== "Enum docstring\n\nMembers:\n\n Member1\n\n Member2"
|
||||||
|
)
|
||||||
|
|
||||||
|
# options.disable_enum_members_docstring()
|
||||||
|
assert m.DocstringTestEnum3.__doc__ == "Enum docstring"
|
||||||
|
|
||||||
|
# options.disable_user_defined_docstrings()
|
||||||
|
assert m.DocstringTestEnum4.__doc__ == "Members:\n\n Member1\n\n Member2"
|
||||||
|
|
||||||
|
# options.disable_user_defined_docstrings()
|
||||||
|
# options.disable_enum_members_docstring()
|
||||||
|
# When all options are disabled, no docstring (instead of an empty one) should be generated
|
||||||
|
assert m.DocstringTestEnum5.__doc__ is None
|
||||||
|
Loading…
Reference in New Issue
Block a user