rigetti / pyquil

A Python library for quantum programming using Quil.
http://docs.rigetti.com
Apache License 2.0
1.4k stars 342 forks source link

Should docstrings all be valid RST? #1140

Closed peterjc closed 4 years ago

peterjc commented 4 years ago

I've seen http://docs.rigetti.com/en/stable/ which includes some of the API strings via https://github.com/rigetti/pyquil/tree/master/docs/source/apidocs and Sphinx.

Initially assuming you used all the docstrings, I used it as a test case for my flake8 plugin which validates docstrings as reStructuredText markup. This reported various violations. I've looked at a sample, but didn't find any affecting docstrings actually appearing in your documentation.

e.g. Multiple usage of the string |000...00> without slash escaping the pipe, which docutils (and therefore I would expect Sphinx) sees as a malformed inline substitution reference, "Inline substitution_reference start-string without end-string". I used your example to build a new test case for the flake8 plugin https://github.com/peterjc/flake8-rst-docstrings/commit/ee3b66a0a0451e0034b1ac7eb849bc3f344c7834

I've concluded there is some selection (possibly manual curation) for which of your docstrings appear in the documentation, so perhaps only those need to be valid RST (and you may be checking this anyway via sphinx in strict mode using SPHINXOPTS = -W?).

appleby commented 4 years ago

I think ideally we'd like for all our docstrings to be valid rst markup. If the number of violations isn't too large and you don't mind sending a PR, I'd be happy to review it.

peterjc commented 4 years ago

I suspect some are false positives (which are interesting to me from the plugin point of view), but the current output:

$ flake8 --select RST --rst-roles ref,py:class,py:func --rst-directives versionadded pyquil/
pyquil/magic.py:126:1: RST203 Definition list ends without a blank line; unexpected unindent.
pyquil/magic.py:214:1: RST301 Unexpected indentation.
pyquil/magic.py:216:1: RST301 Unexpected indentation.
pyquil/magic.py:217:1: RST201 Block quote ends without a blank line; unexpected unindent.
pyquil/gates.py:0:1: RST902 Failed to parse __all__ entry.
pyquil/gate_matrices.py:0:1: RST902 Failed to parse __all__ entry.
pyquil/unitary_tools.py:178:1: RST301 Unexpected indentation.
pyquil/unitary_tools.py:179:1: RST201 Block quote ends without a blank line; unexpected unindent.
pyquil/reference_simulator.py:160:1: RST219 Inline substitution_reference start-string without end-string.
pyquil/reference_simulator.py:176:1: RST305 Undefined substitution referenced: "0><0".
pyquil/reference_simulator.py:179:1: RST305 Undefined substitution referenced: "000...0><000...0".
pyquil/reference_simulator.py:209:1: RST219 Inline substitution_reference start-string without end-string.
pyquil/reference_simulator.py:216:1: RST219 Inline substitution_reference start-string without end-string.
pyquil/numpy_simulator.py:302:1: RST219 Inline substitution_reference start-string without end-string.
pyquil/noise.py:687:1: RST218 Literal block expected; none found.
pyquil/pyqvm.py:135:1: RST219 Inline substitution_reference start-str$ flake8 --select RST --rst-roles ref,py:class,py:func --rst-directives versionadded,deprecated pyquil/
pyquil/magic.py:126:1: RST203 Definition list ends without a blank line; unexpected unindent.
pyquil/magic.py:214:1: RST301 Unexpected indentation.
pyquil/magic.py:216:1: RST301 Unexpected indentation.
pyquil/magic.py:217:1: RST201 Block quote ends without a blank line; unexpected unindent.
pyquil/gates.py:0:1: RST902 Failed to parse __all__ entry.
pyquil/gate_matrices.py:0:1: RST902 Failed to parse __all__ entry.
pyquil/unitary_tools.py:178:1: RST301 Unexpected indentation.
pyquil/unitary_tools.py:179:1: RST201 Block quote ends without a blank line; unexpected unindent.
pyquil/reference_simulator.py:160:1: RST219 Inline substitution_reference start-string without end-string.
pyquil/reference_simulator.py:176:1: RST305 Undefined substitution referenced: "0><0".
pyquil/reference_simulator.py:179:1: RST305 Undefined substitution referenced: "000...0><000...0".
pyquil/reference_simulator.py:209:1: RST219 Inline substitution_reference start-string without end-string.
pyquil/reference_simulator.py:216:1: RST219 Inline substitution_reference start-string without end-string.
pyquil/numpy_simulator.py:302:1: RST219 Inline substitution_reference start-string without end-string.
pyquil/noise.py:687:1: RST218 Literal block expected; none found.
pyquil/pyqvm.py:135:1: RST219 Inline substitution_reference start-string without end-string.
pyquil/tests/test_numpy_simulator.py:276:1: RST213 Inline emphasis start-string without end-string.
pyquil/tests/test_numpy_simulator.py:280:1: RST213 Inline emphasis start-string without end-string.
pyquil/api/_quantum_computer.py:1022:1: RST301 Unexpected indentation.
pyquil/api/_quantum_computer.py:1026:1: RST201 Block quote ends without a blank line; unexpected unindent.
pyquil/api/_quantum_computer.py:1170:1: RST301 Unexpected indentation.
pyquil/api/_quantum_computer.py:1171:1: RST201 Block quote ends without a blank line; unexpected unindent.
pyquil/api/_quantum_computer.py:1173:1: RST203 Definition list ends without a blank line; unexpected unindent.
pyquil/api/_quantum_computer.py:1177:1: RST203 Definition list ends without a blank line; unexpected unindent.
pyquil/api/_quantum_computer.py:1180:1: RST205 Explicit markup ends without a blank line; unexpected unindent.
pyquil/api/_base_connection.py:287:1: RST202 Bullet list ends without a blank line; unexpected unindent.
pyquil/api/_config.py:45:1: RST301 Unexpected indentation.
pyquil/api/_devices.py:55:1: RST301 Unexpected indentation.
pyquil/api/_devices.py:57:1: RST201 Block quote ends without a blank line; unexpected unindent.
pyquil/api/_devices.py:123:1: RST301 Unexpected indentation.
pyquil/api/_devices.py:128:1: RST201 Block quote ends without a blank line; unexpected unindent.
pyquil/api/_qpu.py:314:1: RST203 Definition list ends without a blank line; unexpected unindent.
pyquil/api/_qpu.py:329:1: RST203 Definition list ends without a blank line; unexpected unindent.
pyquil/experiment/_main.py:132:1: RST304 Unknown interpreted text role "func".
pyquil/experiment/_program.py:54:1: RST214 Inline literal start-string without end-string.
pyquil/experiment/_program.py:54:1: RST214 Inline literal start-string without end-string

One is a possibly trivial inconsistency in once using just func as a role rather than py:func, could be harmless depending on your Sphinx configuration:

pyquil/experiment/_main.py:132:1: RST304 Unknown interpreted text role "func".

Others like RST301 Unexpected indentation. are at least in some cases literal blocks not being marked as such (e.g. with double colon or explicitly declaring python code snippets). What is your stylistic preference here?

appleby commented 4 years ago

Others like RST301 Unexpected indentation. are at least in some cases literal blocks not being marked as such (e.g. with double colon or explicitly declaring python code snippets). What is your stylistic preference here?

Feel free to add the appropriate rst syntax for these to parse as code blocks. There are at least a handful of examples of this in the file quil.py, which uses .. code:: sections to delimit Quil source examples.

peterjc commented 4 years ago

What is your preference for strings like |000...00>, |0><0| or |000...0><000...0| for qubit notation?

Escape the slashes (hard to read in the editor), or wrap in double back ticks (visually different once rendered)?

peterjc commented 4 years ago

Or, following docs/source/exercises.rst use math mode explicitly? e.g. |000> becomes:

:math:`|000\rangle`
appleby commented 4 years ago

Hmmm, I think my preference if for backticks, since that is readable both in the source comments and in the generated docs, but I'll defer to @karalekas here. He's currently (supposed to be) taking a break, but should back on Monday to weigh in.

karalekas commented 4 years ago

https://github.com/rigetti/pyquil/pull/1141#issuecomment-569303546

peterjc commented 4 years ago

Quoting that:

As for braket notation, I think that the double backticks or inline math suggestions are the way to go. I'd lean toward double backticks in most situations because we don't need to be rendering math when it is gratuitous, but I'm sure there will be situations where we are writing out equations where using :math: is more appropriate.

I agree, very pragmatic.

karalekas commented 4 years ago

closed in #1141