Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e3eca22
fix(deps): pin `flit_core` to match the already pinned `flit` package…
jenstroeger Aug 6, 2026
99a113a
fix(ci): force Dependabot to always widen the version range of depend…
jenstroeger Aug 19, 2026
afaea91
revert(ci): undo force Dependabot to always widen the version range o…
jenstroeger Aug 19, 2026
93b1cb4
fix(ci): force Dependabot to always increase the version range of dep…
jenstroeger Aug 27, 2026
345dca5
chore(deps-dev): bump twine from 6.2.0 to 7.0.0 (#1267)
dependabot[bot] Oct 19, 2026
09508b4
chore(deps-dev): bump pytest-benchmark from 5.2.3 to 5.3.0 (#1299)
dependabot[bot] Oct 19, 2026
5d0585d
chore(deps-dev): bump pytest-env from 1.7.0 to 1.7.1 (#1308)
dependabot[bot] Oct 19, 2026
e7bfb19
chore(deps-dev): update mypy requirement from <2.4.0,>=2.0.0 to >=2.0…
dependabot[bot] Oct 19, 2026
a13ee73
chore(deps-dev): update pylint requirement from <4.1.0,>=4.0.0 to >=4…
dependabot[bot] Oct 19, 2026
2f2d176
chore(deps): bump github/codeql-action/upload-sarif from 4.36.3 to 4.…
dependabot[bot] Oct 19, 2026
05227ae
chore(deps-dev): update hypothesis requirement from <6.161.6,>=6.21.0…
dependabot[bot] Oct 19, 2026
541acf6
chore(deps-dev): bump faker from 40.36.0 to 40.43.0 (#1334)
dependabot[bot] Oct 19, 2026
9d0ae2f
chore(deps-dev): bump commitizen from 4.16.5 to 4.19.2 (#1332)
dependabot[bot] Oct 19, 2026
01c0d6f
chore(deps-dev): update flit and flit-core requirements from <4.0.0,>…
dependabot[bot] Oct 19, 2026
35d4436
chore(deps): bump the pre-commit group across 1 directory with 2 upda…
dependabot[bot] Oct 19, 2026
16832c3
chore(deps): bump step-security/harden-runner from 2.20.0 to 2.22.1 (…
dependabot[bot] Oct 20, 2026
23acfcd
chore(deps): bump ossf/scorecard-action from 2.4.4 to 2.5.0 (#1333)
dependabot[bot] Oct 20, 2026
9c749e5
docs: enable a few additional features for the generated Markdown doc…
jenstroeger Oct 20, 2026
3d169c5
feat: add support for Python 3.14 and retire support for Python 3.10 …
jenstroeger Oct 20, 2026
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
1 change: 1 addition & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ version: 2
updates:
- package-ecosystem: pip
directory: /
versioning-strategy: increase-if-necessary
schedule:
interval: weekly
cooldown:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/_build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#
# Even though we run the build in a matrix to check against different platforms, due to a known
# limitation of reusable workflows that do not support setting strategy property from the caller
# workflow, we only generate artifacts for ubuntu-latest and Python 3.14, which can be used to
# workflow, we only generate artifacts for ubuntu-latest and Python 3.15, which can be used to
# create a release. For details see:
#
# https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations
Expand Down Expand Up @@ -35,7 +35,7 @@ permissions:
contents: read
env:
ARTIFACT_OS: ubuntu-latest # The default OS for release.
ARTIFACT_PYTHON: '3.14' # The default Python version for release.
ARTIFACT_PYTHON: '3.15' # The default Python version for release.

jobs:
check-and-build-package:
Expand All @@ -51,11 +51,11 @@ jobs:
# It is recommended to pin a Runner version specifically:
# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners
os: [ubuntu-latest, macos-latest, windows-latest]
python: ['3.10', '3.11', '3.12', '3.13', '3.14']
python: ['3.11', '3.12', '3.13', '3.14', '3.15']
steps:

- name: Harden Runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
disable-sudo: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_generate-rebase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
steps:

- name: Harden Runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_wiki-documentation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
steps:

- name: Harden Runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
disable-sudo: true
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ jobs:
matrix:
# Learn more about CodeQL language support at https://git.io/codeql-language-support
language: [python, actions]
python: ['3.14']
python: ['3.15']
steps:

- name: Harden Runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
disable-sudo: true
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pr-conventional-commits.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.14'
python-version: '3.15'

# Install Commitizen without using the package's Makefile: that's much faster than
# creating a venv and installing heaps of dependencies that aren't required for this job.
- name: Set up Commitizen
run: |
pip install --upgrade pip wheel
pip install 'commitizen ==4.16.5'
pip install 'commitizen ==4.19.2'

# Run Commitizen to check the title of the PR which triggered this workflow, and check
# all commit messages of the PR's branch. If any of the checks fails then this job fails.
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
steps:

- name: Harden Runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
disable-sudo: true
Expand All @@ -44,12 +44,12 @@
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.14'
python-version: '3.15'

- name: Set up Commitizen
run: |
pip install --upgrade pip wheel
pip install 'commitizen ==4.16.5'
pip install 'commitizen ==4.19.2'

- name: Set up user
run: |
Expand Down Expand Up @@ -98,7 +98,7 @@
steps:

- name: Harden Runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
disable-sudo: true
Expand All @@ -111,7 +111,7 @@
- name: Download artifact
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
name: artifact-ubuntu-latest-python-3.14
name: artifact-ubuntu-latest-python-3.15
path: dist

# Verify hashes by first computing hashes for the artifacts and then comparing them
Expand All @@ -128,12 +128,12 @@
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.14'
python-version: '3.15'

- name: Set up Commitizen
run: |
pip install --upgrade pip wheel
pip install 'commitizen ==4.16.5'
pip install 'commitizen ==4.19.2'

- name: Create Release Notes
run: cz changelog --dry-run "$(cz version --project)" > RELEASE_NOTES.md
Expand Down Expand Up @@ -199,7 +199,7 @@
steps:

- name: Harden Runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
disable-sudo: true
Expand Down Expand Up @@ -250,7 +250,7 @@
# Github disallows passing environment variables as arguments to a reusable
# workflow, so we have to duplicate these values here. Related discussion
# here: https://github.com/actions/toolkit/issues/931
artifact-name: artifact-ubuntu-latest-python-3.14
artifact-name: artifact-ubuntu-latest-python-3.15
git-user-name: jenstroeger
git-user-email: jenstroeger@users.noreply.github.com
secrets:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/scorecards-analysis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
steps:

- name: Harden Runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
disable-sudo: true
Expand All @@ -37,7 +37,7 @@ jobs:
persist-credentials: false

- name: Run analysis
uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
uses: ossf/scorecard-action@fa7117db83c52d787ae5a89f350999701505d78e # v2.5.0
with:
results_file: results.sarif
results_format: sarif
Expand All @@ -59,6 +59,6 @@ jobs:

# Upload the results to GitHub's code scanning dashboard.
- name: Upload to code-scanning
uses: github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
uses: github/codeql-action/upload-sarif@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
with:
sarif_file: results.sarif
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ repos:

# Commitizen enforces semantic and conventional commit messages.
- repo: https://github.com/commitizen-tools/commitizen
rev: 6afcd8e9560ddf1b9a5032262a0be26540e85fb3 # frozen: v4.16.5
rev: f6be1834c1d5c46f3ad126fb112ca599b6ade685 # frozen: v4.19.2
hooks:
- id: commitizen
name: Check conventional commit message
stages: [commit-msg]

# Ruff formats and lints code.
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: cb8c523fd4835aba42af70f4cad5568db4df0b6c # frozen: v0.16.0
rev: 38bfb07c0c64c304f47eb52090f8288150c77730 # frozen: v0.17.1
hooks:
- id: ruff-format
args: [--config, pyproject.toml]
Expand Down Expand Up @@ -108,7 +108,7 @@ repos:

# Check GitHub Actions workflow files.
- repo: https://github.com/Mateusz-Grzelinski/actionlint-py
rev: c04ed26e40637cab1aa9879c693832a9c120fb20 # frozen: v1.7.12.24
rev: 805f85e558841bf4d852335e036b33d2b26be1cc # frozen: v1.7.12.25
hooks:
- id: actionlint

Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ PACKAGE_WHEEL_BASE_NAME := $(PACKAGE_BASE_NAME)-py3-none-any
PACKAGE_WHEEL_NAME := $(PACKAGE_WHEEL_BASE_NAME).whl

# If a PYTHON environment variable exists then use that, else define it here.
PYTHON ?= python3.14
PYTHON ?= python3.15

# This variable contains the first goal that matches any of the listed goals
# here, else it contains an empty string. The net effect is to filter out
Expand Down Expand Up @@ -75,7 +75,7 @@ endif
.PHONY: all
all: check test dist docs

# Create a virtual environment, either for Python3.14 (default) or using
# Create a virtual environment, either for Python3.15 (default) or using
# the Python interpreter specified in the PYTHON environment variable. Also
# create an empty pip.conf file to ensure that `pip config` modifies this
# venv only, unless told otherwise. For more background, see:
Expand Down Expand Up @@ -199,7 +199,7 @@ dist/$(PACKAGE_WHEEL_NAME): check test-all
SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) python -m flit build --format wheel
echo $(SOURCE_DATE_EPOCH) > dist/$(PACKAGE_WHEEL_BASE_NAME)-build-epoch.txt
dist/$(PACKAGE_SDIST_NAME): check test-all
SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) python -m flit build --no-setup-py --format sdist
SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) python -m flit build --format sdist
dist/$(PACKAGE_BASE_NAME)-docs-html.zip: docs-html
python -m zipfile -c dist/$(PACKAGE_BASE_NAME)-docs-html.zip docs/_build/html/
dist/$(PACKAGE_BASE_NAME)-docs-md.zip: docs-md
Expand Down
28 changes: 14 additions & 14 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 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/)).
The package requires a minimum of [Python 3.11](https://www.python.org/downloads/release/python-31117/), and it supports [Python 3.12](https://www.python.org/downloads/release/python-31215/), [Python 3.13](https://www.python.org/downloads/release/python-31316/), [Python 3.14](https://www.python.org/downloads/release/python-3148/), and [Python 3.15](https://www.python.org/downloads/release/python-3150/) (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 @@ -105,19 +105,19 @@ If you’d like to start your own Python project from scratch, you can either co
To develop your new package, first create a [virtual environment](https://docs.python.org/3/tutorial/venv.html) by either using the [Makefile](https://www.gnu.org/software/make/manual/make.html#toc-An-Introduction-to-Makefiles):

```bash
make venv # Create a new virtual environment in .venv folder using Python 3.14.
make venv # Create a new virtual environment in .venv folder using Python 3.15.
```

or for a specific version of Python:

```bash
PYTHON=python3.12 make venv # Same virtual environment for a different Python version.
PYTHON=python3.14 make venv # Same virtual environment for a different Python version.
```

or manually:

```bash
python3.14 -m venv .venv # Or use .venv314 for more than one local virtual environments.
python3.15 -m venv .venv # Or use .venv315 for more than one local virtual environments.
```

When working with this Makefile _it is important to always [activate the virtual environment](https://docs.python.org/3/library/venv.html)_ because some of the [git hooks](#git-hooks) (see below) depend on that:
Expand Down Expand Up @@ -184,13 +184,13 @@ Note that the unit tests include [doctest](https://docs.python.org/3/library/doc
Both statement and branch coverage are being tracked using [coverage](https://github.com/nedbat/coveragepy) and the [pytest-cov](https://github.com/pytest-dev/pytest-cov) plugin for pytest when running unit tests, and it measures how much code in the `src/package/` folder is covered by tests:
```
=========================================== test session starts ===========================================
platform darwin -- Python 3.14.5, pytest-9.0.3, pluggy-1.6.0 -- /path/to/python-package-template/.venv/bin/python
platform darwin -- Python 3.15.0, pytest-9.0.3, pluggy-1.7.0 -- /path/to/python-package-template/.venv/bin/python
cachedir: .pytest_cache
benchmark: 5.2.3 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
hypothesis profile 'default-with-verbose-verbosity' -> verbosity=Verbosity.verbose
rootdir: /path/to/python-package-template
configfile: pyproject.toml
plugins: benchmark-5.2.3, cov-7.1.0, env-1.6.0, Faker-40.19.1, custom-exit-code-0.3.0, doctestplus-1.7.1, cases-3.10.1, hypothesis-6.152.9
plugins: benchmark-5.2.3, hypothesis-6.161.5, cov-7.1.0, custom-exit-code-0.3.0, Faker-40.36.0, doctestplus-1.7.1, cases-3.10.1, env-1.7.0, platformdirs-4.13.5
collected 6 items / 2 deselected / 4 selected

src/package/something.py::package.something.Something.do_something PASSED [ 25%]
Expand All @@ -199,7 +199,7 @@ tests/unit/test_something.py::test_something_cases[_case_boolean] PASSED
docs/source/index.rst::index.rst PASSED [100%]

============================================= tests coverage ==============================================
____________________________ coverage: platform darwin, python 3.14.5-final-0 _____________________________
____________________________ coverage: platform darwin, python 3.15.0-final-0 _____________________________

Name Stmts Miss Branch BrPart Cover Missing
----------------------------------------------------------------------
Expand All @@ -213,25 +213,25 @@ tests/unit/test_something.py::test_something_hypothesis:

- during generate phase (0.00 seconds):
- Typical runtimes: ~ 0-1 ms, of which < 1ms in data generation
- 2 passing examples, 0 failing examples, 0 invalid examples
- 2 passing, 0 failing, and 0 invalid test cases

- Stopped because nothing left to do


============================================ slowest durations ============================================
0.05s setup src/package/something.py::package.something.Something.do_something
0.04s call src/package/something.py::package.something.Something.do_something
0.00s call tests/unit/test_something.py::test_something_hypothesis
0.00s call src/package/something.py::package.something.Something.do_something
0.00s setup tests/unit/test_something.py::test_something_cases[_case_boolean]
0.00s call docs/source/index.rst::index.rst
0.00s setup docs/source/index.rst::index.rst
0.00s setup tests/unit/test_something.py::test_something_cases[_case_boolean]
0.00s setup tests/unit/test_something.py::test_something_hypothesis
0.00s call tests/unit/test_something.py::test_something_cases[_case_boolean]
0.00s teardown src/package/something.py::package.something.Something.do_something
0.00s setup docs/source/index.rst::index.rst
0.00s teardown docs/source/index.rst::index.rst
0.00s teardown src/package/something.py::package.something.Something.do_something
0.00s call tests/unit/test_something.py::test_something_cases[_case_boolean]
0.00s teardown tests/unit/test_something.py::test_something_cases[_case_boolean]
0.00s teardown tests/unit/test_something.py::test_something_hypothesis
===================================== 4 passed, 2 deselected in 0.16s =====================================
===================================== 4 passed, 2 deselected in 0.19s =====================================
```
Note that code that’s not covered by tests is listed under the `Missing` column, and branches not taken too. The net effect of enforcing 100% code and branch coverage is that every new major and minor feature, every code change, and every fix are being tested (keeping in mind that high _coverage_ does not imply comprehensive, meaningful _test data_).

Expand Down
15 changes: 13 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# -- Project information -----------------------------------------------------

project = "Package"
copyright = "2023, Package"
copyright = "2023-2026, Package"
author = ""


Expand Down Expand Up @@ -52,10 +52,21 @@

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "alabaster"

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]


# -- Options for Markdown output -------------------------------------------------
# For details, see: https://github.com/liran-funaro/sphinx-markdown-builder#configurations
markdown_anchor_sections = True
markdown_anchor_signature = True
markdown_docinfo = True
# markdown_http_base =
# markdown_uri_doc_suffix =
# markdown_file_suffix =
# markdown_bullet =
markdown_flavor = "github"
Loading
Loading