Skip to content

Commit b2e4d9c

Browse files
committed
Merge branch 'stable'
2 parents 1251593 + adf9f3d commit b2e4d9c

File tree

9 files changed

+434
-295
lines changed

9 files changed

+434
-295
lines changed

.github/workflows/pre-commit.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ jobs:
77
main:
88
runs-on: ubuntu-latest
99
steps:
10-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
11-
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
10+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
11+
- uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v6.7.0
1212
with:
1313
enable-cache: true
1414
prune-cache: false
15-
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
15+
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
1616
id: setup-python
1717
with:
1818
python-version-file: pyproject.toml
19-
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
19+
- uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
2020
with:
2121
path: ~/.cache/pre-commit
2222
key: pre-commit|${{ hashFiles('pyproject.toml', '.pre-commit-config.yaml') }}

.github/workflows/publish.yaml

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ jobs:
1616
sdist:
1717
runs-on: ubuntu-latest
1818
steps:
19-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
19+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
2020
with:
2121
ref: ${{ inputs.tag }}
22-
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
22+
- uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v6.7.0
2323
with:
2424
enable-cache: true
2525
prune-cache: false
26-
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
26+
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
2727
with:
2828
python-version-file: pyproject.toml
2929
- run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
@@ -43,27 +43,21 @@ jobs:
4343
matrix:
4444
os: [ubuntu-latest, windows-latest, macos-latest]
4545
steps:
46-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
47-
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
46+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
47+
- uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v6.7.0
4848
with:
4949
enable-cache: true
5050
prune-cache: false
5151
- name: Set up QEMU
5252
if: runner.os == 'Linux'
5353
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
5454
with:
55-
platforms: arm64
55+
platforms: arm64,riscv64
5656
- run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
57-
- uses: pypa/cibuildwheel@faf86a6ed7efa889faf6996aa23820831055001a # v2.23.3
57+
- uses: pypa/cibuildwheel@7c619efba910c04005a835b110b057fc28fd6e93 # v3.2.0
5858
env:
5959
# For workflow_dispatch, only build the new Python version.
6060
CIBW_BUILD: ${{ inputs.python && format('{0}-*', inputs.python) || null }}
61-
CIBW_SKIP: pp*
62-
CIBW_ARCHS_LINUX: auto aarch64
63-
CIBW_ARCHS_MACOS: auto universal2
64-
CIBW_ARCHS_WINDOWS: auto ARM64
65-
CIBW_ENABLE: cpython-freethreading
66-
CIBW_BUILD_FRONTEND: build[uv]
6761
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
6862
with:
6963
name: build-wheels-${{ matrix.os }}
@@ -74,7 +68,7 @@ jobs:
7468
permissions:
7569
contents: write
7670
steps:
77-
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
71+
- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
7872
with:
7973
path: dist
8074
pattern: build-*
@@ -106,11 +100,11 @@ jobs:
106100
permissions:
107101
id-token: write
108102
steps:
109-
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
103+
- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
110104
with:
111105
path: dist
112106
pattern: build-*
113107
merge-multiple: true
114-
- uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4
108+
- uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
115109
with:
116110
skip-existing: true

.github/workflows/tests.yaml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,42 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
include:
16+
- {python: '3.14'}
17+
- {python: '3.14t'}
18+
- {name: Windows, python: '3.14', os: windows-latest}
19+
- {name: Mac, python: '3.14', os: macos-latest}
1620
- {python: '3.13'}
1721
- {python: '3.13t'}
18-
- {name: Windows, python: '3.13', os: windows-latest}
19-
- {name: Mac, python: '3.13', os: macos-latest}
2022
- {python: '3.12'}
2123
- {python: '3.11'}
2224
- {python: '3.10'}
2325
- {name: PyPy, python: 'pypy-3.11', tox: pypy311}
2426
steps:
25-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
26-
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
27+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
28+
- uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v6.7.0
2729
with:
2830
enable-cache: true
2931
prune-cache: false
30-
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
32+
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
3133
with:
3234
python-version: ${{ matrix.python }}
3335
allow-prereleases: true
3436
- run: uv run --locked tox run -e ${{ matrix.tox || format('py{0}', matrix.python) }}
37+
- if: endsWith(matrix.python, 't')
38+
run: uv run --locked tox run -e parallel
3539
typing:
3640
runs-on: ubuntu-latest
3741
steps:
38-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
39-
- uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0
42+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
43+
- uses: astral-sh/setup-uv@b75a909f75acd358c2196fb9a5f1299a9a8868a4 # v6.7.0
4044
with:
4145
enable-cache: true
4246
prune-cache: false
43-
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
47+
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
4448
with:
4549
python-version-file: pyproject.toml
4650
- name: cache mypy
47-
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
51+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
4852
with:
4953
path: ./.mypy_cache
5054
key: mypy|${{ hashFiles('pyproject.toml') }}

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
repos:
22
- repo: https://github.com/astral-sh/ruff-pre-commit
3-
rev: 76e47323a83cd9795e4ff9a1de1c0d2eef610f17 # frozen: v0.11.11
3+
rev: f298305809c552671cc47e0fec0ba43e96c146a2 # frozen: v0.13.2
44
hooks:
55
- id: ruff
66
- id: ruff-format
77
- repo: https://github.com/astral-sh/uv-pre-commit
8-
rev: 648bdbfd6bb1a82f132ecc2c666e0d1b2e4b0d94 # frozen: 0.7.8
8+
rev: 9e8320f8d22dfa502984f75bb72d6bba825e570c # frozen: 0.8.22
99
hooks:
1010
- id: uv-lock
1111
- repo: https://github.com/pre-commit/pre-commit-hooks
12-
rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b # frozen: v5.0.0
12+
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0
1313
hooks:
1414
- id: check-merge-conflict
1515
- id: debug-statements

CHANGES.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ Unreleased
1010
Version 3.0.3
1111
-------------
1212

13-
Unreleased
13+
Released 2025-09-27
1414

1515
- ``__version__`` raises ``DeprecationWarning`` instead of ``UserWarning``.
1616
:issue:`487`
1717
- Adopt multi-phase initialisation (:pep:`489`) for the C extension.
1818
:issue:`494`
1919
- Build Windows ARM64 wheels. :issue:`485`
20+
- Build Python 3.14 wheels. :issue:`503`
21+
- Build riscv64 wheels. :issue:`505`
2022

2123

2224
Version 3.0.2

pyproject.toml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pre-commit = [
4848
]
4949
tests = [
5050
"pytest",
51+
"pytest-run-parallel; python_full_version >= '3.13'",
5152
]
5253
typing = [
5354
"mypy",
@@ -67,7 +68,10 @@ testpaths = ["tests"]
6768
filterwarnings = [
6869
"error",
6970
]
70-
71+
markers = [
72+
# Needed when pytest-run-parallel is not installed
73+
"thread_unsafe: mark test as not safe to run in multiple threads",
74+
]
7175
[tool.coverage.run]
7276
branch = true
7377
source = ["markupsafe", "tests"]
@@ -124,6 +128,7 @@ tag-only = [
124128

125129
[tool.tox]
126130
env_list = [
131+
"py3.14", "py3.14t", "parallel",
127132
"py3.13", "py3.13t", "py3.12", "py3.11", "py3.10",
128133
"pypy3.11",
129134
"style",
@@ -144,6 +149,15 @@ commands = [[
144149
{replace = "posargs", default = [], extend = true},
145150
]]
146151

152+
[tool.tox.env.parallel]
153+
description = "check for free threading issues"
154+
base_python = ["3.14t"]
155+
commands = [[
156+
"pytest", "-v", "--tb=short", "--basetemp=env_tmp_dir",
157+
"--parallel-threads=8",
158+
{replace = "posargs", default = [], extend = true},
159+
]]
160+
147161
[tool.tox.env.style]
148162
description = "run all pre-commit hooks on all files"
149163
dependency_groups = ["pre-commit"]
@@ -188,3 +202,21 @@ dependency_groups = []
188202
no_default_groups = true
189203
skip_install = true
190204
commands = [["uv", "lock", {replace = "posargs", default = ["-U"], extend = true}]]
205+
206+
[tool.cibuildwheel]
207+
enable = "cpython-freethreading"
208+
build-frontend = "build[uv]"
209+
210+
[[tool.cibuildwheel.overrides]]
211+
select = "*-musllinux_riscv64"
212+
# uv is not available
213+
build-frontend = "build"
214+
215+
[tool.cibuildwheel.linux]
216+
archs = ["x86_64", "aarch64", "riscv64"]
217+
218+
[tool.cibuildwheel.macos]
219+
archs = ["x86_64", "arm64"]
220+
221+
[tool.cibuildwheel.windows]
222+
archs = ["auto", "ARM64"]

tests/test_ext_init.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
_speedups = None # type: ignore[assignment]
1111

1212

13+
@pytest.mark.thread_unsafe(reason="Tampers with sys.modules")
1314
@pytest.mark.skipif(_speedups is None, reason="speedups unavailable")
1415
def test_ext_init() -> None:
1516
"""Test that the extension module uses multi-phase init by checking that

tests/test_leak.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
import gc
44

5+
import pytest
6+
57
from markupsafe import escape
68

79

10+
@pytest.mark.thread_unsafe(reason="Tests gc.get_objects()")
811
def test_markup_leaks() -> None:
912
counts = set()
1013
# Try to start with a "clean" count. Works for PyPy but not 3.13 JIT.

0 commit comments

Comments
 (0)