Skip to content

Commit af40e0b

Browse files
author
Martin Belanger
committed
swig: fix Py_NewRef compatibility with Python < 3.10
SWIG >= 4.1 generates calls to Py_NewRef() in its runtime boilerplate. Py_NewRef was introduced in Python 3.10, causing an undefined symbol error on older distributions (e.g. SLES 15.6/15.7 with Python 3.6). The shim must live in a %begin block so it precedes SWIG's own runtime in the generated C file. Since Python.h is not yet included at that point, PyObject is unavailable, so a macro is used instead of an inline function. A -DSWIG_COMPAT_PY_NEWREF flag, set by meson when Py_NewRef is absent, gates the macro so it never conflicts with Python 3.10+'s own definition. Signed-off-by: Martin Belanger <[email protected]> Assisted-by: Claude Sonnet 4.6 <[email protected]>
1 parent f018b37 commit af40e0b

2 files changed

Lines changed: 17 additions & 0 deletions

File tree

libnvme/libnvme/meson.build

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ if want_python
1414
swig_cmd = [swig, '-python', '-o', '@OUTPUT1@', '@INPUT0@']
1515
endif
1616

17+
py_compat_c_args = []
18+
if not cc.has_header_symbol('Python.h', 'Py_NewRef', dependencies: py3_dep)
19+
warning('Python < 3.10 detected: providing Py_NewRef compatibility shim in nvme.i')
20+
py_compat_c_args = ['-DSWIG_COMPAT_PY_NEWREF']
21+
endif
22+
1723
pymod_swig = custom_target(
1824
'nvme.py',
1925
input: ['nvme.i'],
@@ -28,6 +34,7 @@ if want_python
2834
pynvme_clib = python3.extension_module(
2935
'_nvme',
3036
nvme_wrap_c,
37+
c_args: py_compat_c_args,
3138
dependencies: [config_dep, ccan_dep, libnvme_dep, py3_dep],
3239
install: true,
3340
subdir: 'libnvme',

libnvme/libnvme/nvme.i

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@
1010
clashes with the same macro defined in Python.h.
1111
*/
1212
#undef fallthrough
13+
14+
/* WORKAROUND: Py_NewRef() was introduced in Python 3.10. SWIG >= 4.1 generates
15+
calls to it in its runtime boilerplate. On older distributions,
16+
meson detects the absence of Py_NewRef and passes
17+
-DSWIG_COMPAT_PY_NEWREF so we can provide a macro shim here,
18+
before Python.h is included.
19+
*/
20+
#ifdef SWIG_COMPAT_PY_NEWREF
21+
#define Py_NewRef(obj) (Py_INCREF(obj), (obj))
22+
#endif
1323
%}
1424

1525
%module(docstring="Python bindings for libnvme") nvme

0 commit comments

Comments
 (0)