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

Adds hyperlinks to docstrings of Qobj and Qobjevo class #1499

Closed
wants to merge 31 commits into from

Conversation

purva-thakre
Copy link
Contributor

@purva-thakre purva-thakre commented Apr 16, 2021

Description
Adds hyperlinks for functions, classes, attributes etc. wherever possible.

  • Deleted methods table. See this comment.
  • Every function, class etc is linked by default method of :obj:`.some_func`
  • Functions not in API doc are referenced as 'func_not_in_API'.
  • Added TypeError and ValueError etc. in docstrings when an error of either type is raised by a function. Most of these might not be needed as this link advises to provide information about only the obvious errors. I read the link after making the changes. If needed, the new additions can be removed from the docstrings.

Related issues or PRs
One of the fixes for issue 71 in documentation.

Changelog
Add hyperlinks in documentation and errors in docstrings of functions in qobj and qobevo

@purva-thakre purva-thakre changed the title Adds hyperlinks to docstrings Adds hyperlinks to docstrings of Qobj and Qobjevo class Apr 16, 2021
@coveralls
Copy link

coveralls commented Apr 16, 2021

Coverage Status

Coverage increased (+0.2%) to 64.309% when pulling ee349a9 on purva-thakre:ENH_Hyperlink into 67c4687 on qutip:master.

@hodgestar
Copy link
Contributor

hodgestar commented Apr 16, 2021

@purva-thakre Thank you for opening this! Let us know when it's ready and we'll review. Please ask if you have any questions or get stuck with anything.

@purva-thakre
Copy link
Contributor Author

purva-thakre commented Apr 17, 2021

@hodgestar I do not know how to link any of the methods listed in a table like in the methods table for Qobj class here. I tried to link expm() using :meth:expm(). When I preview the html build, entire :meth:expm() shows up in the table instead of a link to expm() method.

The screenshot below tries to link an attribute which was corrected to a method later. I forgot to screenshot the one where its meth:expm()

image

I think this has to do with how : are used by python domain and how the methods table is built (for API documentation - https://github.com/qutip/qutip-doc/blob/master/apidoc/apidoc.rst#api-documentation).

Appreciate any pointers about any workaround to this. If not, I can just skip the links in the table because there'e no problems to adding links to other docstrings.

@BoxiLi
Copy link
Member

BoxiLi commented Apr 17, 2021

Have you tried

:meth:`Qobj.expm`

?
First, there shouldn't be any () in the reference to a function/method. And second, only with :meth:`expm` I think Sphinx will try to look for a function expm in the public API, which does not exist. Because this one is a method under the class Qobj.

@purva-thakre
Copy link
Contributor Author

purva-thakre commented Apr 19, 2021

@BoxiLi Yes, I have not used parentheses for functions not in the public API. These changes are still local and haven't been pushed yet.

My issue is with the Methods table for Qobj class. When I try the same edit for the code lines rendered as a table, there's no hyperlinks in the table. The entire code line shows up as it is. See screenshot below :
image

I think this is due to how Sphinx tables are defined and a similar manner to define python object references as well. One workaround to this could be adding reference labels to these functions.

@jakelishman
Copy link
Member

jakelishman commented Apr 19, 2021

Well for one that table of methods just shouldn't exist - it can all be deleted. It's a holdover from a previous method of doing API documentation, but now since we use numpydoc, the equivalent gets done automatically for us right below where that table appears in the docs. You'll not succeed at any sort of formatting in that table, because all the headers are parsed as literal strings, and (mostly) aren't subject to rst formatting at all. This isn't a feature of all rst tables, just this implicit table created from a definition list.

Second, should you want it elsewhere, the minimal magic incantation is :meth:`expm` if you're inside the object you're referring to. If you're outside it, use a qualified :meth:`Qobj.copy`, which can also be used to refer to other objects' methods from inside an object.

@purva-thakre
Copy link
Contributor Author

purva-thakre commented Apr 21, 2021

Thanks ! I have removed the table.

Couple of questions :

  • What's the preferred method to link functions not in public API ?
    I could create a sphinx reference label to link to these functions either by using Github's permalink or a path to such functions in the directory. You can see this when I try to link check_isunitary which is not in the API but is defined in Qobj file in the linked branch.
  • Qobj vs qobj link :
    There are problems with linking functions for Qobj class. For example, if I want to link to isoperbra then the only link that will work is qutip.qobj.isoperbra not qutip.Qobj.isoperbra. If latter is preferred then I will have to create ref labels for each of these functions as stated above. More examples can be observed in the superrep attributes of Qobj class of linked branch. I think this might be due to qutip.qobj in module code.

@BoxiLi
Copy link
Member

BoxiLi commented Apr 22, 2021

What's the preferred method to link functions that are not public APIs?

I don't think we should link to non-public API in the doc. Non-public API should not (at least no encouraged) be used outside of QuTiP because we may change it without issuing a deprecation warning. Besides, check_unitary is a public API, it is a class method under Qobj, rather than a function, see bellow.

Qobj vs qobj link

qutip.qobj.isoperbra and qutip.Qobj.isoperbra are different. The lower case qobj is a submodule in QuTiP (qobj.py) while Qobj is a class. isoperbra is not a class method under Qobj. It is a function defined under the submodule qobj. So only qutip.qobj.isoperbra is the correct path.

To make the life simpler, I would recommend to use the shortcut :func:`.isoperbra` for functions and :meth:`.Qobj.class_method` . Or even simpler: :obj:`.isoperbra` . Sphinx will automatically look for the correct match. As long as there are no two functions with the same name, we are safe. This isalso because qutip.qobj.isoperbra will be a wrong path in qutip 5.0. The file is moved.

@nathanshammah
Copy link
Member

@purva-thakre, is this still a draft PR?

@purva-thakre
Copy link
Contributor Author

@nathanshammah Yes, I still have to make a couple of changes to this.

qutip/qobj.py Outdated Show resolved Hide resolved
@purva-thakre purva-thakre marked this pull request as ready for review May 4, 2021 16:38
Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

Thank you for making the PR - I saw lots of fixed typos, and places where added links definitely helped the documentation.

However, I only got part way through, but really there's also a lot of changes that aren't appropriate here, sorry. Most of Qobj and QobjEvo already do link when they should (though it's not quite 100%). A few points:

  • Don't put a link on a word if it doesn't specifically refer to the object you're linking to. For example, the words "ket", "bra" and "operator" should almost never have links - they're just words, and they're not referring to any function or module. The word "tensor" usually just means "tensor", it shouldn't be a link to the module. The reason not to do this is that it makes it seem like we're giving a special meaning to common words, and it dilutes the use of "real" links.
  • "Raises" sections should be used very sparingly. There's no need to point out that passing an incorrect value or an incorrect type will cause a ValueError or TypeError, for example. The reason is that this just dilutes the available information - it's always the case that an incorrect value will raise ValueError, so the programmer doesn't get any new information from this. It's more appropriate to use the "Parameters" section to document what's allowed; a programmer can assume that if they violate that, a suitable exception will be raised. The "Raises" section should only be for very non-obvious errors, or errors that even a programmer who has read the "Parameters" section might reasonably make accidentally.
  • Don't put the error message in the description of a "Raises" section. The message is intended to inform the user when it appears, but when you're writing a "Raises" section, that's the purpose of the description below the type of the exception; there's no additional information gained from having the message, and it clutters up the docs.
  • Take care not to change the meaning of sentences when you're adding in additional formatting - I saw a few places where changes in the formatting accidentally deleted a word, or hid some extra meaning.
  • In RST, single backticks (`) produce italics, not monospaced text.
  • There's no need to change :class:/:func:/:meth: directives into :obj: directives - either style is totally fine. Don't worry about it now that you've done it, though, it's fine to leave them in the new style (because either is fine).

Do you have the docs building correctly? It's worth checking to make sure that the changes you made are showing up the way you expected. In the worst case scenario, GitHub now builds them for you whenever you push changes. Click on the "Checks" tab at the top of the PR, and on the right of the screen there's an "Artifacts" button - you can download the file there, and open "index.html" in your web browser to get the full set of rendered docs.

qutip/qobj.py Show resolved Hide resolved
qutip/qobj.py Show resolved Hide resolved
qutip/qobj.py Show resolved Hide resolved
qutip/qobj.py Show resolved Hide resolved
qutip/qobj.py Show resolved Hide resolved
qutip/qobj.py Show resolved Hide resolved
qutip/qobj.py Show resolved Hide resolved
qutip/qobj.py Show resolved Hide resolved
qutip/qobj.py Show resolved Hide resolved
qutip/qobj.py Show resolved Hide resolved
@purva-thakre
Copy link
Contributor Author

purva-thakre commented May 4, 2021

Don't put a link on a word if it doesn't specifically refer to the object you're linking to

Yeah, I was worried if linking words like ket, bra were needed or not. I'll remove them.

The "Raises" section should only be for very non-obvious errors
Don't put the error message in the description of a "Raises" section

No problem. I will remove errors created due to incorrect parameters and other obvious errors + error messages. I will add a parameters section if needed to clarify over ValueError.

I saw a few places where changes in the formatting accidentally deleted a word, or hid some extra meaning

I think the accidental deletes might have been due to getting caught in some cut/copy/paste flow.

Do you have the docs building correctly?

Yes, I do. I was a bit confused about how to try to format to functions not in API doc. So, I still tried to link a ref to them so that they are formatted similar to hyperlinks. I think a couple of these appear as italics.

@purva-thakre purva-thakre marked this pull request as draft May 4, 2021 18:15
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.

None yet

6 participants