From 2e319624f33d585b9f5209f6c6b607a5c3308157 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Mon, 21 Aug 2023 21:16:32 +0200 Subject: [PATCH] smoketests: add a test for the limited API This builds the test module twice, once normally and once for the limited API. In the later case we check at runtime if libpython3.dll is loaded, to make sure we are actually linked against it and not against libpython3.x.dll. This depends on both: * https://github.com/msys2-contrib/cpython-mingw/pull/148 * https://github.com/msys2/MINGW-packages/pull/18232 --- mingw_smoketests.py | 47 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/mingw_smoketests.py b/mingw_smoketests.py index ca1f652caeec27..bb08462e507df7 100644 --- a/mingw_smoketests.py +++ b/mingw_smoketests.py @@ -265,6 +265,12 @@ def test_site(self): self.assertEqual(len(site.getsitepackages()), 1) def test_c_ext_build(self): + self._test_c_ext_build(False) + + def test_c_ext_build_limited_api(self): + self._test_c_ext_build(True) + + def _test_c_ext_build(self, py_limited_api): import tempfile import sys import subprocess @@ -279,32 +285,47 @@ def test_c_ext_build(self): """\ from setuptools import setup, Extension + if %(py_limited_api)s: + ext = Extension( + 'cwrapper', + py_limited_api=True, + define_macros=[('Py_LIMITED_API', '0x03060000')], + sources=['cwrapper.c']) + else: + ext = Extension( + 'cwrapper', + sources=['cwrapper.c']) + setup( name='cwrapper', version='1.0', - ext_modules=[ - Extension( - 'cwrapper', - sources=['cwrapper.c']), - ], + ext_modules=[ext], ) - """ + """ % {"py_limited_api": py_limited_api} ) ) + with Path(tmppro, "cwrapper.c").open("w") as f: f.write( textwrap.dedent( """\ #include + #include static PyObject * helloworld(PyObject *self, PyObject *args) { printf("Hello World\\n"); Py_RETURN_NONE; } + static PyObject * + islimited(PyObject *self, PyObject *args) + { + return PyBool_FromLong(GetModuleHandleA("libpython3.dll") != NULL); + } static PyMethodDef myMethods[] = { { "helloworld", helloworld, METH_NOARGS, "Prints Hello World" }, + { "islimited", islimited, METH_NOARGS, "Returns True if the limited API is used" }, { NULL, NULL, 0, NULL } }; static struct PyModuleDef cwrapper = { @@ -323,6 +344,16 @@ def test_c_ext_build(self): """ ) ) + + if py_limited_api: + with Path(tmppro, "setup.cfg").open("w") as f: + f.write(textwrap.dedent( + """\ + [bdist_wheel] + py_limited_api=cp36 + """ + )) + subprocess.check_call( [sys.executable, "-c", "import struct"], ) @@ -347,6 +378,10 @@ def test_c_ext_build(self): subprocess.check_call( [sys.executable, "-c", "import cwrapper"], ) + # Make sure the resulting extension uses the limited API, or not + subprocess.check_call( + [sys.executable, "-c", f"import cwrapper; assert cwrapper.islimited() == {py_limited_api}"], + )