Skip to content

Commit fdd3de0

Browse files
AA-Turnerdavidism
authored andcommitted
Adopt multi-phase init (PEP 489)
1 parent dec39fe commit fdd3de0

File tree

3 files changed

+56
-20
lines changed

3 files changed

+56
-20
lines changed

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Unreleased
55

66
- ``__version__`` raises ``DeprecationWarning`` instead of ``UserWarning``.
77
:issue:`487`
8+
- Adopt multi-phase initialisation (:pep:`489`) for the C extension.
9+
:issue:`494`
810

911

1012
Version 3.0.2

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_reloading.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import subprocess
2+
import sys
3+
4+
import pytest
5+
6+
import markupsafe
7+
8+
try:
9+
from markupsafe import _speedups
10+
except ImportError:
11+
_speedups = None # type: ignore
12+
13+
14+
@pytest.mark.skipif(_speedups is None, reason="speedups unavailable")
15+
def test_reload():
16+
if markupsafe._escape_inner is not _speedups._escape_inner:
17+
pytest.skip("speedups not active")
18+
19+
code = r"""
20+
import sys
21+
import markupsafe._speedups as old
22+
23+
for k in [k for k in sys.modules if k.startswith('markupsafe')]:
24+
del sys.modules[k]
25+
26+
import markupsafe._speedups as new
27+
28+
assert old.__dict__ != new.__dict__
29+
assert old._escape_inner is not new._escape_inner
30+
"""
31+
p = subprocess.run(
32+
(sys.executable, "-c", code),
33+
stdout=subprocess.PIPE,
34+
stderr=subprocess.STDOUT,
35+
encoding="utf-8",
36+
check=False,
37+
)
38+
assert p.returncode == 0, p.stdout

0 commit comments

Comments
 (0)