Skip to content

Commit

Permalink
Add support for docstrings on enums
Browse files Browse the repository at this point in the history
  • Loading branch information
kljohann committed Oct 18, 2024
1 parent 15daf75 commit 230988b
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 4 deletions.
18 changes: 14 additions & 4 deletions src/expose.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,10 @@ void EnumExposer::emitIntroducer(llvm::raw_ostream &os,
emitType(os);
os << "(" << parent_identifier << ", ";
emitSpelling(os, enum_decl, annotations.lookup<NamedDeclAttrs>(enum_decl));
if (llvm::StringRef doc = getBriefText(enum_decl); !doc.empty()) {
os << ", ";
emitStringLiteral(os, doc);
}
if (const auto attrs = annotations.get<EnumDeclAttrs>(enum_decl);
attrs.has_value() && attrs->arithmetic) {
os << ", ::pybind11::arithmetic()";
Expand All @@ -1024,7 +1028,12 @@ void EnumExposer::handleDeclImpl(llvm::raw_ostream &os,
const std::string scope = getFullyQualifiedName(enum_decl);
os << "context.value(";
emitSpelling(os, decl, annotations.lookup<NamedDeclAttrs>(decl));
os << ", " << scope << "::" << enumerator->getName() << ");\n";
os << ", " << scope << "::" << enumerator->getName();
if (llvm::StringRef doc = getBriefText(decl); !doc.empty()) {
os << ", ";
emitStringLiteral(os, doc);
}
os << ");\n";
}
}

Expand All @@ -1050,6 +1059,10 @@ void RecordExposer::emitIntroducer(llvm::raw_ostream &os,
os << "(" << parent_identifier << ", ";
emitSpelling(os, record_decl,
annotations.lookup<NamedDeclAttrs>(record_decl));
if (llvm::StringRef doc = getBriefText(record_decl); !doc.empty()) {
os << ", ";
emitStringLiteral(os, doc);
}
if (const auto attrs = annotations.get<RecordDeclAttrs>(record_decl);
attrs.has_value() && attrs->dynamic_attr) {
os << ", ::pybind11::dynamic_attr()";
Expand All @@ -1059,9 +1072,6 @@ void RecordExposer::emitIntroducer(llvm::raw_ostream &os,

void RecordExposer::finalizeDefinition(llvm::raw_ostream &os) {
emitProperties(os);
os << "context.doc() = ";
emitStringLiteral(os, getBriefText(record_decl));
os << ";\n";
}

void RecordExposer::emitProperties(llvm::raw_ostream &os) {
Expand Down
1 change: 1 addition & 0 deletions tests/integration/docstrings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "docstrings.h"
19 changes: 19 additions & 0 deletions tests/integration/docstrings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include "genpybind.h"

/// Describes how the output will taste.
enum class GENPYBIND(visible) Flavor {
/// Like you would expect.
bland,
/// It tastes different.
fruity,
};

/// A contrived example.
///
/// Only the “brief” docstring is used in the Python bindings.
class GENPYBIND(visible) Example {};

/// Also here.
class GENPYBIND(dynamic_attr) Dynamic {};
20 changes: 20 additions & 0 deletions tests/integration/docstrings_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import docstrings as m


def test_enums_support_docstrings():
expected = """\
Describes how the output will taste.
Members:
bland : Like you would expect.
fruity : It tastes different.\
"""
assert m.Flavor.__doc__ == expected


def test_classes_support_docstrings():
assert m.Example.__doc__ == "A contrived example."
# Docstrings also work with extra arguments to `class_`.
assert m.Dynamic.__doc__ == "Also here."
1 change: 1 addition & 0 deletions tests/integration/enums-can-be-arithmetic.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum GENPYBIND(arithmetic(false)) ExplicitFalse {
Three = 3,
};

/// Docstrings are also supported.
enum GENPYBIND(arithmetic(true)) ExplicitTrue {
Four = 4,
Five = 5,
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/enums-can-be-arithmetic_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ def test_arithmetic_true_can_use_bitwise_operators():
def test_enums_arent_arithmetic_by_default():
with pytest.raises(TypeError, match="unsupported operand type"):
m.Default.Seven | m.Default.Eight


def test_arithmetic_enums_support_docstrings():
assert m.ExplicitTrue.__doc__.startswith("Docstrings are also supported.")

0 comments on commit 230988b

Please sign in to comment.