diff --git a/.circleci/config.yml b/.circleci/config.yml
index 8bdcb50491..7ab327cb62 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -21,6 +21,7 @@ jobs:
- .venv
- run: pipenv run flake8
- run: pipenv run isort --check-only --diff .
+ - run: pipenv run black --target-version py37 --check --diff .
# Filter out known false positives, while preserving normal output and error codes.
# See https://github.com/motet-a/jinjalint/issues/18.
# And https://circleci.com/docs/2.0/configuration-reference/#default-shell-options.
diff --git a/.editorconfig b/.editorconfig
index 1b06b5e1fe..8d29457a73 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -9,10 +9,15 @@ indent_style = space
[Makefile]
indent_style = tab
-[*.{js,py}]
+[*.py]
+charset = utf-8
+indent_size = 4
+max_line_length = 88
+
+[*.js]
charset = utf-8
-[*.{py,html,rst,md}]
+[*.{html,rst,md}]
indent_size = 4
[*.{js,ts,tsx,json,yml,yaml,css,scss}]
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index ddae64e04c..3c9a6ad713 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,12 @@
default_language_version:
node: system
repos:
+ - repo: https://github.com/psf/black
+ rev: 22.1.0
+ hooks:
+ - id: black
+ language_version: python3
+ args: ['--target-version', 'py37']
- repo: https://github.com/timothycrosley/isort
# isort config is in setup.cfg
rev: 5.6.4
diff --git a/Makefile b/Makefile
index 5a6dbd7c79..ce43d82d1b 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
help:
@echo "clean-pyc - remove Python file artifacts"
@echo "develop - install development dependencies"
- @echo "lint - check style with flake8, sort python with isort, indent html, and lint frontend css/js"
+ @echo "lint - check style with black, flake8, sort python with isort, indent html, and lint frontend css/js"
@echo "test - run tests"
@echo "coverage - check code coverage"
@@ -17,6 +17,7 @@ develop: clean-pyc
npm install --no-save && npm run build
lint:
+ black --target-version py37 --check --diff .
flake8
isort --check-only --diff .
# Filter out known false positives, while preserving normal output and error codes.
diff --git a/docs/contributing/python_guidelines.rst b/docs/contributing/python_guidelines.rst
index 7a38aaff0a..255c52451f 100644
--- a/docs/contributing/python_guidelines.rst
+++ b/docs/contributing/python_guidelines.rst
@@ -4,11 +4,17 @@ Python coding guidelines
PEP8
~~~~
-We ask that all Python contributions adhere to the `PEP8 `_ style guide, apart from the restriction on line length (E501) and some minor docstring-related issues.
-The list of PEP8 violations to ignore is in the ``setup.cfg`` file, under the ``[flake8]`` header.
-You might want to configure the flake8 linter in your editor/IDE to use the configuration in this file.
+We ask that all Python contributions adhere to the `PEP8 `_ style guide.
+All files should be formatted using the `black `_ auto-formatter. This will be
+run by ``pre-commit`` if that is configured.
-In addition, import lines should be sorted according to `isort `_ 5.6.4 rules. If you have installed Wagtail's testing dependencies (``pip install -e .[testing]``), you can check your code by running ``make lint``.
+* The project repository includes an ``.editorconfig`` file. We recommend using
+ a text editor with `EditorConfig `_ support to avoid indentation and
+ whitespace issues. Python and HTML files use 4 spaces for indentation.
+
+In addition, import lines should be sorted according to `isort `_ 5.6.4 rules.
+If you have installed Wagtail's testing dependencies (``pip install -e '.[testing]'``), you can check your code by
+running ``make lint``.
Django compatibility
~~~~~~~~~~~~~~~~~~~~
diff --git a/setup.cfg b/setup.cfg
index e3189b7bae..dad55e8574 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -7,26 +7,24 @@ python-tag = py3
# D102: Missing docstring in public method
# D103: Missing docstring in public function
# D105: Missing docstring in magic method
-# E501: Line too long
# W503: line break before binary operator (superseded by W504 line break after binary operator)
# N806: Variable in function should be lowercase
-ignore = D100,D101,D102,D103,D105,E501,W503,N806
+# E203: Whitespace before ':'
+# E501: Line too long
+ignore = D100,D101,D102,D103,D105,W503,N806,E203,E501
exclude = wagtail/project_template/*,node_modules,venv,.venv
-max-line-length = 120
+max-line-length = 88
[doc8]
ignore = D001
ignore-path = _build,docs/_build
[isort]
-line_length=100
-multi_line_output=4
-skip=migrations,project_template,node_modules,.git,__pycache__,LC_MESSAGES,venv,.venv
-blocked_extensions=rst,html,js,svg,txt,css,scss,png,snap,tsx
+profile = black
+skip=migrations,project_template,node_modules,.git,__pycache__,LC_MESSAGES,venv,.venv,.tox
+blocked_extensions=rst,html,js,svg,txt,css,scss,png,snap,ts,tsx
known_first_party=wagtail
default_section=THIRDPARTY
-lines_between_types=1
-lines_after_imports=2
[tool:pytest]
django_find_project = false
diff --git a/setup.py b/setup.py
index c5e7e03d64..ecb7b0584c 100755
--- a/setup.py
+++ b/setup.py
@@ -55,6 +55,7 @@ testing_extras = [
# For coverage and PEP8 linting
'coverage>=3.7.0',
+ 'black==22.1.0',
'flake8>=3.6.0',
'isort==5.6.4', # leave this pinned - it tends to change rules between patch releases
'flake8-blind-except==0.1.1',