Skip to main content

A more configurable Python code formatter

Project description

Cercis

Cercis /ˈsɜːrsɪs/ is a Python code formatter that is more configurable than Black (a popular Python code formatter).

Cercis is also the name of a deciduous tree that boasts vibrant pink to purple-hued flowers, which bloom in early spring.

This code repository is forked from and directly inspired by Black. The original license of Black is included in this repository (see LICENSE_ORIGINAL).

1. Motivations

While we like the idea of auto-formatting and code readability, we take issue with some style choices and the lack of configurability of the Black formatter. Therefore, Cercis aims at providing some configurability beyond Black's limited offering.

2. Installation and usage

2.1. Installation

Cercis can be installed by running pip install cercis. It requires Python 3.7+ to run. If you want to format Jupyter Notebooks, install with pip install "cercis[jupyter]".

2.2. Usage

2.2.1. Command line usage

To get started right away with sensible defaults:

cercis {source_file_or_directory}

You can run Cercis as a package if running it as a script doesn't work:

python -m cercis {source_file_or_directory}

The commands above reformat entire file(s) in place.

2.2.2. As pre-commit hook

To format Python files (.py), put the following into your .pre-commit-config.yaml file. Remember to replace <VERSION> with your version of this tool (such as v0.1.0):

- repo: https://github.com/jsh9/cercis
  rev: <VERSION>
  hooks:
    - id: cercis
      args: [--line-length=88]

To format Jupyter notebooks (.ipynb), put the following into your .pre-commit-config.yaml file:

- repo: https://github.com/jsh9/cercis
  rev: <VERSION>
  hooks:
    - id: cercis-jupyter
      args: [--line-length=88]

See pre-commit for more instructions. In particular, here is how to specify arguments in pre-commit config.

3. The code style

The code style in Cercis is largely consistent with the style of of Black.

The main difference is that Cercis provides several configurable options that Black doesn't. That's also our main motivation of creating Cercis.

Cercis offers the following configurable options:

The next section (How to configure Cercis) contains detailed instructions of how to configure these options.

3.1. Extra indentation at function definition

# Cercis's default style
def some_function(
        arg1_with_long_name: str,
        arg2_with_longer_name: int,
        arg3_with_longer_name: float,
        arg4_with_longer_name: bool,
) -> None:
    ...
# Black's style (not configurable)
def some_function(
    arg1_with_long_name: str,
    arg2_with_longer_name: int,
    arg3_with_longer_name: float,
    arg4_with_longer_name: bool,
) -> None:
    ...

We choose to indent an extra 4 spaces because it adds a clear visual separation between the function name and the argument list. Not adding extra indentation is also called out as wrong in the the official PEP8 style guide.

If you do not like this default, you can easily turn it off.

Option
Name --function-definition-extra-indent
Abbreviation -fdei
Default True
Command line usage cercis -fdei=False myScript.py
pyproject.toml usage function-definition-extra-indent = true under [tool.cercis]
pre-commit usage args: [--function-definition-extra-indent=False]

3.2. Single quote vs double quote

Both Cercis and Black default to using double quotes. But in Cercis you can specify using single quotes as the default style.

Option
Name --single-quote
Abbreviation -sq
Default False
Command line usage cercis -sq=True myScript.py
pyproject.toml usage single-quote = true under [tool.cercis]
pre-commit usage args: [--single-quote=False]

3.3. "Simple" lines with long strings

By default, Black wraps lines that exceed length limit. But for very simple lines (such as assigning a long string to a variable), line wrapping is not necessary.

Also, as seen below, Black's default style can be a bit hard to predict (var2 vs var3).

# Cercis's default style
var1 = "not wrapped even if too long"

var2 = "not wrapped even if too long"  # comment

var3 = "not wrapped, if the line gets too long"
# Black's style (not configurable)
var1 = (
    "wrapped when too long"
)

var2 = (
    "wrapped when too long"
)  # comment

var3 = "not wrapped, if the line gets too long"
Option
Name --wrap-line-with-long-string
Abbreviation -wl
Default False
Command line usage cercis -wl=True myScript.py
pyproject.toml usage wrap-line-with-long-string = true under [tool.cercis]
pre-commit usage args: [--wrap-line-with-long-string=False]

4. How to configure Cercis

4.1. Dynamically in the command line

Here are some examples:

  • cercis --single-quote=True myScript.py to format files to single quotes
  • cercis --function-definition-extra-indent=False myScript.py to format files without extra indentation at function definition
  • cercis --line-length=79 myScript.py to format files with a line length of 79 characters

4.2. In your project's pyproject.toml file

You can specify the options under the [tool.cercis] section of the file:

[tool.cercis]
line-length = 88
function-definition-extra-indent = true
single-quote = false

4.3. In your project's .pre-commit-config.yaml file

You can specify the options under the args section of your .pre-commit-config.yaml file.

For example:

repos:
  - repo: https://github.com/jsh9/cercis
    rev: 0.1.0
    hooks:
      - id: cercis
        args: [--function-definition-extra-indent=False, --ling-length=79]
  - repo: https://github.com/jsh9/cercis
    rev: 0.1.0
    hooks:
      - id: cercis-jupyter
        args: [--function-definition-extra-indent=False, --line-length=79]

4.4. Specify options in tox.ini

Currently, Cercis does not support a config section in tox.ini. Instead, you can specify the options in pyproject.toml.

Change Log

[0.1.1] - 2023-05-03

Added

  • A configurable option: single-quote, for formatting code into single quotes

Full changelog

[0.1.0] - 2023-04-30

This is the initial version that branches away from Black (commit: e712e4)

Changed

  • The default indentation within a function definition (when line wrap happens) is now 8 spaces. (Black's default is 4, which is not PEP8-compatible)
  • Updated README, because cercis now branches away from Black

Added

  • A configurable option (function-definition-extra-indent) is added instead of enforcing 8 spaces for everyone

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cercis-0.1.2.tar.gz (280.7 kB view details)

Uploaded Source

Built Distribution

cercis-0.1.2-py3-none-any.whl (166.7 kB view details)

Uploaded Python 3

File details

Details for the file cercis-0.1.2.tar.gz.

File metadata

  • Download URL: cercis-0.1.2.tar.gz
  • Upload date:
  • Size: 280.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for cercis-0.1.2.tar.gz
Algorithm Hash digest
SHA256 3deae64adba3f34aba4a4c97e8cd85cf54f0799f86de69e199ba353aadc6e164
MD5 5baae10e05255143de8bc9b4b28c7af7
BLAKE2b-256 c0278e05b58aecbff4e789ea8bc6c9a0b155e65b857bf77b9bee26c6ec5fc710

See more details on using hashes here.

Provenance

File details

Details for the file cercis-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: cercis-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 166.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for cercis-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 46765a7a8cb4871a8b6a379cebe8cfcae2064f62822b3bc5c040311b5eacd9f6
MD5 190d1cb08f8c6ecb83f7c737b9f80fe0
BLAKE2b-256 27a98a7af5c73ee0e8542e3a71dfc574cdabd5e9c40692e8e19daf4d7e751dc2

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page