-
Notifications
You must be signed in to change notification settings - Fork 154
Code Style Guide
If your working IDE is VSCode, we recommend you to install and use these extensions:
- Code Spell Checker: Check the spelling of your code and help you fix the typo in time.
- EditorConfig for VS Code: Automatically fix formatting issues according to the .editorconfig file when saving.
- Trailing Spaces: Automatically remove the unwanted trailing spaces when saving.
MARO uses pre-commit to manage the automatic format toolchain. The detailed configuration can be found in .pre-commit-config.yaml
. You could run pre-commit install
to install pre-commit so that pre-commit will run on every commit. You could also manually run pre-commit by executing:
pre-commit run --all-files
It is okay to run part of hooks by executing pre-commit run <hook_id>
, but we strongly recommend running the entire workflow as the last step before you commit your changes.
In general, we involve autoflake
, add-trailing-comma
, black
, isort
, and flake8
in the pre-commit. To find the detailed configuration of each tool:
-
black
andisort
:.github/linters/pyproject.toml
-
flake8
:.github/linters/tox.ini
We have an identical workflow to check codes on Github. Any pull request without passing all checks will be denied.
Currently, add-trailing-comma
, autoflake
and black
in pre-commit will change the file in-place (i.e., re-write the source files). Meanwhile, isort
and flake8
will not change the files. Instead, they will run in "check-only" mode, i.e., only raise errors. You should fix these errors by yourselves.
For isort
, if you wish to let it modify source files in-place, you could remove the --check
in .pre-commit-config.yaml
in the isort
section.
Since pre-commit might make in-place changes, please ALWAYS check the git diff carefully before actually submitting your code to avoid unexpected errors.
It is worthy to notice that Black will try to collapse multiple lines into one when possible. If you want to leave the code as what it is, you could use "magic trailing comma" to interact with Black. Please see Black's documentation for details. MARO uses add-trailing-comma
to solve this issue, and that is why we will run add-trailing-comma
and black
two times.
Here is a simple example:
# The following code will be reformatted to `obj = func(param1, param2)` by Black.
obj = func(
param1,
param2
)
# The following code will not be reformatted by Black since there is a magic trailing comma at the end.
obj = func(
param1,
param2,
)
To utilize this feature, you can manually add commas for the code that you do not want Black to wrap. You can also run add-trailing-comma
before running Black to solve this issue automatically.
If there are files that should not be modified / checked by pre-commit, you could explicitly configure them in the configuration files. For example, files that should be ignored by Black could be specified in .github/linters/pyproject.toml
. Files that should be ignored by isort
could be specified in .github/linters/pyproject.toml
or just add # isort: skip_file
at the beginning of the files.
flake8
is a little special. In addition to configuring in .github/linters/tox.ini
, you also need to add the ignored files in .pre-commit-config.yaml
, since the exclude
section in .github/linters/tox.ini
will not be used by pre-commit.
Generally speaking, we follow Google Python Style Guide, and the differences/highlights are the below points:
- Line length: maximum line length is 120 characters.
- Comments: never mix code and comment in one line.
- Parameter list: use type declaration as much as you can.
- Function call: use keyword arguments.
- String format: use
"
if you can, usef-Strings
. - Log: use
maro.utils.logger
. - Exception: define them in
maro.utils.exception
. - Docstring for class/function.
- Definition of class/function.
- Arguments explanation.
- Returns explanation.
class XxxYyyZzz():
"""Summary of the class here.
Details.
Attributes:
public_attribute_1: Introduction of this attribute.
public_attribute_2: ...
...
"""
def __init___(self, quota: int, is_test: bool):
"""One line summary.
Details.
Args:
quota (int): Details.
E.g. ...
is_test (bool): Details.
...
"""
pass
def run(self, para1: int, para2: bool = True):
"""One line summary.
Details.
Args:
para1 (int): Details.
para2 (bool): Details. Defaults to True.
Returns:
type: Details.
"""
pass
-
Naming
- File naming: xxx_yyy_zzz.py (noun structure)
- Abstract class file naming: abs_xxx_yyy.py
- Class naming: XxxYyyZzz (noun structure)
- Abstract class naming: AbsXxxYyy
- Function naming: verb/verb + noun
- Private function: _xxx_yyy
- Public function: xxx_yyy
- File naming: xxx_yyy_zzz.py (noun structure)
-
Import
- Import blocks order: native lib, 3rd party lib, privative lib.
- In each import block, package are listed in alphabet order.
- Between blocks, a blank line is needed.
import io import os import numpy as np import pandas as pd from maro.backends.frame import FrameBase from maro.event_buffer import EventBuffer
-
File format:
LF
.