Summary:
The purpose of this document is to outline a migration guide for Django projects
using poetry
and nox
to migrate from using flake8
to ruff
for the
purposes of linting the project.
created: 20230502 updated: 20230510 updated: 20230513
The purpose of this document is to outline the steps necessary to migrate a
Django web application's linting infrastructure from flake8
to ruff
.
- Migration Outline
- Resources
- Installation
- Nox configuration
- Pre-commit configuration
- Remove
flake8
and related packages - Migrate projects identifiers from
setup.cfg
topyproject.toml
- Delete
setup.cfg
&.flake8
- Notes
1. Replace flake8 with ruff
2. Install ruff & initial config in pyproject.toml
3. Update nox lint session with ruff. Remove flake8 packages
4. Migrate project identifier fields from setup.cfg to pyproject.toml
5. Add ruff to pre-commit
6. Update README.md & Sphinx index with ruff usage & active ruleset
1. `poetry add --group -dev ruff`
2. `poetry update`
3. Edit pyproject.toml
- Add [tool.ruff] section
4. Run initial tests
- `ruff check .`
- Assuming that there were issues reported on this first pass, take a look
at the file names that generated error message. If the errors seem
reasonable, have `ruff` attempt to fix the errors by running the command,
`ruff check --fix .` on them. If you choose to keep the files formatted
as they currently are, then add them to the `per-file-ignores` section
of the ruff section, in the `pyproject.toml` file.
- NOTE: Do not commit any fixed files until AFTER the `nox` sesssion and
the `pre-commit` changes have been made AND commited. Otherwise, you will
end up in a sort of "race-condition" with `flake8` wanting to roll back
any changes that were made by running the `ruff check --fix .` command.
[tool.ruff]
select = [
"B", # flake8-bugbear
"C90", # mccabe
"DJ", # flake8-django
"E", # pycodestyle errors
"F", # pyflakes
"I", # isort
"S", # flake8-bandit
"W", # pycodestyle warnings
# "RUF", # ruff checks
]
ignore = [
"E501", # line too long ({width} > {limit} characters)
# "E203", # slice notation whitespace (not currently supported)
"E402", # module level import not at top of file
"E722", # do not use bare except
# "W503", # (not currently supported)
"ERA", # do not autoremove commented out code
]
# Allow autofix for all enabled rules (when `--fix`) is provided.
fixable = ["A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ", "EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET", "RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"]
unfixable = []
# Exclude a variety of commonly ignored directories.
exclude = [
".git",
".mypy_cache",
".nox",
".pytest_cache",
".ruff_cache",
".venv",
"__pycache__",
"__pypackages__",
"htmlcov",
"migrations",
"_build",
"build",
"dist",
"images",
"media",
"node_modules",
"venv",
]
# Same as Black.
line-length = 88
# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
# Assume Python 3.11.
target-version = "py311"
[tool.ruff.per-file-ignores]
# "accounts/tests/factories.py" = ["BLK100"] (Not supported)
# "accounts/tests/*" = ["BLK100"] (Not supported)
"accounts/tests/*" = ["S101", "S106"]
"config/test.py" = ["S101", "S106"]
"pages/tests/*" = ["S101", "S106"]
[tool.ruff.mccabe]
# Unlike Flake8, default to a complexity level of 10.
max-complexity = 10
- See django-start as a primary template
Edit noxfile.py
& remove flake8
references
Configure the lint session as follows:
@nox.session(python=["3.12", "3.11", "3.10", "3.9"])
def lint(session):
"""Lint using ruff."""
args = session.posargs or locations
install_with_constraints(
session,
"ruff",
)
session.run("ruff", "check", *args)
Proceed to run nox
tests with the new ruff
configuration.
Do not run ruff check --fix .
until flake8
is replaced in pre-commit
config.
- Add
ruff
to the.pre-commit-config.yaml
file & remove flake8 NOTE: Ruff's pre-commit hook should be placed after other formatting tools, such as Black and isort, unless you enable autofix, in which case, Ruff's pre-commit hook should run before other formatting tools, as Ruff's autofix behavior can output code changes that require reformatting.
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: 'v0.0.265'
hooks:
- id: ruff
args: [ --fix, --exit-non-zero-on-fix ]
Commit the changes to .pre-commit-config.yaml
before running ruff check --fix .
NOTE: Your CI/GitHub Actions may fail here if you have them running lint checks.
Run ruff check --fix .
and commit the fixes.
Also note that the URL for pre-commit differs from the main ruff package.
poetry remove flake8 flake8-bandit flake8-black flake8-bugbear flake8-import-order
Add the following to the [tool.poetry]
section of the pyproject.toml
file:
[tool.poetry]
name = "django-start"
version = "0.2.0"
description = "Basic Django project template"
authors = [
"Kevin Bowen <kevin.bowen@gmail.com>",
]
maintainers = [
]
license = "MIT"
readme = "README.md"
homepage = ""
repository = "https://github.com/kevinbowen777/repository_name.git"
documentation = ""
keywords = ["django", "web-application", "news"]
classifiers = [
"Development Status :: 2 - Pre-Alpha",
"Environment :: Web Environment",
"Framework :: Django",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Internet :: WWW/HTTP",
]
This assumes that setup.cfg
does not contain additional information for other
packages(e.g. mypy).
WHAT IS THE DIFFERENCE BETWEEN django-pytest AND pytest-django?????????
-
flake8 = "^6.0.0"
-
flake8-bandit = "^4.0.0"
-
flake8-black = "^0.3.3"
-
flake8-bugbear = "^23.0.0"
-
flake8-import-order = "^0.18.1"
poetry remove flake8 flake8-bandit flake8-black flake8-bugbear flake8-import-order
• Removing attrs (23.1.0)
• Removing bandit (1.7.5)
• Removing flake8 (6.0.0)
• Removing flake8-bandit (4.1.1)
• Removing flake8-black (0.3.6)
• Removing flake8-bugbear (23.3.23)
• Removing flake8-import-order (0.18.2)
• Removing gitdb (4.0.10)
• Removing gitpython (3.1.31)
• Removing pbr (5.11.1)
• Removing pycodestyle (2.10.0)
• Removing pyflakes (3.0.1)
• Removing smmap (5.0.0)
• Removing stevedore (5.0.0)
• Updating pyjwt (2.6.0 -> 2.7.0)
• Updating ruamel-yaml (0.17.24 -> 0.17.26)