support docstrings in enum::value() (#1160)

This commit is contained in:
Wenzel Jakob 2017-11-16 22:24:36 +01:00 committed by GitHub
parent 0a0758ce3a
commit 6d19036cb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 9 deletions

View File

@ -18,6 +18,9 @@ v2.3.0 (Not yet released)
* Added support for write only properties. * Added support for write only properties.
`#1144 <https://github.com/pybind/pybind11/pull/1144>`_. `#1144 <https://github.com/pybind/pybind11/pull/1144>`_.
* The ``value()`` method of ``py::enum_`` now accepts an optional docstring
that will be shown in the documentation of the associated enumeration.
v2.2.1 (September 14, 2017) v2.2.1 (September 14, 2017)
----------------------------------------------------- -----------------------------------------------------

View File

@ -1375,15 +1375,30 @@ public:
auto m_entries_ptr = m_entries.inc_ref().ptr(); auto m_entries_ptr = m_entries.inc_ref().ptr();
def("__repr__", [name, m_entries_ptr](Type value) -> pybind11::str { def("__repr__", [name, m_entries_ptr](Type value) -> pybind11::str {
for (const auto &kv : reinterpret_borrow<dict>(m_entries_ptr)) { for (const auto &kv : reinterpret_borrow<dict>(m_entries_ptr)) {
if (pybind11::cast<Type>(kv.second) == value) if (pybind11::cast<Type>(kv.second[int_(0)]) == value)
return pybind11::str("{}.{}").format(name, kv.first); return pybind11::str("{}.{}").format(name, kv.first);
} }
return pybind11::str("{}.???").format(name); return pybind11::str("{}.???").format(name);
}); });
def_property_readonly_static("__members__", [m_entries_ptr](object /* self */) { def_property_readonly_static("__doc__", [m_entries_ptr](handle self) {
std::string docstring;
const char *tp_doc = ((PyTypeObject *) self.ptr())->tp_doc;
if (tp_doc)
docstring += std::string(tp_doc) + "\n\n";
docstring += "Members:";
for (const auto &kv : reinterpret_borrow<dict>(m_entries_ptr)) {
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);
}
return docstring;
});
def_property_readonly_static("__members__", [m_entries_ptr](handle /* self */) {
dict m; dict m;
for (const auto &kv : reinterpret_borrow<dict>(m_entries_ptr)) for (const auto &kv : reinterpret_borrow<dict>(m_entries_ptr))
m[kv.first] = kv.second; m[kv.first] = kv.second[int_(0)];
return m; return m;
}, return_value_policy::copy); }, return_value_policy::copy);
def(init([](Scalar i) { return static_cast<Type>(i); })); def(init([](Scalar i) { return static_cast<Type>(i); }));
@ -1431,15 +1446,15 @@ public:
/// Export enumeration entries into the parent scope /// Export enumeration entries into the parent scope
enum_& export_values() { enum_& export_values() {
for (const auto &kv : m_entries) for (const auto &kv : m_entries)
m_parent.attr(kv.first) = kv.second; m_parent.attr(kv.first) = kv.second[int_(0)];
return *this; return *this;
} }
/// Add an enumeration entry /// Add an enumeration entry
enum_& value(char const* name, Type value) { enum_& value(char const* name, Type value, const char *doc = nullptr) {
auto v = pybind11::cast(value, return_value_policy::copy); auto v = pybind11::cast(value, return_value_policy::copy);
this->attr(name) = v; this->attr(name) = v;
m_entries[pybind11::str(name)] = v; m_entries[pybind11::str(name)] = std::make_pair(v, doc);
return *this; return *this;
} }

View File

@ -15,9 +15,9 @@ TEST_SUBMODULE(enums, m) {
EOne = 1, EOne = 1,
ETwo ETwo
}; };
py::enum_<UnscopedEnum>(m, "UnscopedEnum", py::arithmetic()) py::enum_<UnscopedEnum>(m, "UnscopedEnum", py::arithmetic(), "An unscoped enumeration")
.value("EOne", EOne) .value("EOne", EOne, "Docstring for EOne")
.value("ETwo", ETwo) .value("ETwo", ETwo, "Docstring for ETwo")
.export_values(); .export_values();
// test_scoped_enum // test_scoped_enum

View File

@ -18,6 +18,22 @@ def test_unscoped_enum():
assert m.UnscopedEnum.__members__ == \ assert m.UnscopedEnum.__members__ == \
{"EOne": m.UnscopedEnum.EOne, "ETwo": m.UnscopedEnum.ETwo} {"EOne": m.UnscopedEnum.EOne, "ETwo": m.UnscopedEnum.ETwo}
assert m.UnscopedEnum.__doc__ == \
'''An unscoped enumeration
Members:
EOne : Docstring for EOne
ETwo : Docstring for ETwo''' or m.UnscopedEnum.__doc__ == \
'''An unscoped enumeration
Members:
ETwo : Docstring for ETwo
EOne : Docstring for EOne'''
# no TypeError exception for unscoped enum ==/!= int comparisons # no TypeError exception for unscoped enum ==/!= int comparisons
y = m.UnscopedEnum.ETwo y = m.UnscopedEnum.ETwo
assert y == 2 assert y == 2