diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 5b12fe48..fef394fa 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -1,5 +1,6 @@ # This configuration file enables Dependabot version updates. # https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/about-dependabot-version-updates +# https://docs.github.com/en/code-security/reference/supply-chain-security/supported-ecosystems-and-repositories # https://github.com/dependabot/feedback/issues/551 version: 2 @@ -8,6 +9,8 @@ updates: directory: / schedule: interval: weekly + cooldown: + default-days: 3 commit-message: prefix: chore prefix-development: chore @@ -23,6 +26,8 @@ updates: directory: / schedule: interval: weekly + cooldown: + default-days: 3 commit-message: prefix: chore prefix-development: chore @@ -32,4 +37,25 @@ updates: # Add additional reviewers for PRs opened by Dependabot. For more information, see: # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#reviewers # reviewers: + # + +- package-ecosystem: pre-commit + directory: / + schedule: + interval: weekly + cooldown: + default-days: 3 + commit-message: + prefix: chore + prefix-development: chore + include: scope + target-branch: main + # Group updates into one pull request. See also: + # https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#groups-- + groups: + pre-commit: + patterns: ['*'] + # Add additional reviewers for PRs opened by Dependabot. For more information, see: + # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#reviewers + # reviewers: # - diff --git a/.github/workflows/_build.yaml b/.github/workflows/_build.yaml index 0310704e..f3118e7e 100644 --- a/.github/workflows/_build.yaml +++ b/.github/workflows/_build.yaml @@ -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.13, which can be used to +# workflow, we only generate artifacts for ubuntu-latest and Python 3.14, which can be used to # create a release. For details see: # # https://docs.github.com/en/actions/using-workflows/reusing-workflows#limitations @@ -35,7 +35,7 @@ permissions: contents: read env: ARTIFACT_OS: ubuntu-latest # The default OS for release. - ARTIFACT_PYTHON: '3.13' # The default Python version for release. + ARTIFACT_PYTHON: '3.14' # The default Python version for release. jobs: build: @@ -51,22 +51,22 @@ 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'] + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] steps: - name: Harden Runner - uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs disable-sudo: true - name: Check out repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{ matrix.python }} diff --git a/.github/workflows/_generate-rebase.yaml b/.github/workflows/_generate-rebase.yaml index eaa0cb53..54869af8 100644 --- a/.github/workflows/_generate-rebase.yaml +++ b/.github/workflows/_generate-rebase.yaml @@ -34,12 +34,12 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Check out repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 token: ${{ secrets.REPO_ACCESS_TOKEN }} diff --git a/.github/workflows/_wiki-documentation.yaml b/.github/workflows/_wiki-documentation.yaml index f324a734..2edbbe8d 100644 --- a/.github/workflows/_wiki-documentation.yaml +++ b/.github/workflows/_wiki-documentation.yaml @@ -41,7 +41,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs disable-sudo: true @@ -49,7 +49,7 @@ jobs: # Check out the repository's Wiki repo into the wiki/ folder. The token is required # only for private repositories. - name: Check out repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: token: ${{ secrets.REPO_ACCESS_TOKEN }} repository: ${{ format('{0}.wiki', github.repository) }} diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 98699832..f722bbbb 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -29,20 +29,20 @@ jobs: matrix: # Learn more about CodeQL language support at https://git.io/codeql-language-support language: [python, actions] - python: ['3.13'] + python: ['3.14'] steps: - name: Harden Runner - uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs disable-sudo: true - name: Checkout repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{ matrix.python }} @@ -54,7 +54,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 + uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 with: languages: ${{ matrix.language }} config-file: .github/codeql/codeql-config.yaml @@ -67,4 +67,4 @@ jobs: # queries: ./path/to/local/query, your-org/your-repo/queries@main - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 + uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 diff --git a/.github/workflows/dependabot-automerge.yaml b/.github/workflows/dependabot-automerge.yaml index aef76783..a6f53112 100644 --- a/.github/workflows/dependabot-automerge.yaml +++ b/.github/workflows/dependabot-automerge.yaml @@ -1,4 +1,5 @@ # Automatically merge Dependabot PRs upon approval. +# https://docs.github.com/en/code-security/tutorials/secure-your-dependencies/automating-dependabot-with-github-actions#enabling-automerge-on-a-pull-request name: Automerge Dependabot PR on: diff --git a/.github/workflows/macaron-analysis.yaml b/.github/workflows/macaron-analysis.yaml index e72f4df3..8b94386f 100644 --- a/.github/workflows/macaron-analysis.yaml +++ b/.github/workflows/macaron-analysis.yaml @@ -22,13 +22,13 @@ jobs: steps: - name: Check out repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Check the GitHub Actions workflows in the repository for vulnerabilities. - name: Run Macaron action - uses: oracle/macaron@b31acfe389133a5587d9639063ec70cb84e7bc47 # v0.23.0 + uses: oracle/macaron@4ddb55e3c9ef2c77b548be55c557078c4476fd9c # v0.24.0 with: repo_path: ./ policy_file: check-github-actions diff --git a/.github/workflows/pr-conventional-commits.yaml b/.github/workflows/pr-conventional-commits.yaml index 8a61b236..adf6c1a6 100644 --- a/.github/workflows/pr-conventional-commits.yaml +++ b/.github/workflows/pr-conventional-commits.yaml @@ -22,21 +22,21 @@ jobs: steps: - name: Check out repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: - python-version: '3.13' + python-version: '3.14' # 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.13.9' + pip install 'commitizen ==4.16.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. diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a9c1ec53..1ac67953 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -30,26 +30,26 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs disable-sudo: true - name: Check out repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 token: ${{ secrets.REPO_ACCESS_TOKEN }} - name: Set up Python - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: - python-version: '3.13' + python-version: '3.14' - name: Set up Commitizen run: | pip install --upgrade pip wheel - pip install 'commitizen ==4.13.9' + pip install 'commitizen ==4.16.2' - name: Set up user run: | @@ -98,20 +98,20 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs disable-sudo: true - name: Check out repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - name: Download artifact uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 with: - name: artifact-ubuntu-latest-python-3.13 + name: artifact-ubuntu-latest-python-3.14 path: dist # Verify hashes by first computing hashes for the artifacts and then comparing them @@ -126,14 +126,14 @@ jobs: # Create the Release Notes using commitizen. - name: Set up Python - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: - python-version: '3.13' + python-version: '3.14' - name: Set up Commitizen run: | pip install --upgrade pip wheel - pip install 'commitizen ==4.13.9' + pip install 'commitizen ==4.16.2' - name: Create Release Notes run: cz changelog --dry-run "$(cz version --project)" > RELEASE_NOTES.md @@ -199,13 +199,13 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs disable-sudo: true - name: Check out repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 @@ -250,7 +250,7 @@ jobs: # 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.13 + artifact-name: artifact-ubuntu-latest-python-3.14 git-user-name: jenstroeger git-user-email: jenstroeger@users.noreply.github.com secrets: diff --git a/.github/workflows/scorecards-analysis.yaml b/.github/workflows/scorecards-analysis.yaml index 94664d97..2491d95b 100644 --- a/.github/workflows/scorecards-analysis.yaml +++ b/.github/workflows/scorecards-analysis.yaml @@ -26,13 +26,13 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs disable-sudo: true - name: Check out repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -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@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 + uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 with: sarif_file: results.sarif diff --git a/.github/workflows/sync-with-upstream.yaml b/.github/workflows/sync-with-upstream.yaml index 0f0599f3..e77f8f35 100644 --- a/.github/workflows/sync-with-upstream.yaml +++ b/.github/workflows/sync-with-upstream.yaml @@ -21,7 +21,7 @@ jobs: steps: - name: Check out template repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: # If you decide to change the upstream template repository to a private one, uncomment # the following argument to pass the required token to be able to check it out. @@ -31,7 +31,7 @@ jobs: path: template - name: Check out current repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: token: ${{ secrets.REPO_ACCESS_TOKEN }} fetch-depth: 0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3820efdf..9f0d551d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: # Commitizen enforces semantic and conventional commit messages. - repo: https://github.com/commitizen-tools/commitizen - rev: v4.13.9 + rev: 2ca29f9297911f8f5a4e8f97100b7832f045e8d3 # frozen: v4.13.10 hooks: - id: commitizen name: Check conventional commit message @@ -23,7 +23,7 @@ repos: # Sort imports. - repo: https://github.com/pycqa/isort - rev: 7.0.0 + rev: dac090ce4d9ee313d086e2e89ab1acb8c2664fa1 # frozen: 9.0.0a3 hooks: - id: isort name: Sort import statements @@ -32,22 +32,22 @@ repos: # Add Black code formatters. - repo: https://github.com/ambv/black - rev: 25.11.0 + rev: c6755bb741b6481d6b3d3bb563c83fa060db96c9 # frozen: 26.3.1 hooks: - id: black name: Format code args: [--config, pyproject.toml] - repo: https://github.com/asottile/blacken-docs - rev: 1.20.0 + rev: dda8db18cfc68df532abf33b185ecd12d5b7b326 # frozen: 1.20.0 hooks: - id: blacken-docs name: Format code in docstrings args: [--line-length, '120'] - additional_dependencies: [black==25.11.0] + additional_dependencies: [black==26.3.1] # Upgrade and rewrite Python idioms. - repo: https://github.com/asottile/pyupgrade - rev: v3.21.2 + rev: 75992aaa40730136014f34227e0135f63fc951b4 # frozen: v3.21.2 hooks: - id: pyupgrade name: Upgrade code idioms @@ -57,7 +57,7 @@ repos: # 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: 7.3.0 + rev: d93590f5be797aabb60e3b09f2f52dddb02f349f # frozen: 7.3.0 hooks: - id: flake8 name: Check flake8 issues @@ -91,7 +91,7 @@ repos: # Check for potential security issues. - repo: https://github.com/PyCQA/bandit - rev: 1.9.2 + rev: 92ae8b82fb422a639f0ed8d99e96cea769594e08 # frozen: 1.9.4 hooks: - id: bandit name: Check for security issues @@ -103,7 +103,7 @@ repos: # 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 - rev: v6.0.0 + rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0 hooks: - id: check-ast - id: check-case-conflict @@ -123,7 +123,7 @@ repos: - id: check-yaml - id: check-toml - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.10.0 + rev: 3a6eb0fadf60b3cccfd80bad9dbb6fae7e47b316 # frozen: v1.10.0 hooks: - id: python-check-blanket-noqa - id: python-check-blanket-type-ignore @@ -138,13 +138,13 @@ repos: # this package's documentation. # Commenting this out because https://github.com/Lucas-C/pre-commit-hooks-markup/issues/13 # - repo: https://github.com/Lucas-C/pre-commit-hooks-markup -# rev: v1.0.1 +# rev: 501f3d60cee13c712492103343bc23efdc7b3d1f # frozen: v1.0.1 # hooks: # - id: rst-linter # Check and prettify the configuration files. - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks - rev: v2.15.0 + rev: 4380fbb73a154b5f5624794c1c78d9719ccc860f # frozen: v2.16.0 hooks: - id: pretty-format-ini args: [--autofix] @@ -156,18 +156,16 @@ repos: # Check GitHub Actions workflow files. - repo: https://github.com/Mateusz-Grzelinski/actionlint-py - rev: v1.7.9.24 + rev: c04ed26e40637cab1aa9879c693832a9c120fb20 # frozen: v1.7.12.24 hooks: - id: actionlint -# On push to the remote, run all tests. Note that the `COVERAGE_CORE` variable is required -# for Python 3.12+ to make sure Coverage uses the new Python monitoring module. -# See also: https://blog.trailofbits.com/2025/05/01/making-pypis-test-suite-81-faster/#optimizing-coverage-with-python-312s-sysmonitoring +# On push to the remote, run all tests. - repo: local hooks: - id: pytest name: Run unit tests - entry: env COVERAGE_CORE=sysmon pytest --config-file pyproject.toml --cov-config pyproject.toml -m 'not integration and not performance' src/package/ tests/ docs/ + entry: pytest --config-file pyproject.toml --cov-config pyproject.toml -m 'not integration and not performance' src/package/ tests/ docs/ language: python verbose: true always_run: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 9165651b..d5bea48b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -This project follows the [semantic versioning](https://packaging.python.org/en/latest/discussions/versioning/#semantic-versioning-vs-calendar-versioning) and [pre-release versioning](https://packaging.python.org/en/latest/discussions/versioning/) schemes recommended by the Python Packaging Authority [here](https://packaging.python.org/en/latest/specifications/version-specifiers/). +# Changelog + +All notable changes to this project will be documented in this file. + +This project adheres to [semantic versioning](https://packaging.python.org/en/latest/discussions/versioning/#semantic-versioning-vs-calendar-versioning) and [pre-release versioning](https://packaging.python.org/en/latest/discussions/versioning/) schemes recommended by the Python Packaging Authority [here](https://packaging.python.org/en/latest/specifications/version-specifiers/). The format of this file is loosely based on [Keep a Changelog](https://keepachangelog.com/). ## v2.19.1 (2026-04-24) diff --git a/Makefile b/Makefile index 729531eb..b1827425 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,20 @@ SHELL := bash PACKAGE_NAME := package PACKAGE_VERSION := $(shell python -c $$'try: import $(PACKAGE_NAME); print($(PACKAGE_NAME).__version__);\nexcept: print("unknown");') +# Put together the file names for both the source distribution package (sdist) +# and the binary distribution package (wheel). For more details on these two, +# see: https://packaging.python.org/en/latest/discussions/package-formats/ +# +# For the wheel, users may require additional code to generate the Python tag +# (py3), the ABI tag (none), and the platform tag (any) for the final wheel +# file name. +PACKAGE_BASE_NAME := $(PACKAGE_NAME)-$(PACKAGE_VERSION) +PACKAGE_SDIST_NAME := $(PACKAGE_BASE_NAME).tar.gz +PACKAGE_WHEEL_NAME := $(PACKAGE_BASE_NAME)-py3-none-any.whl + +# If a PYTHON environment variable exists then use that, else define it here. +PYTHON ?= python3.14 + # 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 # whether this current run of `make` requires a Python virtual environment @@ -40,9 +54,11 @@ endif # If the project configuration file has been updated (package deps or # otherwise) then warn the user and suggest resolving the conflict. -ifeq ($(shell test pyproject.toml -nt .venv/upgraded-on; echo $$?),0) - $(warning pyproject.toml was updated, consider `make upgrade` if your packages have changed) - $(warning If this is not correct then run `make upgrade-quiet`) +ifneq ($(wildcard .venv/upgraded-on),) + ifeq ($(shell test pyproject.toml -nt .venv/upgraded-on; echo $$?),0) + $(warning pyproject.toml was updated, consider `make upgrade` if your packages have changed) + $(warning If this is not correct then run `make upgrade-quiet`) + endif endif # The SOURCE_DATE_EPOCH environment variable allows the `flit` tool to @@ -56,7 +72,7 @@ endif .PHONY: all all: check test dist docs -# Create a virtual environment, either for Python3.13 (default) or using +# Create a virtual environment, either for Python3.14 (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: @@ -69,13 +85,8 @@ venv: if [ -d .venv/ ]; then \ echo "Found an inactive Python virtual environment, please activate or nuke it" && exit 1; \ fi - if [ -z "${PYTHON}" ]; then \ - echo "Creating virtual environment in .venv/ for python3.13"; \ - python3.13 -m venv --upgrade-deps --prompt . .venv; \ - else \ - echo "Creating virtual environment in .venv/ for ${PYTHON}"; \ - ${PYTHON} -m venv --upgrade-deps --prompt . .venv; \ - fi + echo "Creating virtual environment in .venv/ for ${PYTHON}"; \ + ${PYTHON} -m venv --upgrade-deps --prompt . .venv; \ touch .venv/pip.conf # Set up a newly created virtual environment. Note: pre-commit uses the @@ -91,7 +102,7 @@ setup: force-upgrade # Install or upgrade an existing virtual environment based on the # package dependencies declared in pyproject.toml. -.PHONY: upgrade force-upgrade +.PHONY: upgrade force-upgrade upgrade-quiet upgrade: .venv/upgraded-on .venv/upgraded-on: pyproject.toml python -m pip install --upgrade pip setuptools @@ -107,7 +118,7 @@ upgrade-quiet: # Generate a Software Bill of Materials (SBOM). .PHONY: sbom sbom: requirements - python -m cyclonedx_py requirements --output-reproducible --output-format json --output-file dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-sbom.json + python -m cyclonedx_py requirements --output-reproducible --output-format json --output-file dist/$(PACKAGE_BASE_NAME)-sbom.json # Generate a requirements.txt file containing version and integrity hashes for all # packages currently installed in the virtual environment. There's no easy way to @@ -129,14 +140,14 @@ requirements.txt: pyproject.toml [[ $$pkg =~ (.*)==(.*) ]] && curl -s https://pypi.org/pypi/$${BASH_REMATCH[1]}/$${BASH_REMATCH[2]}/json | python -c "import json, sys; print(''.join(f''' \\\\\n --hash=sha256:{pkg['digests']['sha256']}''' for pkg in json.load(sys.stdin)['urls']));" >> requirements.txt; \ done echo -e -n "$(PACKAGE_NAME)==$(PACKAGE_VERSION)" >> requirements.txt - if [ -f dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz ]; then \ - echo -e -n " \\\\\n $$(python -m pip hash --algorithm sha256 dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz | grep '^\-\-hash')" >> requirements.txt; \ + if [ -f dist/$(PACKAGE_SDIST_NAME) ]; then \ + echo -e -n " \\\\\n $$(python -m pip hash --algorithm sha256 dist/$(PACKAGE_SDIST_NAME) | grep '^\-\-hash')" >> requirements.txt; \ fi - if [ -f dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-py3-none-any.whl ]; then \ - echo -e -n " \\\\\n $$(python -m pip hash --algorithm sha256 dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-py3-none-any.whl | grep '^\-\-hash')" >> requirements.txt; \ + if [ -f dist/$(PACKAGE_WHEEL_NAME) ]; then \ + echo -e -n " \\\\\n $$(python -m pip hash --algorithm sha256 dist/$(PACKAGE_WHEEL_NAME) | grep '^\-\-hash')" >> requirements.txt; \ fi echo "" >> requirements.txt - cp requirements.txt dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-requirements.txt + cp requirements.txt dist/$(PACKAGE_BASE_NAME)-requirements.txt # Audit the currently installed packages. Skip packages that are installed in # editable mode (like the one in development here) because they may not have @@ -171,7 +182,7 @@ check: .PHONY: test test-all test-unit test-integration test-performance test: test-unit test-unit: - COVERAGE_CORE=sysmon python -m pytest --config-file pyproject.toml --cov-config pyproject.toml -m 'not integration and not performance' src/package/ tests/ docs/ + python -m pytest --config-file pyproject.toml --cov-config pyproject.toml -m 'not integration and not performance' src/package/ tests/ docs/ test-integration: python -m pytest --config-file pyproject.toml --no-cov -m integration tests/ test-performance: @@ -182,20 +193,16 @@ test-all: test-unit test-integration test-performance # When building these artifacts, we need the environment variable SOURCE_DATE_EPOCH # set to the build date/epoch. For more details, see: https://flit.pypa.io/en/latest/reproducible.html .PHONY: dist -dist: dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-py3-none-any.whl dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-docs-html.zip dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-docs-md.zip dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-build-epoch.txt -dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-py3-none-any.whl: check test-all dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-build-epoch.txt +dist: dist/$(PACKAGE_WHEEL_NAME) dist/$(PACKAGE_SDIST_NAME) dist/$(PACKAGE_BASE_NAME)-docs-html.zip dist/$(PACKAGE_BASE_NAME)-docs-md.zip +dist/$(PACKAGE_WHEEL_NAME): check test-all SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) python -m flit build --setup-py --format wheel -dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz: check test-all dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-build-epoch.txt + echo $(SOURCE_DATE_EPOCH) > dist/$(PACKAGE_BASE_NAME)-py3-none-any-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 -dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-docs-html.zip: docs-html - python -m zipfile -c dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-docs-html.zip docs/_build/html/ -dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-docs-md.zip: docs-md - python -m zipfile -c dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-docs-md.zip docs/_build/markdown/ - -# Keep this goal phony to ensure the epoch is always updated. -.PHONY: dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-build-epoch.txt -dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-build-epoch.txt: - echo $(SOURCE_DATE_EPOCH) > dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-build-epoch.txt +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 + python -m zipfile -c dist/$(PACKAGE_BASE_NAME)-docs-md.zip docs/_build/markdown/ # Build a PEP-503 compatible Simple Repository directory inside of dist/. For details on # the layout of that directory and the normalized project name, see: https://peps.python.org/pep-0503/ @@ -203,13 +210,13 @@ dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-build-epoch.txt: # its `--extra-index-url` argument: https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-extra-index-url PROJECT_NAME := $(shell python -c $$'import re; print(re.sub(r"[-_.]+", "-", "$(PACKAGE_NAME)").lower());') .PHONY: simple-index -simple-index: dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-py3-none-any.whl dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz +simple-index: dist/$(PACKAGE_WHEEL_NAME) dist/$(PACKAGE_SDIST_NAME) mkdir -p dist/simple-index/$(PROJECT_NAME) - echo -e "\nSimple Index$(PACKAGE_NAME)" > dist/simple-index/index.html - echo -e "\nSimple Index: $(PROJECT_NAME)$(PACKAGE_NAME)-$(PACKAGE_VERSION)-py3-none-any.whl$(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz" > dist/simple-index/$(PROJECT_NAME)/index.html - cp -f dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-py3-none-any.whl dist/simple-index/$(PROJECT_NAME)/ - cp -f dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION).tar.gz dist/simple-index/$(PROJECT_NAME)/ - python -m tarfile --create dist/$(PACKAGE_NAME)-$(PACKAGE_VERSION)-pep503-simple-index.tar dist/simple-index/ + echo -e "\nSimple Index$(PACKAGE_NAME)" > dist/simple-index/index.html + echo -e "\nSimple Index: $(PROJECT_NAME)" > dist/simple-index/$(PROJECT_NAME)/index.html + cp -f dist/$(PACKAGE_WHEEL_NAME) dist/simple-index/$(PROJECT_NAME)/ + cp -f dist/$(PACKAGE_SDIST_NAME) dist/simple-index/$(PROJECT_NAME)/ + python -m tarfile --create dist/$(PACKAGE_BASE_NAME)-pep503-simple-index.tar dist/simple-index/ # Build the HTML and Markdown documentation from the package's source. DOCS_SOURCE := $(shell git ls-files docs/source) @@ -243,7 +250,7 @@ prune: python -m pip wheel --wheel-dir build/wheelhouse/ --requirement build/prune-requirements.txt python -m pip wheel --wheel-dir build/wheelhouse/ . python -m pip uninstall --yes --requirement build/prune-requirements.txt - python -m pip install --no-index --find-links=build/wheelhouse/ --editable . + python -m pip install --no-index --only-binary :all: --find-links=build/wheelhouse/ --editable . rm -fr build/ # Clean test caches and remove build artifacts. diff --git a/README.md b/README.md index 7d77de8c..ca945ebf 100644 --- a/README.md +++ b/README.md @@ -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-31015/), and it supports [Python 3.11](https://www.python.org/downloads/release/python-31110/), [Python 3.12](https://www.python.org/downloads/release/python-3127/) and [Python 3.13](https://www.python.org/downloads/release/python-3130/) (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 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/)). ### Quality assurance @@ -50,7 +50,7 @@ Documentation is important, and [Sphinx](https://www.sphinx-doc.org/en/master/) ### Versioning and publishing -Automatic package versioning and tagging, publishing to [PyPI](https://pypi.org/), and [Changelog](https://en.wikipedia.org/wiki/Changelog) generation are enabled using Github Actions. Furthermore, an optional [Release Notification](https://github.com/jenstroeger/python-package-template/tree/main/.github/workflows/release-notifications.yaml) Action allows Github to push an update notification to a [Slack bot](https://api.slack.com/bot-users) of your choice. For setup instructions, please see [below](#versioning-publishing-and-changelog). +Automatic package versioning and tagging, publishing to [PyPI](https://pypi.org/), and [Changelog](https://keepachangelog.com/) generation are enabled using Github Actions. Furthermore, an optional [Release Notification](https://github.com/jenstroeger/python-package-template/tree/main/.github/workflows/release-notifications.yaml) Action allows Github to push an update notification to a [Slack bot](https://api.slack.com/bot-users) of your choice. For setup instructions, please see [below](#versioning-publishing-and-changelog). ### Dependency analysis @@ -105,7 +105,7 @@ 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.13. +make venv # Create a new virtual environment in .venv folder using Python 3.14. ``` or for a specific version of Python: @@ -117,7 +117,7 @@ PYTHON=python3.12 make venv # Same virtual environment for a different Python v or manually: ```bash -python3.13 -m venv .venv # Or use .venv313 for more than one local virtual environments. +python3.14 -m venv .venv # Or use .venv314 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: @@ -184,14 +184,14 @@ 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.13.9, pytest-8.4.2, pluggy-1.6.0 -- /path/to/python-package-template/.venv/bin/python +platform darwin -- Python 3.14.5, pytest-9.0.3, pluggy-1.6.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 -benchmark: 5.2.0 (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) rootdir: /path/to/python-package-template configfile: pyproject.toml -plugins: cases-3.9.1, hypothesis-6.138.16, env-1.1.5, cov-6.3.0, custom-exit-code-0.3.0, doctestplus-1.4.0, Faker-37.6.0, benchmark-5.2.0 -collected 6 items / 2 deselected / 4 selected +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 +collected 6 items / 2 deselected / 4 selected src/package/something.py::package.something.Something.do_something PASSED [ 25%] tests/unit/test_something.py::test_something_hypothesis PASSED [ 50%] @@ -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.13.9-final-0 _____________________________ +____________________________ coverage: platform darwin, python 3.14.5-final-0 _____________________________ Name Stmts Miss Branch BrPart Cover Missing ---------------------------------------------------------------------- @@ -217,20 +217,21 @@ tests/unit/test_something.py::test_something_hypothesis: - Stopped because nothing left to do + ============================================ slowest durations ============================================ -0.10s setup src/package/something.py::package.something.Something.do_something -0.01s call tests/unit/test_something.py::test_something_hypothesis +0.05s setup 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 teardown src/package/something.py::package.something.Something.do_something -0.00s teardown tests/unit/test_something.py::test_something_cases[_case_boolean] -0.00s call 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 teardown docs/source/index.rst::index.rst +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.23s ===================================== +===================================== 4 passed, 2 deselected in 0.16s ===================================== ``` 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_). @@ -279,7 +280,7 @@ cz changelog cz bump ``` -## Building from a source distribution package +### Building from a source distribution package The source distribution package ([sdist](https://packaging.python.org/en/latest/discussions/package-formats/#what-is-a-source-distribution)) contains everything needed in order to check, test, and build a binary distribution ([wheel](https://packaging.python.org/en/latest/discussions/package-formats/#what-is-a-wheel)) and its documentation; that is particulalry useful for third-party packaging services that build their own software distribution packages using custom processes. @@ -300,7 +301,7 @@ SKIP=check-hooks-apply,check-useless-excludes,actionlint make dist Note that we skip Git hooks that are unnecessary when building from the source distribution. As above, this builds the source package and a binary distribution, and stores both in the `dist/` folder. And, as expected, setting the `SOURCE_DATE_EPOCH` environment variable to the build epoch value of the original sdist and wheel build results in the bit-exact same binary distribution package! -## Using the Simple Index +### Using the Simple Index Once source and/or binary distribution packages have been built, they can be served using a [PEP 503](https://peps.python.org/pep-0503/) compatible package repository. Simply call diff --git a/pyproject.toml b/pyproject.toml index 7bf0383c..fb300b47 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,17 +1,18 @@ # https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html # https://flit.pypa.io/en/latest/pyproject_toml.html [build-system] -requires = ["flit_core >=3.2.0,<4.0.0"] +requires = ["flit_core >=3.12.0,<4.0.0"] build-backend = "flit_core.buildapi" [project] name = "package" -requires-python = ">=3.10.0,<3.14.0" +requires-python = ">=3.10.0,<3.15.0" authors = [{name = "Author", email = "author@email"}] maintainers = [{name = "Maintainer", email = "maintainer@email"}] -dynamic = ["version", "description"] +dynamic = ["version"] license = "MIT" # https://spdx.org/licenses/MIT.html license-files = ["LICENSE.md"] +description = "An opinionated Python package/application template repository, with SLSA and SBOM support built in, enabled for security scanners, code linters, typing, testing and code coverage monitoring, and release automation for reproducible builds." readme = "README.md" dependencies = [] keywords = [] @@ -26,6 +27,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Libraries :: Python Modules", @@ -41,15 +43,14 @@ something = "package.__main__:main" # We keep them listed here to ensure the infrastructure BOM is consistent with what's # installed. Make sure to keep the requirements in sync with the workflows! actions = [ - "commitizen ==4.13.9", + "commitizen ==4.16.2", "twine ==6.2.0", ] dev = [ "flit >=3.2.0,<4.0.0", "mypy >=1.0.0,!=1.20.2,<1.21", "pip-audit >=2.4.4,<3.0.0", - "pylint >=3.0.0,<4.1.0", - "perflint >=0.8.0,<1.0.0", + "pylint >=4.0.0,<4.1.0", "cyclonedx-bom >=7.0.0,<8.0.0", ] docs = [ @@ -57,20 +58,19 @@ docs = [ "sphinx-markdown-builder >=0.6.4,<1.0.0", ] hooks = [ - "pre-commit >=3.0.0,<4.6.0", + "pre-commit >=3.0.0,<4.7.0", ] # Note that the `custom_exit_code` and `env` plugins may currently be unmaintained. test = [ - "coverage ==7.6.12; python_version<'3.14'", # https://github.com/pypi/warehouse/pull/17872#issuecomment-2845932281 - "faker ==40.13.0", - "hypothesis >=6.21.0,<6.151.12", + "faker ==40.19.1", + "hypothesis >=6.21.0,<6.152.10", "pytest >=9.0.3,<10.0.0", "pytest-benchmark ==5.2.3", "pytest-cases ==3.10.1", "pytest-custom_exit_code ==0.3.0", - "pytest-cov ==6.3.0", # Uses: coverage[toml] >=7.5 + "pytest-cov ==7.1.0", "pytest-doctestplus ==1.7.1", - "pytest-env ==1.2.0", + "pytest-env ==1.6.0", ] [project.urls] @@ -177,9 +177,7 @@ ignore_missing_imports = true # https://pylint.pycqa.org/en/latest/user_guide/configuration/index.html [tool.pylint.main] fail-under = 10.0 -suggestion-mode = true load-plugins = [ - "perflint", # A Linter for performance anti-patterns. "pylint.extensions.bad_builtin", "pylint.extensions.broad_try_clause", "pylint.extensions.check_elif", @@ -213,6 +211,7 @@ disable = [ "too-many-arguments", "too-many-boolean-expressions", "too-many-branches", + "too-many-function-args", "too-many-instance-attributes", "too-many-lines", "too-many-locals", @@ -266,10 +265,6 @@ env = [ filterwarnings = [ "error", "always::DeprecationWarning", - # The CoverageWarning warning is issued in two contexts: - # Python 3.10, 3.11: sys.monitoring isn't available in this version, using default core (no-sysmon) - # Python 3.12, 3.13: sys.monitoring can't measure branches in this version, using default core (no-sysmon) - "ignore:sys.monitoring isn't available in this version:coverage.exceptions.CoverageWarning", "always::coverage.exceptions.CoverageWarning", # https://docs.pytest.org/en/latest/how-to/failures.html#warning-about-unraisable-exceptions-and-unhandled-thread-exceptions "error::pytest.PytestUnraisableExceptionWarning",