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

Use of \protected \private commands with python #6554

Open
pierralex opened this issue Oct 13, 2018 · 12 comments
Open

Use of \protected \private commands with python #6554

pierralex opened this issue Oct 13, 2018 · 12 comments
Labels
needinfo reported bug is incomplete, please add additional info Python

Comments

@pierralex
Copy link

In somme classes I want to hide the init method /constructor because I implement a singleton. On others I want to make protected methods visible (methods starting with an underscore)
To achieve that, I am trying to use the \protected and \private commands but without success. The init method i still present in generated doc and the protected method is still absent. What am I missing?
When exploring the issues, I thought this should be working since version 1.4.7 and I am using 1.8.14

## Constructor to be hidden
#   @private
__init__(self):
    pass

## Protected method to display
#   @protected
_my_protected_method_to_override(self):
    pass
@albert-github
Copy link
Collaborator

albert-github commented Oct 13, 2018

  • Did you set the right options in the doxygen configuration file (EXTRACT_...)
  • Did you have a look at \cond .., \endcond and\if and HIDE_...

Can you please attach a, small, complete self contained example (source+config file in a tar or zip) that allows us to reproduce the problem?

@albert-github albert-github added the needinfo reported bug is incomplete, please add additional info label Oct 13, 2018
@pierralex
Copy link
Author

pierralex commented Oct 13, 2018

I created the attached project with a single class Test based on my previous comment (with generated doc and Doxyfile).
I explored the documentation (both Configuration file and commands) but i did not find a way to achieve what I need but maybe I missed something
Issues.zip

@albert-github
Copy link
Collaborator

Looks like there are 2 problems:

  • HIDE_UNDOC_MEMBERS should be set to YES, this will take care of the __init__ function
  • the _protected_method is seen by doxygen as a private member (actually all methods starting wit an underscore are see as public methods unless the method name starts and ends with 2 underscores). We can make this function visible by means of EXTRACT_PRIVATE=YES but the title of the section will be "Private Member Function" this can be overcome by setting in the layout file (doxygen -l to generate the default file) but in the detailed description there will still be the label private

I found a reference (in an answer) of what should be protected and private (https://stackoverflow.com/questions/797771/python-protected-attributes) but is there an authoritative source with this type of information?

@pierralex
Copy link
Author

Thank you for your quick answer but

  • HIDE_UNDOC_MEMBERS must be set to "no" because we are building a library and all public ( and protected for some classes) members must be present in the final doc (even if not documented in the code)
  • Because of the above reason, I don't want to use EXTRACT_PRIVATE=YES and rename the section through the layout file because it will make all the private members visible

I thought \protected and \private instructions work for python. Aren't they?

@albert-github
Copy link
Collaborator

albert-github commented Oct 13, 2018

As far as I can see at the moment \private and \protected don't overrule the default settings in this case.

At the moment I think the only thing you can do is to use \cond ... \endcond

@pierralex
Copy link
Author

Is there any fix planned for that? from this issue #1996 I thought i was supposed to be implemented since version 1.4.7.

@albert-github
Copy link
Collaborator

This is the reason why we now see that the methods with an underscore is private (unless starting and ending with 2 underscores).
Looks like:

  • definition / usage has change in time: now 1 underscore as protected and 2 underscores as private (needed authoritative source with explanation of usage of _ and __ in python).
  • \private and \protected are not handled in python (has to be investigated).

@pierralex
Copy link
Author

ok so the fact is that \private and \protected are not handled in python is a doxygen bug?

@albert-github
Copy link
Collaborator

I'm a bit reluctant to say that it is a bug in doxygen.

In Python when no underscore is used the \public , \protected, \private` work as expected.
When having an underscore this takes precedence over the setting in the comment.

When looking at Fortran we have here a similar situation (see attachment
Fortran.zip), here the attribute setting also takes precedence over the comment setting.

In C++ we don't have this situation, as far as I know, as we can only set globally a protection and not per individual variable / function (unless of course putting 'public:' or 'private:' just in front of it but this is not on a variable but on the following section), so here the comment protection setting overrules always the default / section setting.

@doxygen what is your opinion about this: should the attribute setting (Python underscore, Fortran attribute) or the comment (\private etc.) prevail?

@pierralex
Copy link
Author

OK I understand now. I will try the \cond statements to see i can find a workaround.
But I see 2 problems:
In python, every member is public. But private and protected are notions that are used for design through conventions (single underscore for protected, double underscore for public). If you do not want to respect the design, you can.
Generally we want to encourage someone to use our design that is why we try to respect conventions. So members starting with a single underscore should not be considered private (1st problem). I understand the point that there is no authoritative source clearly stating a single underscore defines a protected member. Also conventions might evolve through time. This why I think \public , \protected and \private should override naming conventions (2nd problem).
More over, as I stated in my sample, if you define a singleton, the constructor must be private (init in python). If it appears in the documentation as public member, the users will think they can use this class constructor. They might be a little surprised to get a SingletonException.

albert-github added a commit to albert-github/doxygen that referenced this issue Oct 15, 2018
Python does not have a real knowledge of protection in respect to variables and functions (i.e. public / private / protected). There are some ad-hoc rules but they changed over time as well.
Doxygen uses  some build in settings for protection i.e. methods starting with '__' and ending with '__' are public other variables and methods starting with '_' are private. This change makes it possible for the user to define his own rules for the protection within Python.

(Loosely based on issue doxygen#6554)
@albert-github
Copy link
Collaborator

I've just pushed a pull request for a more flexible definition of the protection within Python, pull request #6555.
The problem whether or not the documentation should take precedence remains.

@pierralex
Copy link
Author

Thank you for your support.
I have been checking python documentation this morning. In fact protected is not really a thing in python. They define only public versus internal. As a consequence, we decided to use only public members but to notify in the documentation the fact that the method should not be used publicly.
Concerning the private constructor, I have been using the \cond command as a workaround. But I would prefer to use a \private command if your request is accepted in future version of doxygen.
Thank you again for your assistance.
Best regards,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needinfo reported bug is incomplete, please add additional info Python
Projects
None yet
Development

No branches or pull requests

2 participants