@@ -265,6 +265,12 @@ def test_site(self):
265
265
self .assertEqual (len (site .getsitepackages ()), 1 )
266
266
267
267
def test_c_ext_build (self ):
268
+ self ._test_c_ext_build (False )
269
+
270
+ def test_c_ext_build_limited_api (self ):
271
+ self ._test_c_ext_build (True )
272
+
273
+ def _test_c_ext_build (self , py_limited_api ):
268
274
import tempfile
269
275
import sys
270
276
import subprocess
@@ -279,32 +285,47 @@ def test_c_ext_build(self):
279
285
"""\
280
286
from setuptools import setup, Extension
281
287
288
+ if %(py_limited_api)s:
289
+ ext = Extension(
290
+ 'cwrapper',
291
+ py_limited_api=True,
292
+ define_macros=[('Py_LIMITED_API', '0x03060000')],
293
+ sources=['cwrapper.c'])
294
+ else:
295
+ ext = Extension(
296
+ 'cwrapper',
297
+ sources=['cwrapper.c'])
298
+
282
299
setup(
283
300
name='cwrapper',
284
301
version='1.0',
285
- ext_modules=[
286
- Extension(
287
- 'cwrapper',
288
- sources=['cwrapper.c']),
289
- ],
302
+ ext_modules=[ext],
290
303
)
291
- """
304
+ """ % { "py_limited_api" : py_limited_api }
292
305
)
293
306
)
307
+
294
308
with Path (tmppro , "cwrapper.c" ).open ("w" ) as f :
295
309
f .write (
296
310
textwrap .dedent (
297
311
"""\
298
312
#include <Python.h>
313
+ #include <windows.h>
299
314
static PyObject *
300
315
helloworld(PyObject *self, PyObject *args)
301
316
{
302
317
printf("Hello World\\ n");
303
318
Py_RETURN_NONE;
304
319
}
320
+ static PyObject *
321
+ islimited(PyObject *self, PyObject *args)
322
+ {
323
+ return PyBool_FromLong(GetModuleHandleA("libpython3.dll") != NULL);
324
+ }
305
325
static PyMethodDef
306
326
myMethods[] = {
307
327
{ "helloworld", helloworld, METH_NOARGS, "Prints Hello World" },
328
+ { "islimited", islimited, METH_NOARGS, "Returns True if the limited API is used" },
308
329
{ NULL, NULL, 0, NULL }
309
330
};
310
331
static struct PyModuleDef cwrapper = {
@@ -323,6 +344,16 @@ def test_c_ext_build(self):
323
344
"""
324
345
)
325
346
)
347
+
348
+ if py_limited_api :
349
+ with Path (tmppro , "setup.cfg" ).open ("w" ) as f :
350
+ f .write (textwrap .dedent (
351
+ """\
352
+ [bdist_wheel]
353
+ py_limited_api=cp36
354
+ """
355
+ ))
356
+
326
357
subprocess .check_call (
327
358
[sys .executable , "-c" , "import struct" ],
328
359
)
@@ -347,6 +378,10 @@ def test_c_ext_build(self):
347
378
subprocess .check_call (
348
379
[sys .executable , "-c" , "import cwrapper" ],
349
380
)
381
+ # Make sure the resulting extension uses the limited API, or not
382
+ subprocess .check_call (
383
+ [sys .executable , "-c" , f"import cwrapper; assert cwrapper.islimited() == { py_limited_api } " ],
384
+ )
350
385
351
386
352
387
0 commit comments