Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option for enable/disable enum members in docstring. #2768

Merged
merged 7 commits into from
Dec 9, 2022

Conversation

knarfS
Copy link
Contributor

@knarfS knarfS commented Jan 5, 2021

Description

This adds the option to disable/enable the enum members listed in the docstring (default is enabled). This is useful, when the documentation tool is able to generate documentation for class variables, so the enum members / class variable aren't listed twice in the documentation. An other benefit of using the features of the documentation generator is, that the members are linkable in the documentation.

I'm using pdoc3 to generate the documentation of an embedded python module, but the above also applies partially to pydoc. No idea about sphinx, I wasn't able to generate the documentation programmatically with sphinx...

I'd be happy to add that option to the documentation, but need a hint to which section this would fit best. There is a chapter about sphinx, but that doesn't exactly match.

Suggested changelog entry:

Add option for enable/disable enum members in docstring.

@YannickJadoul
Copy link
Collaborator

Two things:

  1. Should this be a global setting, or just a local flag, passed to the enum constructor? I'm not sure; other reviewers, what do you think? At any rate, I'd like some arguments pro or contra this approach.
  2. m_base.attr("__doc__") = static_property(...) isn't doing anything more than adding something to the docstring. The if statement can/should just go around this whole creation of the static_property, I think.

@knarfS
Copy link
Contributor Author

knarfS commented Jan 5, 2021

1. Should this be a global setting, or just a local flag, passed to the enum constructor? I'm not sure; other reviewers, what do you think? At any rate, I'd like some arguments pro or contra this approach.

I wanted to put this in the same place as the other docstring related options (function_signaturesand user_defined_docstrings), but yeah, maybe the enum ctor would be a better place?

2. `m_base.attr("__doc__") = static_property(...)` isn't doing anything more than adding something to the docstring. The `if` statement can/should just go around this whole creation of the `static_property`, I think.

There is still the docstring of the enum class itself (std::string(((PyTypeObject *) arg.ptr())->tp_doc)), which shouldn't be affected by this option.

@YannickJadoul
Copy link
Collaborator

I wanted to put this in the same place as the other docstring related options (function_signaturesand user_defined_docstrings), but yeah, maybe the enum ctor would be a better place?

Yeah, I'm not 100% convinced of either approach, but I thought it's worth bringing up).
The advantage of a global thing is that it's consistent across all enums_. The thing that makes me doubt this approach is whether this isn't too fine-grained to make a full global option out of it.
The disadvantage of a constructor argument is that C++ doesn't have keyword arguments or even keyword-only arguments... :-/

If there are no further complaints, I'm happy to keep the global option, though.

There is still the docstring of the enum class itself (std::string(((PyTypeObject *) arg.ptr())->tp_doc)), which shouldn't be affected by this option.

I believe that if you don't set __doc__, asking for __doc__ will/should give you the contents of tp_doc. I might of course be completely wrong. Could you please give this a try?

@knarfS
Copy link
Contributor Author

knarfS commented Jan 5, 2021

I believe that if you don't set __doc__, asking for __doc__ will/should give you the contents of tp_doc. I might of course be completely wrong. Could you please give this a try?

You are right, I've just tested this and it works!

@YannickJadoul
Copy link
Collaborator

Thanks, that's already better, I think :-)

The disadvantage of a constructor argument is that C++ doesn't have keyword arguments or even keyword-only arguments... :-/

Just to add to future discussion (I'm still not saying this is preferred): if we want to get around this, another option is to come up with some custom tag like py::enum_members_docstring(false) or so.

@knarfS
Copy link
Contributor Author

knarfS commented Jan 6, 2021

This will also fix #2275 when disabling the enum members docstring (aka not setting __doc__):

# include <pybind11/pybind11.h>

namespace py = pybind11;

enum Numbers {
    zero,
    one
}

PYBIND11_MODULE(numbers, m) {
    py::options options;
    options.disable_enum_members_docstring();

    py::enum_<Numbers>e(m, "Numbers");
    e
        .value("zero", zero)
        .value("one", one)
        .export_values();
    e.attr("__doc__") = "test";
}

@YannickJadoul
Copy link
Collaborator

Thanks for checking that as well, @knarfS!

@rwgk
Copy link
Collaborator

rwgk commented Dec 1, 2022

Looks good to me, based on the understanding that this PR adds an option with a default that leaves the existing behavior unchanged, unless the option is actually used. Is that correct?

The only thing missing are tests and possibly a couple lines in the documentation (I'd look for documentation for existing options as a starting point).

@knarfS
Copy link
Contributor Author

knarfS commented Dec 2, 2022

Looks good to me, based on the understanding that this PR adds an option with a default that leaves the existing behavior unchanged, unless the option is actually used. Is that correct?

Yes, the current docstring behavior is untouched. I've added a test to secure that.

I've also added a section about the undocumented option disable_user_defined_docstrings().

Copy link
Collaborator

@rwgk rwgk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thank you!

docs/advanced/misc.rst Outdated Show resolved Hide resolved
docs/advanced/misc.rst Outdated Show resolved Hide resolved
@knarfS
Copy link
Contributor Author

knarfS commented Dec 2, 2022

Thank you @rwgk for reviewing and approving. I updated the PR with your suggestions.

@rwgk rwgk requested a review from Skylion007 December 2, 2022 16:41
@rwgk
Copy link
Collaborator

rwgk commented Dec 2, 2022

Great, thanks! I'll wait a day or so to give @Skylion007 I chance to review, too.

dict entries = arg.attr("__entries");
if (((PyTypeObject *) arg.ptr())->tp_doc) {
docstring
+= std::string(((PyTypeObject *) arg.ptr())->tp_doc) + "\n\n";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: reinterpret_cast ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied in commit c2456d9

auto comment = kv.second[int_(1)];
docstring += "\n\n " + key;
if (!comment.is_none()) {
docstring += " : " + (std::string) pybind11::str(comment);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: static_cast or .cast<std::string>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also applied in Applied in commit c2456d9

I also changed the code to systematically use +=.

@Skylion007
Copy link
Collaborator

Great, thanks! I'll wait a day or so to give @Skylion007 I chance to review, too.

Sorry, missed this in my Github notifications.

@rwgk
Copy link
Collaborator

rwgk commented Dec 9, 2022

I went ahead with a rebase & applying the review suggestions, to get this into the next smart_holder update.

Waiting for the CI.

@rwgk
Copy link
Collaborator

rwgk commented Dec 9, 2022

The only one CI failure is a known flake (test_gil_scoped DEADLOCK), definitely unrelated to this RP.

@rwgk rwgk merged commit 0012685 into pybind:master Dec 9, 2022
@github-actions github-actions bot added the needs changelog Possibly needs a changelog entry label Dec 9, 2022
@knarfS
Copy link
Contributor Author

knarfS commented Dec 11, 2022

Thanks @rwgk for merging!

Not sure, but maybe #2275 can be also closed now (see test above).

@rwgk
Copy link
Collaborator

rwgk commented Dec 11, 2022

Thanks @rwgk for merging!

Not sure, but maybe #2275 can be also closed now (see test above).

@AWhetter Is there a chance you could confirm & update or close #2275?

@AWhetter
Copy link
Contributor

This does indeed fix that issue!

@rwgk
Copy link
Collaborator

rwgk commented Dec 12, 2022

Thanks @AWhetter!

@henryiii henryiii removed the needs changelog Possibly needs a changelog entry label Dec 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants