mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
Add class doc string to native_enum (#5617)
* add class doc string to native_enum * adapt doc argument name * fix test, make class enum doc None by default * fix other python versions? * make clang-tidy happy * rename 'enum_doc' to 'class_doc' * update documentation * [skip ci] Polish changed documentation (mostly done by ChatGPT). --------- Co-authored-by: Bryn Lloyd <12702862+dyollb@users.noreply.github.com> Co-authored-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
This commit is contained in:
@@ -556,7 +556,7 @@ The binding code for this example looks as follows:
|
||||
.def_readwrite("type", &Pet::type)
|
||||
.def_readwrite("attr", &Pet::attr);
|
||||
|
||||
py::native_enum<Pet::Kind>(pet, "Kind")
|
||||
py::native_enum<Pet::Kind>(pet, "Kind", "enum.Enum")
|
||||
.value("Dog", Pet::Kind::Dog)
|
||||
.value("Cat", Pet::Kind::Cat)
|
||||
.export_values()
|
||||
@@ -593,16 +593,20 @@ once. To achieve this, ``py::native_enum`` acts as a buffer to collect the
|
||||
name/value pairs. The ``.finalize()`` call uses the accumulated name/value
|
||||
pairs to build the arguments for constructing a native Python enum type.
|
||||
|
||||
The ``py::native_enum`` constructor supports a third optional
|
||||
``native_type_name`` string argument, with default value ``"enum.Enum"``.
|
||||
Other types can be specified like this:
|
||||
The ``py::native_enum`` constructor takes a third argument,
|
||||
``native_type_name``, which specifies the fully qualified name of the Python
|
||||
base class to use — e.g., ``"enum.Enum"`` or ``"enum.IntEnum"``. A fourth
|
||||
optional argument, ``class_doc``, provides the docstring for the generated
|
||||
class.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::native_enum<Pet::Kind>(pet, "Kind", "enum.IntEnum")
|
||||
py::native_enum<Pet::Kind>(pet, "Kind", "enum.IntEnum", "Constant specifying the kind of pet")
|
||||
|
||||
Any fully-qualified Python name can be specified. The only requirement is
|
||||
that the named type is similar to
|
||||
You may use any fully qualified Python name for ``native_type_name``.
|
||||
The only requirement is that the named type is similar to
|
||||
`enum.Enum <https://docs.python.org/3/library/enum.html#enum.Enum>`_
|
||||
in these ways:
|
||||
|
||||
|
||||
@@ -29,10 +29,12 @@ public:
|
||||
native_enum_data(const object &parent_scope,
|
||||
const char *enum_name,
|
||||
const char *native_type_name,
|
||||
const char *class_doc,
|
||||
const std::type_index &enum_type_index)
|
||||
: enum_name_encoded{enum_name}, native_type_name_encoded{native_type_name},
|
||||
enum_type_index{enum_type_index}, parent_scope(parent_scope), enum_name{enum_name},
|
||||
native_type_name{native_type_name}, export_values_flag{false}, finalize_needed{false} {}
|
||||
native_type_name{native_type_name}, class_doc(class_doc), export_values_flag{false},
|
||||
finalize_needed{false} {}
|
||||
|
||||
void finalize();
|
||||
|
||||
@@ -70,10 +72,11 @@ private:
|
||||
object parent_scope;
|
||||
str enum_name;
|
||||
str native_type_name;
|
||||
std::string class_doc;
|
||||
|
||||
protected:
|
||||
list members;
|
||||
list docs;
|
||||
list member_docs;
|
||||
bool export_values_flag : 1; // Attention: It is best to keep the bools together.
|
||||
|
||||
private:
|
||||
@@ -191,7 +194,10 @@ inline void native_enum_data::finalize() {
|
||||
parent_scope.attr(member_name) = py_enum[member_name];
|
||||
}
|
||||
}
|
||||
for (auto doc : docs) {
|
||||
if (!class_doc.empty()) {
|
||||
py_enum.attr("__doc__") = class_doc.c_str();
|
||||
}
|
||||
for (auto doc : member_docs) {
|
||||
py_enum[doc[int_(0)]].attr("__doc__") = doc[int_(1)];
|
||||
}
|
||||
global_internals_native_enum_type_map_set_item(enum_type_index, py_enum.release().ptr());
|
||||
|
||||
@@ -24,9 +24,10 @@ public:
|
||||
|
||||
native_enum(const object &parent_scope,
|
||||
const char *name,
|
||||
const char *native_type_name = "enum.Enum")
|
||||
const char *native_type_name,
|
||||
const char *class_doc = "")
|
||||
: detail::native_enum_data(
|
||||
parent_scope, name, native_type_name, std::type_index(typeid(EnumType))) {
|
||||
parent_scope, name, native_type_name, class_doc, std::type_index(typeid(EnumType))) {
|
||||
if (detail::get_local_type_info(typeid(EnumType)) != nullptr
|
||||
|| detail::get_global_type_info(typeid(EnumType)) != nullptr) {
|
||||
pybind11_fail(
|
||||
@@ -53,7 +54,7 @@ public:
|
||||
disarm_finalize_check("value after finalize");
|
||||
members.append(make_tuple(name, static_cast<Underlying>(value)));
|
||||
if (doc) {
|
||||
docs.append(make_tuple(name, doc));
|
||||
member_docs.append(make_tuple(name, doc));
|
||||
}
|
||||
arm_finalize_check(); // There was no exception.
|
||||
return *this;
|
||||
|
||||
@@ -76,7 +76,7 @@ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
TEST_SUBMODULE(native_enum, m) {
|
||||
using namespace test_native_enum;
|
||||
|
||||
py::native_enum<smallenum>(m, "smallenum", "enum.IntEnum")
|
||||
py::native_enum<smallenum>(m, "smallenum", "enum.IntEnum", "doc smallenum")
|
||||
.value("a", smallenum::a)
|
||||
.value("b", smallenum::b)
|
||||
.value("c", smallenum::c)
|
||||
@@ -89,7 +89,7 @@ TEST_SUBMODULE(native_enum, m) {
|
||||
.value("blue", color::blue)
|
||||
.finalize();
|
||||
|
||||
py::native_enum<altitude>(m, "altitude")
|
||||
py::native_enum<altitude>(m, "altitude", "enum.Enum")
|
||||
.value("high", altitude::high)
|
||||
.value("low", altitude::low)
|
||||
.finalize();
|
||||
@@ -189,7 +189,7 @@ TEST_SUBMODULE(native_enum, m) {
|
||||
py::native_enum<fake>(m, "fake_double_registration_native_enum", "enum.IntEnum")
|
||||
.value("x", fake::x)
|
||||
.finalize();
|
||||
py::native_enum<fake>(m, "fake_double_registration_native_enum");
|
||||
py::native_enum<fake>(m, "fake_double_registration_native_enum", "enum.Enum");
|
||||
});
|
||||
|
||||
m.def("native_enum_name_clash", [](py::module_ &m) {
|
||||
|
||||
@@ -108,6 +108,12 @@ def test_export_values():
|
||||
assert m.exv1 is m.export_values.exv1
|
||||
|
||||
|
||||
def test_class_doc():
|
||||
pure_native = enum.IntEnum("pure_native", (("mem", 0),))
|
||||
assert m.smallenum.__doc__ == "doc smallenum"
|
||||
assert m.color.__doc__ == pure_native.__doc__
|
||||
|
||||
|
||||
def test_member_doc():
|
||||
pure_native = enum.IntEnum("pure_native", (("mem", 0),))
|
||||
assert m.member_doc.mem0.__doc__ == "docA"
|
||||
|
||||
Reference in New Issue
Block a user