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

diff --git a/docs/changelog.rst b/docs/changelog.rst
index b0d958d..ec8dc72 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -18,6 +18,9 @@
 * 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)
 -----------------------------------------------------
 
diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h
index b489bb2..5bd2ccc 100644
--- a/include/pybind11/pybind11.h
+++ b/include/pybind11/pybind11.h
@@ -1375,15 +1375,30 @@
         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 @@
     /// 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;
     }
 
diff --git a/tests/test_enum.cpp b/tests/test_enum.cpp
index 49f31ba..4cd14a9 100644
--- a/tests/test_enum.cpp
+++ b/tests/test_enum.cpp
@@ -15,9 +15,9 @@
         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
diff --git a/tests/test_enum.py b/tests/test_enum.py
index d8eff52..d3f5b4d 100644
--- a/tests/test_enum.py
+++ b/tests/test_enum.py
@@ -18,6 +18,22 @@
     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