Skip to content

Commit 4270353

Browse files
committed
Merge branch 'stable'
2 parents de44041 + 5abca29 commit 4270353

File tree

5 files changed

+57
-20
lines changed

5 files changed

+57
-20
lines changed

.github/workflows/publish.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ jobs:
6363
CIBW_SKIP: pp*
6464
CIBW_ARCHS_LINUX: auto aarch64
6565
CIBW_ARCHS_MACOS: auto universal2
66+
CIBW_ARCHS_WINDOWS: auto ARM64
6667
CIBW_ENABLE: cpython-freethreading
6768
CIBW_BUILD_FRONTEND: build[uv]
6869
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2

CHANGES.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ Version 3.1.0
44
Unreleased
55

66

7+
Version 3.0.3
8+
-------------
9+
10+
Unreleased
11+
12+
- ``__version__`` raises ``DeprecationWarning`` instead of ``UserWarning``.
13+
:issue:`487`
14+
- Adopt multi-phase initialisation (:pep:`489`) for the C extension.
15+
:issue:`494`
16+
- Build Windows ARM64 wheels. :issue:`485`
17+
18+
719
Version 3.0.2
820
-------------
921

src/markupsafe/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ def __getattr__(name: str) -> t.Any:
388388
"The '__version__' attribute is deprecated and will be removed in"
389389
" MarkupSafe 3.1. Use feature detection, or"
390390
' `importlib.metadata.version("markupsafe")`, instead.',
391+
DeprecationWarning,
391392
stacklevel=2,
392393
)
393394
return importlib.metadata.version("markupsafe")

src/markupsafe/_speedups.c

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -175,30 +175,26 @@ static PyMethodDef module_methods[] = {
175175
{NULL, NULL, 0, NULL} /* Sentinel */
176176
};
177177

178+
static PyModuleDef_Slot module_slots[] = {
179+
#ifdef Py_mod_multiple_interpreters // Python 3.12+
180+
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
181+
#endif
182+
#ifdef Py_mod_gil // Python 3.13+
183+
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
184+
#endif
185+
{0, NULL} /* Sentinel */
186+
};
187+
178188
static struct PyModuleDef module_definition = {
179-
PyModuleDef_HEAD_INIT,
180-
"markupsafe._speedups",
181-
NULL,
182-
-1,
183-
module_methods,
184-
NULL,
185-
NULL,
186-
NULL,
187-
NULL
189+
.m_base = PyModuleDef_HEAD_INIT,
190+
.m_name = "markupsafe._speedups",
191+
.m_size = 0,
192+
.m_methods = module_methods,
193+
.m_slots = module_slots,
188194
};
189195

190196
PyMODINIT_FUNC
191197
PyInit__speedups(void)
192198
{
193-
PyObject *m = PyModule_Create(&module_definition);
194-
195-
if (m == NULL) {
196-
return NULL;
197-
}
198-
199-
#ifdef Py_GIL_DISABLED
200-
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
201-
#endif
202-
203-
return m;
199+
return PyModuleDef_Init(&module_definition);
204200
}

tests/test_ext_init.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import sys
2+
3+
import pytest
4+
5+
import markupsafe
6+
7+
try:
8+
from markupsafe import _speedups
9+
except ImportError:
10+
_speedups = None # type: ignore[assignment]
11+
12+
13+
@pytest.mark.skipif(_speedups is None, reason="speedups unavailable")
14+
def test_ext_init() -> None:
15+
"""Test that the extension module uses multi-phase init by checking that
16+
uncached imports result in different module objects.
17+
"""
18+
if markupsafe._escape_inner is not _speedups._escape_inner: # type: ignore[attr-defined]
19+
pytest.skip("speedups not active")
20+
21+
for k in [k for k in sys.modules if k.startswith("markupsafe")]:
22+
del sys.modules[k]
23+
24+
import markupsafe._speedups as new
25+
26+
assert _speedups.__dict__ != new.__dict__
27+
assert _speedups._escape_inner is not new._escape_inner

0 commit comments

Comments
 (0)