Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 0 additions & 52 deletions .flake8

This file was deleted.

61 changes: 6 additions & 55 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,50 +21,14 @@ repos:
name: Check conventional commit message
stages: [commit-msg]

# Sort imports.
- repo: https://github.com/pycqa/isort
rev: dac090ce4d9ee313d086e2e89ab1acb8c2664fa1 # frozen: 9.0.0a3
# Ruff formats and lints code.
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 3b3f7c3f57fe9925356faf5fe6230835138be230 # frozen: v0.15.17
hooks:
- id: isort
name: Sort import statements
args: [--settings-path, pyproject.toml]
stages: [pre-commit]

# Add Black code formatters.
- repo: https://github.com/ambv/black
rev: c6755bb741b6481d6b3d3bb563c83fa060db96c9 # frozen: 26.3.1
hooks:
- id: black
name: Format code
- id: ruff-format
args: [--config, pyproject.toml]
- repo: https://github.com/asottile/blacken-docs
rev: dda8db18cfc68df532abf33b185ecd12d5b7b326 # frozen: 1.20.0
hooks:
- id: blacken-docs
name: Format code in docstrings
args: [--line-length, '120']
additional_dependencies: [black==26.3.1]

# Upgrade and rewrite Python idioms.
- repo: https://github.com/asottile/pyupgrade
rev: 75992aaa40730136014f34227e0135f63fc951b4 # frozen: v3.21.2
hooks:
- id: pyupgrade
name: Upgrade code idioms
files: ^src/package/|^tests/
args: [--py310-plus]

# Similar to pylint, with a few more/different checks. For more available
# extensions: https://github.com/DmytroLitvinov/awesome-flake8-extensions
- repo: https://github.com/pycqa/flake8
rev: d93590f5be797aabb60e3b09f2f52dddb02f349f # frozen: 7.3.0
hooks:
- id: flake8
name: Check flake8 issues
files: ^src/package/|^tests/
types: [text, python]
additional_dependencies: [flake8-bugbear==25.11.29, flake8-builtins==3.1.0, flake8-comprehensions==3.17.0, flake8-docstrings==1.7.0, flake8-logging==1.8.0, flake8-mutable==1.2.0, flake8-noqa==1.4.0, flake8-print==5.0.0, flake8-pyi==25.5.0, flake8-pytest-style==2.2.0, flake8-rst-docstrings==0.4.0, pep8-naming==0.15.1]
args: [--config, .flake8]
- id: ruff-check
args: [--config, pyproject.toml, --fix, --exit-non-zero-on-fix]

# Run Pylint from the local repo to make sure venv packages
# specified in pyproject.toml are available.
Expand All @@ -89,17 +53,6 @@ repos:
types: [text, python]
args: [--explicit-package-bases, --config-file, pyproject.toml]

# Check for potential security issues.
- repo: https://github.com/PyCQA/bandit
rev: 92ae8b82fb422a639f0ed8d99e96cea769594e08 # frozen: 1.9.4
hooks:
- id: bandit
name: Check for security issues
args: [--configfile, pyproject.toml]
files: ^src/package/|^tests/
types: [text, python]
additional_dependencies: ['bandit[toml]']

# Enable a whole bunch of useful helper hooks, too.
# See https://pre-commit.com/hooks.html for more hooks.
- repo: https://github.com/pre-commit/pre-commit-hooks
Expand Down Expand Up @@ -146,8 +99,6 @@ repos:
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: 4380fbb73a154b5f5624794c1c78d9719ccc860f # frozen: v2.16.0
hooks:
- id: pretty-format-ini
args: [--autofix]
- id: pretty-format-yaml
args: [--autofix]
# Commenting this out because https://github.com/pappasam/toml-sort/issues/11
Expand Down
12 changes: 5 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,10 @@ audit:
python -m pip_audit --skip-editable --desc on --fix --dry-run

# Run some or all checks over the package code base.
.PHONY: check check-code check-bandit check-flake8 check-lint check-mypy check-actionlint
check-code: check-bandit check-flake8 check-lint check-mypy check-actionlint
check-bandit:
pre-commit run bandit --all-files
check-flake8:
pre-commit run flake8 --all-files
.PHONY: check check-code check-ruff check-lint check-mypy check-actionlint
check-code: check-ruff check-lint check-mypy check-actionlint
check-ruff:
pre-commit run ruff --all-files
check-lint:
pre-commit run pylint --all-files
check-mypy:
Expand Down Expand Up @@ -259,7 +257,7 @@ dist-clean:
rm -fr dist/*
rm -f requirements.txt
clean: dist-clean
rm -fr .coverage .hypothesis/ .mypy_cache/ .pytest_cache/
rm -fr .coverage .hypothesis/ .mypy_cache/ .pytest_cache/ .ruff_cache/
rm -fr docs/_build/

# Remove code caches, or the entire virtual environment.
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The badges above give you an idea of what this project template provides. It’s

### Typing

The package requires a minimum of [Python 3.10](https://www.python.org/downloads/release/python-31020/), and it supports [Python 3.11](https://www.python.org/downloads/release/python-31115/), [Python 3.12](https://www.python.org/downloads/release/python-31213/), [Python 3.13](https://www.python.org/downloads/release/python-31313/), and [Python 3.14](https://www.python.org/downloads/release/python-3144/) ( (default). All code requires comprehensive [typing](https://docs.python.org/3/library/typing.html). The [mypy](http://mypy-lang.org/) static type checker and the [flake8-pyi](https://github.com/PyCQA/flake8-pyi) plugin are invoked by git hooks and through a Github Action to enforce continuous type checks on Python source and [stub files](https://peps.python.org/pep-0484/#stub-files). Make sure to add type hints to your code or to use [stub files](https://mypy.readthedocs.io/en/stable/stubs.html) for types, to ensure that users of your package can `import` and type-check your code (see also [PEP 561](https://www.python.org/dev/peps/pep-0561/)).
The package requires a minimum of [Python 3.10](https://www.python.org/downloads/release/python-31020/), and it supports [Python 3.11](https://www.python.org/downloads/release/python-31115/), [Python 3.12](https://www.python.org/downloads/release/python-31213/), [Python 3.13](https://www.python.org/downloads/release/python-31313/), and [Python 3.14](https://www.python.org/downloads/release/python-3144/) (default). All code requires comprehensive [typing](https://docs.python.org/3/library/typing.html). The [mypy](http://mypy-lang.org/) static type checker and ruff’s [pyi](https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi) plugin are invoked by git hooks and through a Github Action to enforce continuous type checks on Python source and [stub files](https://peps.python.org/pep-0484/#stub-files). Make sure to add type hints to your code or to use [stub files](https://mypy.readthedocs.io/en/stable/stubs.html) for types, to ensure that users of your package can `import` and type-check your code (see also [PEP 561](https://www.python.org/dev/peps/pep-0561/)).

### Quality assurance

Expand Down Expand Up @@ -146,7 +146,7 @@ make upgrade

Using the pre-commit tool and its `.pre-commit-config.yaml` configuration, the following git hooks are active in this repository:

- When committing code, a number of [pre-commit hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_committing_workflow_hooks) ensure that your code is formatted according to [PEP 8](https://www.python.org/dev/peps/pep-0008/) using the [`black`](https://github.com/psf/black) tool, and they’ll invoke [`flake8`](https://github.com/PyCQA/flake8) (and various plugins), [`pylint`](https://github.com/PyCQA/pylint) and [`mypy`](https://github.com/python/mypy) to check for lint and correct types. There are more checks, but those two are the important ones. You can adjust the settings for these tools in the `pyproject.toml` or `.flake8` configuration files.
- When committing code, a number of [pre-commit hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_committing_workflow_hooks) ensure that your code is formatted according to [PEP 8](https://www.python.org/dev/peps/pep-0008/) using [ruff’s formatter](https://docs.astral.sh/ruff/formatter/), and they’ll invoke [`ruff`](https://docs.astral.sh/ruff/linter/) (and various plugins), [`pylint`](https://github.com/PyCQA/pylint) and [`mypy`](https://github.com/python/mypy) to check for Python code flakes and lint and for correct types. You can adjust the settings for these tools in the `pyproject.toml` configuration file.
- The [commit message hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_committing_workflow_hooks) enforces [conventional commit messages](https://www.conventionalcommits.org/) and that, in turn, enables a _semantic release_ of this package on the Github side: upon merging changes into the `release` branch, the [release action](https://github.com/jenstroeger/python-package-template/blob/main/.github/workflows/release.yaml) uses the [Commitizen tool](https://commitizen-tools.github.io/commitizen/) to produce a [changelog](https://en.wikipedia.org/wiki/Changelog) and it computes the next version of this package and publishes a release — all based on the commit messages of a release.
- Using a [pre-push hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_other_client_hooks) this package is also set up to run [`pytest`](https://github.com/pytest-dev/pytest); in addition, the [`coverage`](https://github.com/nedbat/coveragepy) plugin makes sure that _all_ of your package’s code is covered by unit tests and [Hypothesis](https://hypothesis.works/) and [Faker](https://github.com/joke2k/faker) are already installed to help with generating test case payloads.
- The [`actionlint`](https://github.com/Mateusz-Grzelinski/actionlint-py) hook is set up to lint GitHub Actions workflows. If [`shellcheck`](https://github.com/koalaman/shellcheck) is installed on the system, `actionlint` runs `shellcheck` to lint the `run` steps in GitHub Actions. Note that `shellcheck` is available on [Ubuntu GitHub Actions runners](https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md) by default.
Expand All @@ -157,13 +157,13 @@ You can also run these hooks manually, which comes in very handy during daily de
make check-code
```

runs all the code checks (i.e. `bandit`, `flake8`, `pylint`, `mypy`, `actionlint`), whereas
runs all the code checks (i.e. `ruff`, `pylint`, `mypy`, `actionlint`), whereas

```bash
make check
```

runs _all_ installed git hooks over your code. For more control over the code checks, the Makefile also implements the `check-bandit`, `check-flake8`, `check-lint`, `check-mypy`, and `check-actionlint` goals.
runs _all_ installed git hooks over your code. For more control over the code checks, the Makefile also implements the `check-ruff`, `check-lint`, `check-mypy`, and `check-actionlint` goals.

## Testing

Expand Down
72 changes: 51 additions & 21 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,6 @@ Documentation = "https://github.com/jenstroeger/python-package-template/wiki"
Issues = "https://github.com/jenstroeger/python-package-template/issues"


# https://bandit.readthedocs.io/en/latest/config.html
# Skip test B101 because of issue https://github.com/PyCQA/bandit/issues/457
[tool.bandit]
tests = []
skips = ["B101"]


# https://github.com/psf/black#configuration
[tool.black]
line-length = 120


# https://github.com/commitizen-tools/commitizen
# https://commitizen-tools.github.io/commitizen/bump/
[tool.commitizen]
Expand Down Expand Up @@ -134,15 +122,6 @@ exclude = [
]


# https://pycqa.github.io/isort/
[tool.isort]
profile = "black"
multi_line_output = 3
line_length = 120
skip_gitignore = true
filter_files = true


# https://mypy.readthedocs.io/en/stable/config_file.html#using-a-pyproject-toml
[tool.mypy]
# mypy_path =
Expand Down Expand Up @@ -175,6 +154,7 @@ ignore_missing_imports = true


# https://pylint.pycqa.org/en/latest/user_guide/configuration/index.html
# https://github.com/astral-sh/ruff/issues/970
[tool.pylint.main]
fail-under = 10.0
load-plugins = [
Expand Down Expand Up @@ -274,3 +254,53 @@ markers = [
"integration: more complex application-level integration tests.",
"performance: performance tests.",
]


# https://docs.astral.sh/ruff/formatter/
# https://docs.astral.sh/ruff/linter/
[tool.ruff]
line-length = 120

[tool.ruff.format]
docstring-code-format = true
docstring-code-line-length = 88

# https://docs.astral.sh/ruff/configuration/
# https://docs.astral.sh/ruff/rules/
[tool.ruff.lint]
exclude = ["docs/*"]
select = [
"A", # flake8-builtins
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"D", # pydocstyle
"DOC", # pydoclint
"E", # pycodestyle
"F", # pyflakes
"I", # isort
"LOG", # flake8-logging
"N", # pep8-naming
"PIE", # flake8-pie
"PT", # flake8-pytest-style
"PYI", # flake8-pyi
"RUF", # ruff-specific rules
"S", # flake8-bandit
"T20", # flake8-print
"UP", # pyupgrade
]
ignore = [
"D105", # D105: Missing docstring in magic method
"E203", # E203: whitespace before ‘,’, ‘;’, or ‘:’ (not Black compliant)
"E501", # E501: line too long (managed better by Bugbear's B950)
]

[tool.ruff.lint.flake8-pytest-style]
fixture-parentheses = true

[tool.ruff.lint.per-file-ignores]
"tests/*" = [
"S101", # S101 Use of `assert` detected
]

[tool.ruff.lint.pydocstyle]
convention = "numpy"
8 changes: 3 additions & 5 deletions tests/integration/test_something.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
# Copyright (c) 2021-2026 CODEOWNERS
# This code is licensed under MIT license, see LICENSE.md for details.

# https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b404-import-subprocess
import subprocess # nosec B404
import subprocess

import pytest

Expand All @@ -13,7 +12,6 @@
def test_package() -> None:
"""Test the Something command."""
# For testing we disable this warning here:
# https://bandit.readthedocs.io/en/latest/plugins/b603_subprocess_without_shell_equals_true.html
# https://bandit.readthedocs.io/en/latest/plugins/b607_start_process_with_partial_path.html
completed = subprocess.run(["something"], check=True, shell=False) # nosec B603, B607
# https://docs.astral.sh/ruff/rules/start-process-with-partial-path/
completed = subprocess.run(["something"], check=True, shell=False) # noqa: S607
assert completed.returncode == 0
Loading