use uv for dependency management

drop python 3.7 and 3.8
move tox config into pyproject
use new license metadata
This commit is contained in:
Adam Englander 2025-05-28 10:06:18 -07:00 committed by David Lord
parent 220e67ae99
commit 51dbd8977e
No known key found for this signature in database
GPG Key ID: 43368A7AA8CC5926
22 changed files with 1618 additions and 414 deletions

View File

@ -1,7 +1,17 @@
#!/bin/bash
set -e
python3 -m venv --upgrade-deps .venv
. .venv/bin/activate
pip install -r requirements/dev.txt
pip install -e .
# Install uv if not already installed
if ! command -v uv &> /dev/null; then
echo "Installing uv..."
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.cargo/bin:$PATH"
fi
# Create venv using uv and install dependencies
echo "Creating virtual environment and installing dependencies..."
uv sync
# Install pre-commit hooks
echo "Installing pre-commit hooks..."
pre-commit install --install-hooks

View File

@ -10,6 +10,7 @@ on:
permissions:
issues: write
pull-requests: write
discussions: write
concurrency:
group: lock
jobs:

View File

@ -7,10 +7,19 @@ jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
with:
python-version: 3.x
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
- uses: pre-commit-ci/lite-action@9d882e7a565f7008d4faf128f27d1cb6503d4ebf # v1.0.2
enable-cache: true
prune-cache: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
id: setup-python
with:
python-version-file: pyproject.toml
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ hashFiles('pyproject.toml', '.pre-commit-config.yaml') }}
- run: uv run --locked --group pre-commit pre-commit run --show-diff-on-failure --color=always --all-files
- uses: pre-commit-ci/lite-action@5d6cc0eb514c891a40562a58a8e71576c5c7fb43 # v1.1.0
if: ${{ !cancelled() }}

View File

@ -1,8 +1,7 @@
name: Publish
on:
push:
tags:
- '*'
tags: ['*']
jobs:
build:
runs-on: ubuntu-latest
@ -10,20 +9,19 @@ jobs:
hash: ${{ steps.hash.outputs.hash }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
with:
python-version: '3.x'
cache: pip
cache-dependency-path: requirements*/*.txt
- run: pip install -r requirements/build.txt
# Use the commit date instead of the current date during the build.
enable-cache: true
prune-cache: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version-file: pyproject.toml
- run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
- run: python -m build
# Generate hashes used for provenance.
- run: uv build
- name: generate hash
id: hash
run: cd dist && echo "hash=$(sha256sum * | base64 -w0)" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
path: ./dist
provenance:
@ -33,18 +31,16 @@ jobs:
id-token: write
contents: write
# Can't pin with hash due to how this workflow works.
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
with:
base64-subjects: ${{ needs.build.outputs.hash }}
create-release:
# Upload the sdist, wheels, and provenance to a GitHub release. They remain
# available as build artifacts for a while as well.
needs: [provenance]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- name: create release
run: >
gh release create --draft --repo ${{ github.repository }}
@ -54,8 +50,6 @@ jobs:
GH_TOKEN: ${{ github.token }}
publish-pypi:
needs: [provenance]
# Wait for approval before attempting to upload to PyPI. This allows reviewing the
# files in the draft release.
environment:
name: publish
url: https://pypi.org/project/Jinja2/${{ github.ref_name }}
@ -63,7 +57,7 @@ jobs:
permissions:
id-token: write
steps:
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
- uses: pypa/gh-action-pypi-publish@67339c736fd9354cd4f8cb0b744f2b82a74b5c70 # v1.12.3
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4
with:
packages-dir: artifact/

View File

@ -1,10 +1,10 @@
name: Tests
on:
pull_request:
paths-ignore: ['docs/**', 'README.md']
push:
branches: [main, stable]
paths-ignore: ['docs/**', '*.md', '*.rst']
pull_request:
paths-ignore: [ 'docs/**', '*.md', '*.rst' ]
paths-ignore: ['docs/**', 'README.md']
jobs:
tests:
name: ${{ matrix.name || matrix.python }}
@ -14,37 +14,37 @@ jobs:
matrix:
include:
- {python: '3.13'}
- {name: Windows, python: '3.13', os: windows-latest}
- {name: Mac, python: '3.13', os: macos-latest}
- {python: '3.12'}
- {name: Windows, python: '3.12', os: windows-latest}
- {name: Mac, python: '3.12', os: macos-latest}
- {python: '3.11'}
- {python: '3.10'}
- {python: '3.9'}
- {python: '3.8'}
- {name: PyPy, python: 'pypy-3.10', tox: pypy310}
- {name: PyPy, python: 'pypy-3.11', tox: pypy3.11}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
with:
enable-cache: true
prune-cache: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python }}
allow-prereleases: true
cache: pip
cache-dependency-path: requirements*/*.txt
- run: pip install tox
- run: tox run -e ${{ matrix.tox || format('py{0}', matrix.python) }}
- run: uv run --locked tox run -e ${{ matrix.tox || format('py{0}', matrix.python) }}
typing:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
with:
python-version: '3.x'
cache: pip
cache-dependency-path: requirements*/*.txt
enable-cache: true
prune-cache: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version-file: pyproject.toml
- name: cache mypy
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ./.mypy_cache
key: mypy|${{ hashFiles('pyproject.toml') }}
- run: pip install tox
- run: tox run -e typing
- run: uv run --locked tox run -e typing

2
.gitignore vendored
View File

@ -1,7 +1,5 @@
.idea/
.vscode/
.venv*/
venv*/
__pycache__/
dist/
.coverage*

View File

@ -1,11 +1,15 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.4
rev: 76e47323a83cd9795e4ff9a1de1c0d2eef610f17 # frozen: v0.11.11
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 648bdbfd6bb1a82f132ecc2c666e0d1b2e4b0d94 # frozen: 0.7.8
hooks:
- id: uv-lock
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b # frozen: v5.0.0
hooks:
- id: check-merge-conflict
- id: debug-statements

View File

@ -1,13 +1,10 @@
version: 2
build:
os: ubuntu-22.04
os: ubuntu-24.04
tools:
python: '3.12'
python:
install:
- requirements: requirements/docs.txt
- method: pip
path: .
sphinx:
builder: dirhtml
fail_on_warning: true
python: '3.13'
commands:
- asdf plugin add uv
- asdf install uv latest
- asdf global uv latest
- uv run --group docs sphinx-build -W -b dirhtml docs $READTHEDOCS_OUTPUT/html

View File

@ -5,7 +5,7 @@ Version 3.2.0
Unreleased
- Drop support for Python 3.7.
- Drop support for Python 3.7 and 3.8.
- Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``.
:pr:`1793`
- Use ``flit_core`` instead of ``setuptools`` as build backend.

View File

@ -2,35 +2,66 @@
name = "Jinja2"
description = "A very fast and expressive template engine."
readme = "README.md"
license = {file = "LICENSE.txt"}
license = "BSD-3-Clause"
license-files = ["LICENSE.txt"]
maintainers = [{name = "Pallets", email = "contact@palletsprojects.com"}]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Web Environment",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
"Topic :: Text Processing :: Markup :: HTML",
"Typing :: Typed",
]
requires-python = ">=3.8"
dependencies = ["MarkupSafe>=2.0"]
requires-python = ">=3.9"
dependencies = [
"MarkupSafe>=2.0"
]
dynamic = ["version"]
[project.urls]
Donate = "https://palletsprojects.com/donate"
Documentation = "https://jinja.palletsprojects.com/"
Changes = "https://jinja.palletsprojects.com/changes/"
Changes = "https://jinja.palletsprojects.com/page/changes/"
Source = "https://github.com/pallets/jinja/"
Chat = "https://discord.gg/pallets"
[project.optional-dependencies]
i18n = ["Babel>=2.7"]
[project.entry-points."babel.extractors"]
jinja2 = "jinja2.ext:babel_extract[i18n]"
[dependency-groups]
dev = [
"ruff",
"tox",
"tox-uv",
]
docs = [
"pallets-sphinx-themes",
"sphinx",
"sphinxcontrib-log-cabinet",
]
docs-auto = [
"sphinx-autobuild",
]
gha-update = [
"gha-update ; python_full_version >= '3.12'",
]
pre-commit = [
"pre-commit",
"pre-commit-uv",
]
tests = [
"pytest",
"pytest-timeout",
"trio"
]
typing = [
"mypy",
"pyright",
"pytest",
]
[build-system]
requires = ["flit_core<4"]
@ -43,15 +74,17 @@ name = "jinja2"
include = [
"docs/",
"examples/",
"requirements/",
"tests/",
"CHANGES.md",
"tox.ini",
"CHANGES.rst",
"uv.lock"
]
exclude = [
"docs/_build/",
]
[tool.uv]
default-groups = ["dev", "pre-commit", "tests", "typing"]
[tool.pytest.ini_options]
testpaths = ["tests"]
filterwarnings = [
@ -65,19 +98,24 @@ source = ["jinja2", "tests"]
[tool.coverage.paths]
source = ["src", "*/site-packages"]
[tool.coverage.report]
exclude_also = [
"if t.TYPE_CHECKING",
"raise NotImplementedError",
": \\.{3}",
]
[tool.mypy]
python_version = "3.8"
files = ["src/jinja2"]
python_version = "3.9"
files = ["src"]
show_error_codes = true
pretty = true
strict = true
local_partial_types = true
warn_unreachable = true
[tool.pyright]
pythonVersion = "3.8"
include = ["src/jinja2"]
typeCheckingMode = "basic"
pythonVersion = "3.9"
include = ["src"]
typeCheckingMode = "standard"
[tool.ruff]
src = ["src"]
@ -94,6 +132,9 @@ select = [
"UP", # pyupgrade
"W", # pycodestyle warning
]
ignore = [
"UP038", # keep isinstance tuple
]
[tool.ruff.lint.isort]
force-single-line = true
@ -103,3 +144,70 @@ order-by-type = false
tag-only = [
"slsa-framework/slsa-github-generator",
]
[tool.tox]
env_list = [
"py3.13", "py3.12", "py3.11", "py3.10", "py3.9",
"pypy3.11",
"style",
"typing",
"docs",
]
[tool.tox.env_run_base]
description = "pytest on latest dependency versions"
runner = "uv-venv-lock-runner"
package = "wheel"
wheel_build_env = ".pkg"
constrain_package_deps = true
use_frozen_constraints = true
dependency_groups = ["tests"]
commands = [[
"pytest", "-v", "--tb=short", "--basetemp={env_tmp_dir}",
{replace = "posargs", default = [], extend = true},
]]
[tool.tox.env.style]
description = "run all pre-commit hooks on all files"
dependency_groups = ["pre-commit"]
skip_install = true
commands = [["pre-commit", "run", "--all-files"]]
[tool.tox.env.typing]
description = "run static type checkers"
dependency_groups = ["typing"]
commands = [
["mypy"],
]
[tool.tox.env.docs]
description = "build docs"
dependency_groups = ["docs"]
commands = [["sphinx-build", "-E", "-W", "-b", "dirhtml", "docs", "docs/_build/dirhtml"]]
[tool.tox.env.docs-auto]
description = "continuously rebuild docs and start a local server"
dependency_groups = ["docs", "docs-auto"]
commands = [["sphinx-autobuild", "-W", "-b", "dirhtml", "--watch", "src", "docs", "docs/_build/dirhtml"]]
[tool.tox.env.update-actions]
description = "update GitHub Actions pins"
labels = ["update"]
dependency_groups = ["gha-update"]
skip_install = true
commands = [["gha-update"]]
[tool.tox.env.update-pre_commit]
description = "update pre-commit pins"
labels = ["update"]
dependency_groups = ["pre-commit"]
skip_install = true
commands = [["pre-commit", "autoupdate", "--freeze", "-j4"]]
[tool.tox.env.update-requirements]
description = "update uv lock"
labels = ["update"]
dependency_groups = []
no_default_groups = true
skip_install = true
commands = [["uv", "lock", {replace = "posargs", default = ["-U"], extend = true}]]

View File

@ -1 +0,0 @@
build

View File

@ -1,12 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile build.in
#
build==1.2.2.post1
# via -r build.in
packaging==24.2
# via build
pyproject-hooks==1.2.0
# via build

View File

@ -1,5 +0,0 @@
-r docs.txt
-r tests.txt
-r typing.txt
pre-commit
tox

View File

@ -1,151 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile dev.in
#
alabaster==1.0.0
# via sphinx
attrs==24.3.0
# via
# outcome
# trio
babel==2.16.0
# via sphinx
build==1.2.2.post1
# via pip-tools
cachetools==5.5.0
# via tox
certifi==2024.12.14
# via requests
cfgv==3.4.0
# via pre-commit
chardet==5.2.0
# via tox
charset-normalizer==3.4.0
# via requests
click==8.1.7
# via
# pip-compile-multi
# pip-tools
colorama==0.4.6
# via tox
distlib==0.3.9
# via virtualenv
docutils==0.21.2
# via sphinx
filelock==3.16.1
# via
# tox
# virtualenv
identify==2.6.3
# via pre-commit
idna==3.10
# via
# requests
# trio
imagesize==1.4.1
# via sphinx
iniconfig==2.0.0
# via pytest
jinja2==3.1.4
# via sphinx
markupsafe==3.0.2
# via jinja2
mypy==1.14.0
# via -r /Users/david/Projects/jinja/requirements/typing.in
mypy-extensions==1.0.0
# via mypy
nodeenv==1.9.1
# via pre-commit
outcome==1.3.0.post0
# via trio
packaging==24.2
# via
# build
# pallets-sphinx-themes
# pyproject-api
# pytest
# sphinx
# tox
pallets-sphinx-themes==2.3.0
# via -r /Users/david/Projects/jinja/requirements/docs.in
pip-compile-multi==2.7.1
# via -r dev.in
pip-tools==7.4.1
# via pip-compile-multi
platformdirs==4.3.6
# via
# tox
# virtualenv
pluggy==1.5.0
# via
# pytest
# tox
pre-commit==4.0.1
# via -r dev.in
pygments==2.18.0
# via sphinx
pyproject-api==1.8.0
# via tox
pyproject-hooks==1.2.0
# via
# build
# pip-tools
pytest==8.3.4
# via -r /Users/david/Projects/jinja/requirements/tests.in
pyyaml==6.0.2
# via pre-commit
requests==2.32.3
# via sphinx
sniffio==1.3.1
# via trio
snowballstemmer==2.2.0
# via sphinx
sortedcontainers==2.4.0
# via trio
sphinx==8.1.3
# via
# -r /Users/david/Projects/jinja/requirements/docs.in
# pallets-sphinx-themes
# sphinx-issues
# sphinx-notfound-page
# sphinxcontrib-log-cabinet
sphinx-issues==5.0.0
# via -r /Users/david/Projects/jinja/requirements/docs.in
sphinx-notfound-page==1.0.4
# via pallets-sphinx-themes
sphinxcontrib-applehelp==2.0.0
# via sphinx
sphinxcontrib-devhelp==2.0.0
# via sphinx
sphinxcontrib-htmlhelp==2.1.0
# via sphinx
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-log-cabinet==1.0.1
# via -r /Users/david/Projects/jinja/requirements/docs.in
sphinxcontrib-qthelp==2.0.0
# via sphinx
sphinxcontrib-serializinghtml==2.0.0
# via sphinx
toposort==1.10
# via pip-compile-multi
tox==4.23.2
# via -r dev.in
trio==0.27.0
# via -r /Users/david/Projects/jinja/requirements/tests.in
typing-extensions==4.12.2
# via mypy
urllib3==2.2.3
# via requests
virtualenv==20.28.0
# via
# pre-commit
# tox
wheel==0.45.1
# via pip-tools
# The following packages are considered to be unsafe in a requirements file:
# pip
# setuptools

View File

@ -1,3 +0,0 @@
pallets-sphinx-themes
sphinx
sphinxcontrib-log-cabinet

View File

@ -1,63 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile docs.in
#
alabaster==1.0.0
# via sphinx
babel==2.16.0
# via sphinx
certifi==2024.12.14
# via requests
charset-normalizer==3.4.0
# via requests
docutils==0.21.2
# via sphinx
idna==3.10
# via requests
imagesize==1.4.1
# via sphinx
jinja2==3.1.4
# via sphinx
markupsafe==3.0.2
# via jinja2
packaging==24.2
# via
# pallets-sphinx-themes
# sphinx
pallets-sphinx-themes==2.3.0
# via -r docs.in
pygments==2.18.0
# via sphinx
requests==2.32.3
# via sphinx
snowballstemmer==2.2.0
# via sphinx
sphinx==8.1.3
# via
# -r docs.in
# pallets-sphinx-themes
# sphinx-issues
# sphinx-notfound-page
# sphinxcontrib-log-cabinet
sphinx-issues==5.0.0
# via -r docs.in
sphinx-notfound-page==1.0.4
# via pallets-sphinx-themes
sphinxcontrib-applehelp==2.0.0
# via sphinx
sphinxcontrib-devhelp==2.0.0
# via sphinx
sphinxcontrib-htmlhelp==2.1.0
# via sphinx
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-log-cabinet==1.0.1
# via -r docs.in
sphinxcontrib-qthelp==2.0.0
# via sphinx
sphinxcontrib-serializinghtml==2.0.0
# via sphinx
urllib3==2.2.3
# via requests

View File

@ -1,2 +0,0 @@
pytest
trio

View File

@ -1,28 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile tests.in
#
attrs==24.3.0
# via
# outcome
# trio
idna==3.10
# via trio
iniconfig==2.0.0
# via pytest
outcome==1.3.0.post0
# via trio
packaging==24.2
# via pytest
pluggy==1.5.0
# via pytest
pytest==8.3.4
# via -r tests.in
sniffio==1.3.1
# via trio
sortedcontainers==2.4.0
# via trio
trio==0.27.0
# via -r tests.in

View File

@ -1,3 +0,0 @@
mypy
pyright
pytest

View File

@ -1,12 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile typing.in
#
mypy==1.14.0
# via -r typing.in
mypy-extensions==1.0.0
# via mypy
typing-extensions==4.12.2
# via mypy

52
tox.ini
View File

@ -1,52 +0,0 @@
[tox]
envlist =
py3{13,12,11,10,9,8}
pypy310
style
typing
docs
skip_missing_interpreters = true
[testenv]
package = wheel
wheel_build_env = .pkg
constrain_package_deps = true
use_frozen_constraints = true
deps = -r requirements/tests.txt
commands = pytest -v --tb=short --basetemp={envtmpdir} {posargs}
[testenv:style]
deps = pre-commit
skip_install = true
commands = pre-commit run --all-files
[testenv:typing]
deps = -r requirements/typing.txt
commands = mypy
[testenv:docs]
deps = -r requirements/docs.txt
commands = sphinx-build -E -W -b dirhtml docs docs/_build/dirhtml
[testenv:update-actions]
labels = update
deps = gha-update
commands = gha-update
[testenv:update-pre_commit]
labels = update
deps = pre-commit
skip_install = true
commands = pre-commit autoupdate -j4
[testenv:update-requirements]
labels = update
deps = pip-tools
skip_install = true
change_dir = requirements
commands =
pip-compile build.in -q {posargs:-U}
pip-compile docs.in -q {posargs:-U}
pip-compile tests.in -q {posargs:-U}
pip-compile typing.in -q {posargs:-U}
pip-compile dev.in -q {posargs:-U}

1415
uv.lock generated Normal file

File diff suppressed because it is too large Load Diff