Simplifying line length with pre-commit, flake8, black, isort, pylint, etc

9.7k views Asked by At

When using multiple tools that either check or format python files, is there a way to set line length once for all?

Currently I have:

.flake8 file:

max-line-length = 120

.isort.cfg file:

line-length = 120

.black file:

line-length = 120

.pylintrc file:

max-line-length = 120
2

There are 2 answers

0
pythoninthegrass On

If you use Poetry, it's possible to configure all the above in the pyproject.toml file as a workaround.

For example, my project looks like this:

[tool.black]
line-length = 130
target-version = ['py310']
include = '\.pyi?$'
exclude = '''
/(
    \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
)/
'''

[tool.flake8]
max-line-length = 130
extend-ignore = ["D203", "E203", "E251", "E266", "E302", "E305", "E401", "E402", "E501", "F401", "F403", "W503"]
exclude = [".git", "__pycache__", "dist"]
max-complexity = 10

[tool.isort]
atomic = true
profile = "black"
line_length = 130
skip_gitignore = true

This is combined with a .pre-commit-config.yaml file that kicks off each tool upon commits, respectively:

fail_fast: true

repos:
  - repo: https://github.com/ambv/black
    rev: 22.10.0
    hooks:
    - id: black
  - repo: https://gitlab.com/pycqa/flake8
    rev: 3.9.2
    hooks:
    - id: flake8
  - repo: https://github.com/timothycrosley/isort
    rev: 5.10.1
    hooks:
    - id: isort

Haven't used the individual linters much outside of pre-commit hooks, but would think they behave the same way when run via poetry shell or poetry run black --check --diff file_name.py for instance.

0
willwrighteng On

Adding to @pythoninthegrass 's answer:

A method I use frequently is generating project boilerplate code using cookiecutter, which allows for all instances to be templated using jinja syntax

for example

pyproject.toml

[tool.black]
target-version = ["py39"]
line-length = {{ cookiecutter.line_length }}

[tool.isort]
py_version = 39
line_length = {{ cookiecutter.line_length }}

along with your cookiecutter.json file

{
  "project_name": "python-project",
  "line_length": 88
}

using your example

.flake8 file:

max-line-length = {{ cookiecutter.line_length }}

.isort.cfg file:

line-length = {{ cookiecutter.line_length }}

.black file:

line-length = {{ cookiecutter.line_length }}

.pylintrc file:

max-line-length = {{ cookiecutter.line_length }}

execution

python3 -m pip install --user cookiecutter
git clone https://github.com/will-wright-eng/cookiecutter-configs.git
cd cookiecutter-configs/
cookiecutter project-cc-template --no-input

directory structure

$tree . -a
.
├── .gitignore
├── README.md
└── project-cc-template
    ├── cookiecutter.json
    └── {{ cookiecutter.project_slug }}
        ├── .black
        ├── .flake8
        ├── .isort.cfg
        ├── .pylintrc
        └── pyproject.toml