Coding standards
Guide to coding standards for Q-CTRL projects
Hierarchy of standards
Standards for coding style MUST be obtained from the following hierarchy in the order specified:
Third-party
“Third-party” refers to the third-party software you are using and the corresponding Third-party coding standards. For example, if you are using Django, you MUST use the Django coding style. If any of the following conditions hold then you MUST move to Language:
- You are not using third-party software
- The third-party software does not specify a coding standard
- The coding standard does not specify a rule (for example how to name variables)
Language
“Language” refers to the language you are using and the corresponding language coding standards. For example, if you are using Python, you MUST use the PEP 8 – Style Guide for Python Code. If any of the following conditions hold then you MUST move to First-party:
- The language does not specify a coding standard
- The coding standard does not specify a rule (for example how to name variables)
First-party
“First-party” refers to the First-party coding standards. These standards are developed by Q-CTRL and exist to specify standards that are not defined in the coding standards of the third-party software or language you are using.
Third-party coding standards
Third-party | Style | Docstrings | Testing | Linting |
---|---|---|---|---|
Django | Django coding style | numpydoc[++] | pytest | Pylint |
React | Airbnb React/JSX Style Guide | JSDoc | Jest and React Testing Library | ESLint and eslint-config-airbnb |
Terraform | Terraform Style Guide | N/A | N/A | terraform fmt |
Language coding standards
Language | Style | Docstrings | Testing | Linting |
---|---|---|---|---|
Go | Effective Go | Godoc | go test | go vet and Staticcheck |
GraphQL | GraphQL Rules | CommonMark[++] | N/A | graphql-schema-linter |
HTML | Prettier | N/A | HTMLProofer | N/A |
JavaScript | Airbnb JavaScript Style Guide() { | JSDoc | Jest | ESLint and eslint-config-airbnb |
Markdown | Prettier | N/A | N/A | Markdownlint |
Python | PEP 8 | numpydoc[++] | pytest, mypy | Pylint, Black, isort |
TypeScript | N/A | TSDoc | Jest | ESLint and eslint-config-airbnb-typescript |
YAML | Home Assistant YAML Style Guide | N/A | N/A | yamllint |
First-party coding standards
Variable naming
Unless prescribed otherwise by the framework or language (as described above), use the following rules when naming variables:
- Spell variable names out in full using American English spelling (for example
optimized_pulse
oroptimizedPulse
and NOTop
). - For variable names that are more than three words, use an acronym (for example
cpmg
and NOTcarr_purcell_meiboom_gill
orcarrPurcellMeiboomGill
). - For variable names that describe how many of an object there are, use
<object>_count
or<object>Count
(for examplepulse_count
orpulseCount
and NOTnumber_of_pulses
,numberOfPulses
,pulses_count
, orpulsesCount
). - Capitalize only the first letter of acronyms in camelCase or PascalCase names (for example
QctrlApiException
ortensorPwc
and NOTQCTRLAPIException
ortensorPWC
).
OIDC authentication provider
We currently use Keycloak for our OpenId Connect (OIDC) authentication. As OIDC is a standard for authentication and Keycloak is only our current provider all variables required for use related to OIDC should be prefixed with OIDC_
. Avoid KEYCLOAK_
unless you feel there is a valid reason for bringing that prefix back into use, in which case bring it up for discussion.
Docstrings
GraphQL
The CommonMark specification is unopinionated and/or inconsistent in a small number of cases. We therefore adopt the following additional standards.
- Inline math MUST start with
`$
and end with$`
:`$E=mc^2$`
- Block math MUST have the language set to
math
:```math E=mc^2 ```
-
Footnote referencing MUST use the following syntax:
This is my sentence with a footnote[^1]. [^1]: My reference.
numpydoc
The numpydoc standard is unclear, unopinionated, or inconsistent in a small number of cases. We therefore adopt the following additional standards.
- Place the opening and closing triple quotes of each docstring on their own lines, with no blank lines separating them from the contents, as follows:
""" <contents> """
- Use single backticks when referring to a module, function, class, method, parameter, variable, or attribute thereof; otherwise use double backticks (for example
`np.array`
,`int`
,`parameter_1`
,`CustomClass.attribute`
,`CustomClass.method`
, `value_1*value_2
,
function().result
, or
List[int]
`). Do not use backticks for literals such as 3.2, “string”, True, or None. -
We adopt the following on top of numpydoc’s style for parameter types, as is too simple for some complex types:
- We use Python 3.9 (or later) syntax to represent lists or tuples.
- If a parameter has requirements on its shape or data type, we include that information in parentheses.
- The word “optional” at the end of a type indicates that a parameter has a default value. If a parameter is nullable we add “or None” to its type.
Below are a few examples of how we might represent some types.
hamiltonian : Pwc or SparsePwc noise_operators : list[np.ndarray or Tensor or Stf] or None, optional lindblad_terms : list[tuple[float, np.ndarray or sp.sparse.spmatrix]] cost : Tensor(scalar, real) verbose : bool, optional sample_times : np.ndarray(1D, real)
numpydoc applied to GraphQL
The documentation for Boulder Opal functions comes from their corresponding GraphQL schemas. Write their docstrings in Markdown format, as required by the GraphQL specification. The documentation infrastructure automatically converts them into the reStructuredText (reST) format required by Python. The following example shows how you can do that for a hypothetical function calculate_object
:
extend type Mutation {
"""
# Description
Single-line description.
Extended summary about the functionality of the object.
It can contain multiple sentences.
# Warnings
Text explaining some behavior of the function that the user
should be aware of, such as possible mistakes a user could
make that are not described elsewhere.
# See Also
function1: Summary of function1, relating it to this function.
function_whose_name_makes_relationship_obvious
# Notes
A more detailed description that can contain references such as
[external links](www.someurl.com) and paper citations [1]_. It
can also contain mathematical formulas such as:
```math
H(t) = \Omega(t) \sigma_x,
```
where `$\Omega(t)$` is an inline formula.
# References
.. [1] A. Person, Some Journal **22**, 1 (2021).
"""
calculateObject(objectInput!): objectResult!
}
input objectInput{
"""
Short description of the parameter. A short description can span
over multiple lines if necessary.
"""
parameter: type!
"""Short description of the optional parameter. Defaults to 2."""
optional_parameter: int=2
}
Note that the sections following “Warnings” have to be placed after “Parameters” and “Returns” according to the numpydoc docstring guide. The documentation infrastructure automatically moves them to their appropriate location in the Python docstring. It also removes the “Description” section and converts the Markdown syntax into reStructuredText (reST).
The next sections explain the contents of each of these parts in more detail.
Single-line description
In this sentence, explain what the function does without repeating the function’s name nor its variables.
Extended summary
Add some sentences with a more detailed description of the functionality, including additional information about the function that is not obvious from its syntax. Leave out any internal implementation details that aren’t relevant to the user.
Warnings
If the user should be aware of situations that might cause unexpected behavior but that don’t necessarily raise errors or warnings, include one or more paragraphs of text about them.
See also
If there are other objects whose documentation contains relevant information about the element, include each of them in a new line, without empty lines between them.
Notes
Add a mathematical description of the theory behind the purpose of the object, including mathematical formulas if necessary. Make sure that your text makes sense on its own, and link to clear explanations of the key concepts if the user is not necessarily familiar with them.
In this section, you can include links to external pages with additional information about the functionality. Make sure that the text of the link is meaningful in itself, and only link to websites that are visible and useful globally. If you cite academic references, you can list them in full form in the References section.
You can also add a description of the algorithm if it’s relevant for the understanding the purpose of the object, and if the algorithm is not proprietary.
References
If you cite academic references in the “Notes” section, add a list of them here.