Style¶
This document talks about code formatting, conventions, documentation, and any stylistic choices that we adhere to.
Try to run the formatters before every commit. This way, if you push up files for review, they are easy to read, even if your pull request isn’t yet ready to merge.
Python File Formatting¶
To install black in the environment
$ pip install black==19.10b0
Run the black formatter on all Python files.
$ black .
In VSCode open command pallette by Ctrl+Shift+p, open Settings(JSON) and add the properties.
{
"editor.formatOnSave": true,
"python.formatting.provider": "black",
}
JavaScript File Formatting¶
Run the js-beautify formatter on all JavaScript files. Use the following options.
$ js-beautify -r -n -s 2 file_to_format.js
Naming Conventions¶
Variables should always use underscores, as well as functions and methods.
Classes should use CamelCase.
Imports¶
Here’s an example of how we style our imports.
import re
import json
import inspect
import unittest.mock
from typing import Dict, Any
import sklearn.datasets
from dffml.record import Record
from dffml.configloader.configloader import BaseConfigLoader
from dffml.util.asynctestcase import AsyncTestCase
import dffml_model_scikit
from .helpers import my_helper_func
Here’s the generic format.
Standard Library Packages
Imports from
typing
should always be last regardless of XMAS tree style.
Empty line
Third Party Packages
Anything that doesn’t come with Python, things you
pip install
.
Empty line
Any imports from DFFML (the main package)
Empty line
Any imports from DFFML plugins (dffml-plugin_type-name packages)
Empty line
Imports of other files from the package we’re currently in (if we’re this far nested, likely this might only happen in an example package like
shouldi
or in the tests for an Official plugin).
In every block of imports (a block is a group of lines between empty lines), you should be following reverse reverse christmas tree style. This means that lines with the least characters go before lines with more characters. If you’re feeling wordy you can refer to this as “XMAS tree” instead of “reverse reverse christmas tree”.
Docstrings¶
We use Numpy style docstrings, as opposed to Google or the Sphinx default.
This is because Google does not support multiple return values, and it looks a bit more organized to have multi line descriptions for arguments indented on the following line.
More information on the Numpy docstiring format can be found here.
Example Docstring¶
from typing import Optional, Dict, Any, Tuple
def double_ret(
super_cool_arg, *, other_very_cool_arg: Optional[Dict[str, Any]] = None
) -> Tuple[str, Tuple]:
"""
This is the short description.
This is the longer description.
Parameters
----------
super_cool_arg : str
Argument we want the string value of.
other_very_cool_arg : dict, optional
Dictionary we want to turn into a tuple of (keys, values).
Returns
-------
str_super_cool_arg : str
``super_cool_arg`` as a string
keys_and_values : tuple
Keys and values of ``other_very_cool_arg`` returned as a tuple. Keys
are at index 0, values are at index 1.
Examples
-------
Here's how you use use this function
>>> double_ret(42, other_very_cool_arg={"feed": 0xFACE})
("42", ("feed"], [0xFACE],))
"""
if other_very_cool_arg is None:
other_very_cool_arg = {}
return (
str(super_cool_arg),
tuple(other_very_cool_arg.keys(), other_very_cool_arg.values()),
)