summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Berg <sebastian@sipsolutions.net>2022-01-14 15:01:32 -0600
committerGitHub <noreply@github.com>2022-01-14 15:01:32 -0600
commitf40b105d627096ef04ca7a5ccbcd6ff53d810be6 (patch)
treea33d3a80dc0b741ec6e24392ff5c17e05e7e4483
parentae270c3346499e73693730050e0f0b2272bd7e5c (diff)
parent1edd6407d008fcaa282a6058ae355025c26517fd (diff)
downloadnumpy-f40b105d627096ef04ca7a5ccbcd6ff53d810be6.tar.gz
Merge pull request #20818 from lpsinger/test-third-party-c-extensions-limited-api
BUG: Fix build of third-party extensions with Py_LIMITED_API
-rw-r--r--numpy/core/include/numpy/ufuncobject.h6
-rw-r--r--numpy/core/tests/examples/cython/checks.pyx (renamed from numpy/core/tests/examples/checks.pyx)0
-rw-r--r--numpy/core/tests/examples/cython/setup.py (renamed from numpy/core/tests/examples/setup.py)0
-rw-r--r--numpy/core/tests/examples/limited_api/limited_api.c17
-rw-r--r--numpy/core/tests/examples/limited_api/setup.py22
-rw-r--r--numpy/core/tests/test_cython.py2
-rw-r--r--numpy/core/tests/test_limited_api.py41
7 files changed, 86 insertions, 2 deletions
diff --git a/numpy/core/include/numpy/ufuncobject.h b/numpy/core/include/numpy/ufuncobject.h
index 1d7050bbe..bb0633100 100644
--- a/numpy/core/include/numpy/ufuncobject.h
+++ b/numpy/core/include/numpy/ufuncobject.h
@@ -173,7 +173,11 @@ typedef struct _tagPyUFuncObject {
* but this was never implemented. (This is also why the above
* selector is called the "legacy" selector.)
*/
- vectorcallfunc vectorcall;
+ #ifndef Py_LIMITED_API
+ vectorcallfunc vectorcall;
+ #else
+ void *vectorcall;
+ #endif
/* Was previously the `PyUFunc_MaskedInnerLoopSelectionFunc` */
void *_always_null_previously_masked_innerloop_selector;
diff --git a/numpy/core/tests/examples/checks.pyx b/numpy/core/tests/examples/cython/checks.pyx
index 151979db7..151979db7 100644
--- a/numpy/core/tests/examples/checks.pyx
+++ b/numpy/core/tests/examples/cython/checks.pyx
diff --git a/numpy/core/tests/examples/setup.py b/numpy/core/tests/examples/cython/setup.py
index 6e34aa778..6e34aa778 100644
--- a/numpy/core/tests/examples/setup.py
+++ b/numpy/core/tests/examples/cython/setup.py
diff --git a/numpy/core/tests/examples/limited_api/limited_api.c b/numpy/core/tests/examples/limited_api/limited_api.c
new file mode 100644
index 000000000..698c54c57
--- /dev/null
+++ b/numpy/core/tests/examples/limited_api/limited_api.c
@@ -0,0 +1,17 @@
+#define Py_LIMITED_API 0x03060000
+
+#include <Python.h>
+#include <numpy/arrayobject.h>
+#include <numpy/ufuncobject.h>
+
+static PyModuleDef moduledef = {
+ .m_base = PyModuleDef_HEAD_INIT,
+ .m_name = "limited_api"
+};
+
+PyMODINIT_FUNC PyInit_limited_api(void)
+{
+ import_array();
+ import_umath();
+ return PyModule_Create(&moduledef);
+}
diff --git a/numpy/core/tests/examples/limited_api/setup.py b/numpy/core/tests/examples/limited_api/setup.py
new file mode 100644
index 000000000..18747dc80
--- /dev/null
+++ b/numpy/core/tests/examples/limited_api/setup.py
@@ -0,0 +1,22 @@
+"""
+Build an example package using the limited Python C API.
+"""
+
+import numpy as np
+from setuptools import setup, Extension
+import os
+
+macros = [("NPY_NO_DEPRECATED_API", 0), ("Py_LIMITED_API", "0x03060000")]
+
+limited_api = Extension(
+ "limited_api",
+ sources=[os.path.join('.', "limited_api.c")],
+ include_dirs=[np.get_include()],
+ define_macros=macros,
+)
+
+extensions = [limited_api]
+
+setup(
+ ext_modules=extensions
+)
diff --git a/numpy/core/tests/test_cython.py b/numpy/core/tests/test_cython.py
index a1f09d0fe..9896de0ec 100644
--- a/numpy/core/tests/test_cython.py
+++ b/numpy/core/tests/test_cython.py
@@ -32,7 +32,7 @@ def install_temp(request, tmp_path):
# Based in part on test_cython from random.tests.test_extending
here = os.path.dirname(__file__)
- ext_dir = os.path.join(here, "examples")
+ ext_dir = os.path.join(here, "examples", "cython")
cytest = str(tmp_path / "cytest")
diff --git a/numpy/core/tests/test_limited_api.py b/numpy/core/tests/test_limited_api.py
new file mode 100644
index 000000000..0bb543d59
--- /dev/null
+++ b/numpy/core/tests/test_limited_api.py
@@ -0,0 +1,41 @@
+import os
+import shutil
+import subprocess
+import sys
+import sysconfig
+import pytest
+
+
+@pytest.mark.xfail(
+ sysconfig.get_config_var("Py_DEBUG"),
+ reason=(
+ "Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, "
+ "and Py_REF_DEBUG"
+ ),
+)
+def test_limited_api(tmp_path):
+ """Test building a third-party C extension with the limited API."""
+ # Based in part on test_cython from random.tests.test_extending
+
+ here = os.path.dirname(__file__)
+ ext_dir = os.path.join(here, "examples", "limited_api")
+
+ cytest = str(tmp_path / "limited_api")
+
+ shutil.copytree(ext_dir, cytest)
+ # build the examples and "install" them into a temporary directory
+
+ install_log = str(tmp_path / "tmp_install_log.txt")
+ subprocess.check_call(
+ [
+ sys.executable,
+ "setup.py",
+ "build",
+ "install",
+ "--prefix", str(tmp_path / "installdir"),
+ "--single-version-externally-managed",
+ "--record",
+ install_log,
+ ],
+ cwd=cytest,
+ )