Skip to content

Code Style


General

Docstrings

Docstrings are required for every function, class and method. No specific style is required. Though the Google docstring format is encouraged, we expect that most of the relevant information can be gleaned from both the function signature's type-hints and descriptive parameter names. The docstring should serve to give additional context/flavour beyond that which can be gained from the code itself.

Docstring Example
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Bad
def tokenize(text: str,
             special_cases: Dict[str, Iterable[str]]
             ) -> spacy.tokens.doc.Doc:
    """
    tokenize a string
    """

# Good
def tokenize(text: str,
             special_cases: Dict[str, Iterable[str]]
             ) -> spacy.tokens.doc.Doc:
    """
    Convert a string to a spacy tokenized document
    """

# Best
def tokenize(text: str,
             special_cases: Dict[str, Iterable[str]]
             ) -> spacy.tokens.doc.Doc:
    """
    Convert a string to a spacy tokenized document
    Args:
        text: the text string to be tokenized
        special_cases: special token cases used to initialize the nlp framework

    Returns:
        the input text tokens
    """

Variable/Parameter Naming

Variable and parameter names should be as self-describing as possible. Brevity is not a concern here. Here are some common examples for writing good self-documenting code:

Single Letter Variable Names
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Incorrect
s = 726

# Correct
elapsed_time_seconds = 726

# Incorrect
for n in nodes:
    print(n)

# Correct
for node in nodes:
    print(node)
Abbreviated Variable Names
1
2
3
4
5
6
7
8
# Incorrect
r = requests.get(url)

# Incorrect
resp = reqeusts.get(url)

# Correct
response = requests.get(url)
Type Ambiguous Variable Names
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Incorrect
food = ["apple", "banana"] 

# Incorrect
foods = ["apple", "banana"] 

# Correct
# Use type annotations if the name is somewhat ambiguous
foods: List[str] = ["apple", "banana"] 

# Correct
# The type is contained in the name
foods_list = ["apple", "banana"] 

# Correct
# Both of the above styles
foods_list: List[str] = ["apple", "banana"] 

Pre-Commit Hooks

Fidescls includes a .pre-commit-config.yaml to facilitate running CI checks before pushing up to a PR. The pre-commit package is included in the dev-requirements.txt. Once that is installed, follow these steps to get up and running:

  1. pre-commit install - This is a one-time setup step to create the git pre-commit hooks.
  2. These pre-commit hooks will now run automatically. However, you can also use pre-commit run to run them manually once all of your changes have been staged.

NOTE: A Python interpreter must be available from wherever the git commands are being run, as this is required to run the pre-commit package.

CI Checks

CI checks are stored as targets within the Makefile, and can be run from the top-level fidescls directory with the following pattern:

Pattern
1
make <lowercased_name>
Examples
1
2
3
make black
make mypy
make xenon

Black formatting

Fidescls's code is formatted using the black style. This style is checked in a CI step, and merges to master are prevented if code does not conform.

A number of extensions are available for popular editors that will automatically apply black to your code.

Pylint

Fidescls's code is linted using pylint. Linter checks run as part of a CI step and merges to master are prevented if code does not conform.

Mypy

Fidescls's code is statically-typed using mypy. Type checking is validated as a CI step, and merges to master are prevented if code does not pass type checks. As a general rule, mypy typing requires all function arguments and return values to be annotated.

Xenon

Fidescls's code is checked for its cyclomatic-complexity by Xenon. If a single logical piece of code is deemed too complex, then a CI step will fail, at which point the focus should be on breaking up said complex function/method/class.

Back to top