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.
`#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)
-----------------------------------------------------

View File

@ -1375,15 +1375,30 @@ public:
auto m_entries_ptr = m_entries.inc_ref().ptr();
def("__repr__", [name, m_entries_ptr](Type value) -> pybind11::str {
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);
});
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;
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_value_policy::copy);
def(init([](Scalar i) { return static_cast<Type>(i); }));
@ -1431,15 +1446,15 @@ public:
/// Export enumeration entries into the parent scope
enum_& export_values() {
for (const auto &kv : m_entries)
m_parent.attr(kv.first) = kv.second;
m_parent.attr(kv.first) = kv.second[int_(0)];
return *this;
}
/// 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);
this->attr(name) = v;
m_entries[pybind11::str(name)] = v;
m_entries[pybind11::str(name)] = std::make_pair(v, doc);
return *this;
}

View File

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

View File

@ -18,6 +18,22 @@ def test_unscoped_enum():
assert m.UnscopedEnum.__members__ == \
{"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
y = m.UnscopedEnum.ETwo
assert y == 2