Code Style

Formatting tools

The Synapse codebase uses a number of code formatting tools in order to quickly and automatically check for formatting (and sometimes logical) errors in code.

The necessary tools are:

  • black, a source code formatter;
  • isort, which organises each file's imports;
  • ruff, which can spot common errors; and
  • mypy, a type checker.

Install them with:

pip install -e ".[lint,mypy]"

The easiest way to run the lints is to invoke the linter script as follows.

scripts-dev/lint.sh

It's worth noting that modern IDEs and text editors can run these tools automatically on save. It may be worth looking into whether this functionality is supported in your editor for a more convenient development workflow. It is not, however, recommended to run mypy on save as they take a while and can be very resource intensive.

General rules

  • Naming:
    • Use CamelCase for class and type names
    • Use underscores for function_names and variable_names.
  • Docstrings: should follow the google code style. See the examples in the sphinx documentation.
  • Imports:
    • Imports should be sorted by isort as described above.

    • Prefer to import classes and functions rather than packages or modules.

      Example:

      from synapse.types import UserID
      ...
      user_id = UserID(local, server)
      

      is preferred over:

      from synapse import types
      ...
      user_id = types.UserID(local, server)
      

      (or any other variant).

      This goes against the advice in the Google style guide, but it means that errors in the name are caught early (at import time).

    • Avoid wildcard imports (from synapse.types import *) and relative imports (from .types import UserID).

Configuration code and documentation format

When adding a configuration option to the code, if several settings are grouped into a single dict, ensure that your code correctly handles the top-level option being set to None (as it will be if no sub-options are enabled).

The configuration manual acts as a reference to Synapse's configuration options for server administrators. Remember that many readers will be unfamiliar with YAML and server administration in general, so it is important that when you add a configuration option the documentation be as easy to understand as possible, which includes following a consistent format.

Some guidelines follow:

  • Each option should be listed in the config manual with the following format:

    • The name of the option, prefixed by ###.

    • A comment which describes the default behaviour (i.e. what happens if the setting is omitted), as well as what the effect will be if the setting is changed.

    • An example setting, using backticks to define the code block

      For boolean (on/off) options, convention is that this example should be the opposite to the default. For other options, the example should give some non-default value which is likely to be useful to the reader.

  • There should be a horizontal rule between each option, which can be achieved by adding --- before and after the option.

  • true and false are spelt thus (as opposed to True, etc.)

Example:


modules

Use the module sub-option to add a module under modules to extend functionality. The module setting then has a sub-option, config, which can be used to define some configuration for the module.

Defaults to none.

Example configuration:

modules:
  - module: my_super_module.MySuperClass
    config:
      do_thing: true
  - module: my_other_super_module.SomeClass
    config: {}

Note that the sample configuration is generated from the synapse code and is maintained by a script, scripts-dev/generate_sample_config.sh. Making sure that the output from this script matches the desired format is left as an exercise for the reader!