We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
import_array hides true cause of import errors
When compiling for Python 3, it would be useful to utilize exception chaining to explain why "numpy.core.multiarray failed to import". I think you can use [PyException_SetCause](https://docs.python.org/3/c-api/exceptions.html#c.PyException_SetCause) to do this?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `numpy/core/code_generators/generate_numpy_api.py`
Content:
```
1 from __future__ import division, print_function
2 
3 import os
4 import genapi
5 
6 from genapi import \
7         TypeApi, GlobalVarApi, FunctionApi, BoolValuesApi
8 
9 import numpy_api
10 
11 # use annotated api when running under cpychecker
12 h_template = r"""
13 #if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)
14 
15 typedef struct {
16         PyObject_HEAD
17         npy_bool obval;
18 } PyBoolScalarObject;
19 
20 extern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type;
21 extern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type;
22 extern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];
23 
24 %s
25 
26 #else
27 
28 #if defined(PY_ARRAY_UNIQUE_SYMBOL)
29 #define PyArray_API PY_ARRAY_UNIQUE_SYMBOL
30 #endif
31 
32 #if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)
33 extern void **PyArray_API;
34 #else
35 #if defined(PY_ARRAY_UNIQUE_SYMBOL)
36 void **PyArray_API;
37 #else
38 static void **PyArray_API=NULL;
39 #endif
40 #endif
41 
42 %s
43 
44 #if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
45 static int
46 _import_array(void)
47 {
48   int st;
49   PyObject *numpy = PyImport_ImportModule("numpy.core._multiarray_umath");
50   PyObject *c_api = NULL;
51 
52   if (numpy == NULL) {
53       PyErr_SetString(PyExc_ImportError, "numpy.core._multiarray_umath failed to import");
54       return -1;
55   }
56   c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
57   Py_DECREF(numpy);
58   if (c_api == NULL) {
59       PyErr_SetString(PyExc_AttributeError, "_ARRAY_API not found");
60       return -1;
61   }
62 
63 #if PY_VERSION_HEX >= 0x03000000
64   if (!PyCapsule_CheckExact(c_api)) {
65       PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCapsule object");
66       Py_DECREF(c_api);
67       return -1;
68   }
69   PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL);
70 #else
71   if (!PyCObject_Check(c_api)) {
72       PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is not PyCObject object");
73       Py_DECREF(c_api);
74       return -1;
75   }
76   PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);
77 #endif
78   Py_DECREF(c_api);
79   if (PyArray_API == NULL) {
80       PyErr_SetString(PyExc_RuntimeError, "_ARRAY_API is NULL pointer");
81       return -1;
82   }
83 
84   /* Perform runtime check of C API version */
85   if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
86       PyErr_Format(PyExc_RuntimeError, "module compiled against "\
87              "ABI version 0x%%x but this version of numpy is 0x%%x", \
88              (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
89       return -1;
90   }
91   if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) {
92       PyErr_Format(PyExc_RuntimeError, "module compiled against "\
93              "API version 0x%%x but this version of numpy is 0x%%x", \
94              (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion());
95       return -1;
96   }
97 
98   /*
99    * Perform runtime check of endianness and check it matches the one set by
100    * the headers (npy_endian.h) as a safeguard
101    */
102   st = PyArray_GetEndianness();
103   if (st == NPY_CPU_UNKNOWN_ENDIAN) {
104       PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as unknown endian");
105       return -1;
106   }
107 #if NPY_BYTE_ORDER == NPY_BIG_ENDIAN
108   if (st != NPY_CPU_BIG) {
109       PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
110              "big endian, but detected different endianness at runtime");
111       return -1;
112   }
113 #elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
114   if (st != NPY_CPU_LITTLE) {
115       PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
116              "little endian, but detected different endianness at runtime");
117       return -1;
118   }
119 #endif
120 
121   return 0;
122 }
123 
124 #if PY_VERSION_HEX >= 0x03000000
125 #define NUMPY_IMPORT_ARRAY_RETVAL NULL
126 #else
127 #define NUMPY_IMPORT_ARRAY_RETVAL
128 #endif
129 
130 #define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
131 
132 #define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return ret; } }
133 
134 #define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }
135 
136 #endif
137 
138 #endif
139 """
140 
141 
142 c_template = r"""
143 /* These pointers will be stored in the C-object for use in other
144     extension modules
145 */
146 
147 void *PyArray_API[] = {
148 %s
149 };
150 """
151 
152 c_api_header = """
153 ===========
154 NumPy C-API
155 ===========
156 """
157 
158 def generate_api(output_dir, force=False):
159     basename = 'multiarray_api'
160 
161     h_file = os.path.join(output_dir, '__%s.h' % basename)
162     c_file = os.path.join(output_dir, '__%s.c' % basename)
163     d_file = os.path.join(output_dir, '%s.txt' % basename)
164     targets = (h_file, c_file, d_file)
165 
166     sources = numpy_api.multiarray_api
167 
168     if (not force and not genapi.should_rebuild(targets, [numpy_api.__file__, __file__])):
169         return targets
170     else:
171         do_generate_api(targets, sources)
172 
173     return targets
174 
175 def do_generate_api(targets, sources):
176     header_file = targets[0]
177     c_file = targets[1]
178     doc_file = targets[2]
179 
180     global_vars = sources[0]
181     scalar_bool_values = sources[1]
182     types_api = sources[2]
183     multiarray_funcs = sources[3]
184 
185     multiarray_api = sources[:]
186 
187     module_list = []
188     extension_list = []
189     init_list = []
190 
191     # Check multiarray api indexes
192     multiarray_api_index = genapi.merge_api_dicts(multiarray_api)
193     genapi.check_api_dict(multiarray_api_index)
194 
195     numpyapi_list = genapi.get_api_functions('NUMPY_API',
196                                               multiarray_funcs)
197     ordered_funcs_api = genapi.order_dict(multiarray_funcs)
198 
199     # Create dict name -> *Api instance
200     api_name = 'PyArray_API'
201     multiarray_api_dict = {}
202     for f in numpyapi_list:
203         name = f.name
204         index = multiarray_funcs[name][0]
205         annotations = multiarray_funcs[name][1:]
206         multiarray_api_dict[f.name] = FunctionApi(f.name, index, annotations,
207                                                   f.return_type,
208                                                   f.args, api_name)
209 
210     for name, val in global_vars.items():
211         index, type = val
212         multiarray_api_dict[name] = GlobalVarApi(name, index, type, api_name)
213 
214     for name, val in scalar_bool_values.items():
215         index = val[0]
216         multiarray_api_dict[name] = BoolValuesApi(name, index, api_name)
217 
218     for name, val in types_api.items():
219         index = val[0]
220         multiarray_api_dict[name] = TypeApi(name, index, 'PyTypeObject', api_name)
221 
222     if len(multiarray_api_dict) != len(multiarray_api_index):
223         keys_dict = set(multiarray_api_dict.keys())
224         keys_index = set(multiarray_api_index.keys())
225         raise AssertionError(
226             "Multiarray API size mismatch - "
227             "index has extra keys {}, dict has extra keys {}"
228             .format(keys_index - keys_dict, keys_dict - keys_index)
229         )
230 
231     extension_list = []
232     for name, index in genapi.order_dict(multiarray_api_index):
233         api_item = multiarray_api_dict[name]
234         extension_list.append(api_item.define_from_array_api_string())
235         init_list.append(api_item.array_api_define())
236         module_list.append(api_item.internal_define())
237 
238     # Write to header
239     s = h_template % ('\n'.join(module_list), '\n'.join(extension_list))
240     genapi.write_file(header_file, s)
241 
242     # Write to c-code
243     s = c_template % ',\n'.join(init_list)
244     genapi.write_file(c_file, s)
245 
246     # write to documentation
247     s = c_api_header
248     for func in numpyapi_list:
249         s += func.to_ReST()
250         s += '\n\n'
251     genapi.write_file(doc_file, s)
252 
253     return targets
254
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/numpy/core/code_generators/generate_numpy_api.py b/numpy/core/code_generators/generate_numpy_api.py
--- a/numpy/core/code_generators/generate_numpy_api.py
+++ b/numpy/core/code_generators/generate_numpy_api.py
@@ -50,7 +50,6 @@
   PyObject *c_api = NULL;
 
   if (numpy == NULL) {
-      PyErr_SetString(PyExc_ImportError, "numpy.core._multiarray_umath failed to import");
       return -1;
   }
   c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");

{"golden_diff": "diff --git a/numpy/core/code_generators/generate_numpy_api.py b/numpy/core/code_generators/generate_numpy_api.py\n--- a/numpy/core/code_generators/generate_numpy_api.py\n+++ b/numpy/core/code_generators/generate_numpy_api.py\n@@ -50,7 +50,6 @@\n   PyObject *c_api = NULL;\n \n   if (numpy == NULL) {\n-      PyErr_SetString(PyExc_ImportError, \"numpy.core._multiarray_umath failed to import\");\n       return -1;\n   }\n   c_api = PyObject_GetAttrString(numpy, \"_ARRAY_API\");\n", "issue": "import_array hides true cause of import errors\nWhen compiling for Python 3, it would be useful to utilize exception chaining to explain why \"numpy.core.multiarray failed to import\". I think you can use [PyException_SetCause](https://docs.python.org/3/c-api/exceptions.html#c.PyException_SetCause) to do this?\n\n", "before_files": [{"content": "from __future__ import division, print_function\n\nimport os\nimport genapi\n\nfrom genapi import \\\n        TypeApi, GlobalVarApi, FunctionApi, BoolValuesApi\n\nimport numpy_api\n\n# use annotated api when running under cpychecker\nh_template = r\"\"\"\n#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)\n\ntypedef struct {\n        PyObject_HEAD\n        npy_bool obval;\n} PyBoolScalarObject;\n\nextern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type;\nextern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type;\nextern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];\n\n%s\n\n#else\n\n#if defined(PY_ARRAY_UNIQUE_SYMBOL)\n#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL\n#endif\n\n#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)\nextern void **PyArray_API;\n#else\n#if defined(PY_ARRAY_UNIQUE_SYMBOL)\nvoid **PyArray_API;\n#else\nstatic void **PyArray_API=NULL;\n#endif\n#endif\n\n%s\n\n#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)\nstatic int\n_import_array(void)\n{\n  int st;\n  PyObject *numpy = PyImport_ImportModule(\"numpy.core._multiarray_umath\");\n  PyObject *c_api = NULL;\n\n  if (numpy == NULL) {\n      PyErr_SetString(PyExc_ImportError, \"numpy.core._multiarray_umath failed to import\");\n      return -1;\n  }\n  c_api = PyObject_GetAttrString(numpy, \"_ARRAY_API\");\n  Py_DECREF(numpy);\n  if (c_api == NULL) {\n      PyErr_SetString(PyExc_AttributeError, \"_ARRAY_API not found\");\n      return -1;\n  }\n\n#if PY_VERSION_HEX >= 0x03000000\n  if (!PyCapsule_CheckExact(c_api)) {\n      PyErr_SetString(PyExc_RuntimeError, \"_ARRAY_API is not PyCapsule object\");\n      Py_DECREF(c_api);\n      return -1;\n  }\n  PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL);\n#else\n  if (!PyCObject_Check(c_api)) {\n      PyErr_SetString(PyExc_RuntimeError, \"_ARRAY_API is not PyCObject object\");\n      Py_DECREF(c_api);\n      return -1;\n  }\n  PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);\n#endif\n  Py_DECREF(c_api);\n  if (PyArray_API == NULL) {\n      PyErr_SetString(PyExc_RuntimeError, \"_ARRAY_API is NULL pointer\");\n      return -1;\n  }\n\n  /* Perform runtime check of C API version */\n  if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {\n      PyErr_Format(PyExc_RuntimeError, \"module compiled against \"\\\n             \"ABI version 0x%%x but this version of numpy is 0x%%x\", \\\n             (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());\n      return -1;\n  }\n  if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) {\n      PyErr_Format(PyExc_RuntimeError, \"module compiled against \"\\\n             \"API version 0x%%x but this version of numpy is 0x%%x\", \\\n             (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion());\n      return -1;\n  }\n\n  /*\n   * Perform runtime check of endianness and check it matches the one set by\n   * the headers (npy_endian.h) as a safeguard\n   */\n  st = PyArray_GetEndianness();\n  if (st == NPY_CPU_UNKNOWN_ENDIAN) {\n      PyErr_Format(PyExc_RuntimeError, \"FATAL: module compiled as unknown endian\");\n      return -1;\n  }\n#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN\n  if (st != NPY_CPU_BIG) {\n      PyErr_Format(PyExc_RuntimeError, \"FATAL: module compiled as \"\\\n             \"big endian, but detected different endianness at runtime\");\n      return -1;\n  }\n#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN\n  if (st != NPY_CPU_LITTLE) {\n      PyErr_Format(PyExc_RuntimeError, \"FATAL: module compiled as \"\\\n             \"little endian, but detected different endianness at runtime\");\n      return -1;\n  }\n#endif\n\n  return 0;\n}\n\n#if PY_VERSION_HEX >= 0x03000000\n#define NUMPY_IMPORT_ARRAY_RETVAL NULL\n#else\n#define NUMPY_IMPORT_ARRAY_RETVAL\n#endif\n\n#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, \"numpy.core.multiarray failed to import\"); return NUMPY_IMPORT_ARRAY_RETVAL; } }\n\n#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, \"numpy.core.multiarray failed to import\"); return ret; } }\n\n#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }\n\n#endif\n\n#endif\n\"\"\"\n\n\nc_template = r\"\"\"\n/* These pointers will be stored in the C-object for use in other\n    extension modules\n*/\n\nvoid *PyArray_API[] = {\n%s\n};\n\"\"\"\n\nc_api_header = \"\"\"\n===========\nNumPy C-API\n===========\n\"\"\"\n\ndef generate_api(output_dir, force=False):\n    basename = 'multiarray_api'\n\n    h_file = os.path.join(output_dir, '__%s.h' % basename)\n    c_file = os.path.join(output_dir, '__%s.c' % basename)\n    d_file = os.path.join(output_dir, '%s.txt' % basename)\n    targets = (h_file, c_file, d_file)\n\n    sources = numpy_api.multiarray_api\n\n    if (not force and not genapi.should_rebuild(targets, [numpy_api.__file__, __file__])):\n        return targets\n    else:\n        do_generate_api(targets, sources)\n\n    return targets\n\ndef do_generate_api(targets, sources):\n    header_file = targets[0]\n    c_file = targets[1]\n    doc_file = targets[2]\n\n    global_vars = sources[0]\n    scalar_bool_values = sources[1]\n    types_api = sources[2]\n    multiarray_funcs = sources[3]\n\n    multiarray_api = sources[:]\n\n    module_list = []\n    extension_list = []\n    init_list = []\n\n    # Check multiarray api indexes\n    multiarray_api_index = genapi.merge_api_dicts(multiarray_api)\n    genapi.check_api_dict(multiarray_api_index)\n\n    numpyapi_list = genapi.get_api_functions('NUMPY_API',\n                                              multiarray_funcs)\n    ordered_funcs_api = genapi.order_dict(multiarray_funcs)\n\n    # Create dict name -> *Api instance\n    api_name = 'PyArray_API'\n    multiarray_api_dict = {}\n    for f in numpyapi_list:\n        name = f.name\n        index = multiarray_funcs[name][0]\n        annotations = multiarray_funcs[name][1:]\n        multiarray_api_dict[f.name] = FunctionApi(f.name, index, annotations,\n                                                  f.return_type,\n                                                  f.args, api_name)\n\n    for name, val in global_vars.items():\n        index, type = val\n        multiarray_api_dict[name] = GlobalVarApi(name, index, type, api_name)\n\n    for name, val in scalar_bool_values.items():\n        index = val[0]\n        multiarray_api_dict[name] = BoolValuesApi(name, index, api_name)\n\n    for name, val in types_api.items():\n        index = val[0]\n        multiarray_api_dict[name] = TypeApi(name, index, 'PyTypeObject', api_name)\n\n    if len(multiarray_api_dict) != len(multiarray_api_index):\n        keys_dict = set(multiarray_api_dict.keys())\n        keys_index = set(multiarray_api_index.keys())\n        raise AssertionError(\n            \"Multiarray API size mismatch - \"\n            \"index has extra keys {}, dict has extra keys {}\"\n            .format(keys_index - keys_dict, keys_dict - keys_index)\n        )\n\n    extension_list = []\n    for name, index in genapi.order_dict(multiarray_api_index):\n        api_item = multiarray_api_dict[name]\n        extension_list.append(api_item.define_from_array_api_string())\n        init_list.append(api_item.array_api_define())\n        module_list.append(api_item.internal_define())\n\n    # Write to header\n    s = h_template % ('\\n'.join(module_list), '\\n'.join(extension_list))\n    genapi.write_file(header_file, s)\n\n    # Write to c-code\n    s = c_template % ',\\n'.join(init_list)\n    genapi.write_file(c_file, s)\n\n    # write to documentation\n    s = c_api_header\n    for func in numpyapi_list:\n        s += func.to_ReST()\n        s += '\\n\\n'\n    genapi.write_file(doc_file, s)\n\n    return targets\n", "path": "numpy/core/code_generators/generate_numpy_api.py"}], "after_files": [{"content": "from __future__ import division, print_function\n\nimport os\nimport genapi\n\nfrom genapi import \\\n        TypeApi, GlobalVarApi, FunctionApi, BoolValuesApi\n\nimport numpy_api\n\n# use annotated api when running under cpychecker\nh_template = r\"\"\"\n#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)\n\ntypedef struct {\n        PyObject_HEAD\n        npy_bool obval;\n} PyBoolScalarObject;\n\nextern NPY_NO_EXPORT PyTypeObject PyArrayMapIter_Type;\nextern NPY_NO_EXPORT PyTypeObject PyArrayNeighborhoodIter_Type;\nextern NPY_NO_EXPORT PyBoolScalarObject _PyArrayScalar_BoolValues[2];\n\n%s\n\n#else\n\n#if defined(PY_ARRAY_UNIQUE_SYMBOL)\n#define PyArray_API PY_ARRAY_UNIQUE_SYMBOL\n#endif\n\n#if defined(NO_IMPORT) || defined(NO_IMPORT_ARRAY)\nextern void **PyArray_API;\n#else\n#if defined(PY_ARRAY_UNIQUE_SYMBOL)\nvoid **PyArray_API;\n#else\nstatic void **PyArray_API=NULL;\n#endif\n#endif\n\n%s\n\n#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)\nstatic int\n_import_array(void)\n{\n  int st;\n  PyObject *numpy = PyImport_ImportModule(\"numpy.core._multiarray_umath\");\n  PyObject *c_api = NULL;\n\n  if (numpy == NULL) {\n      return -1;\n  }\n  c_api = PyObject_GetAttrString(numpy, \"_ARRAY_API\");\n  Py_DECREF(numpy);\n  if (c_api == NULL) {\n      PyErr_SetString(PyExc_AttributeError, \"_ARRAY_API not found\");\n      return -1;\n  }\n\n#if PY_VERSION_HEX >= 0x03000000\n  if (!PyCapsule_CheckExact(c_api)) {\n      PyErr_SetString(PyExc_RuntimeError, \"_ARRAY_API is not PyCapsule object\");\n      Py_DECREF(c_api);\n      return -1;\n  }\n  PyArray_API = (void **)PyCapsule_GetPointer(c_api, NULL);\n#else\n  if (!PyCObject_Check(c_api)) {\n      PyErr_SetString(PyExc_RuntimeError, \"_ARRAY_API is not PyCObject object\");\n      Py_DECREF(c_api);\n      return -1;\n  }\n  PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);\n#endif\n  Py_DECREF(c_api);\n  if (PyArray_API == NULL) {\n      PyErr_SetString(PyExc_RuntimeError, \"_ARRAY_API is NULL pointer\");\n      return -1;\n  }\n\n  /* Perform runtime check of C API version */\n  if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {\n      PyErr_Format(PyExc_RuntimeError, \"module compiled against \"\\\n             \"ABI version 0x%%x but this version of numpy is 0x%%x\", \\\n             (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());\n      return -1;\n  }\n  if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) {\n      PyErr_Format(PyExc_RuntimeError, \"module compiled against \"\\\n             \"API version 0x%%x but this version of numpy is 0x%%x\", \\\n             (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion());\n      return -1;\n  }\n\n  /*\n   * Perform runtime check of endianness and check it matches the one set by\n   * the headers (npy_endian.h) as a safeguard\n   */\n  st = PyArray_GetEndianness();\n  if (st == NPY_CPU_UNKNOWN_ENDIAN) {\n      PyErr_Format(PyExc_RuntimeError, \"FATAL: module compiled as unknown endian\");\n      return -1;\n  }\n#if NPY_BYTE_ORDER == NPY_BIG_ENDIAN\n  if (st != NPY_CPU_BIG) {\n      PyErr_Format(PyExc_RuntimeError, \"FATAL: module compiled as \"\\\n             \"big endian, but detected different endianness at runtime\");\n      return -1;\n  }\n#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN\n  if (st != NPY_CPU_LITTLE) {\n      PyErr_Format(PyExc_RuntimeError, \"FATAL: module compiled as \"\\\n             \"little endian, but detected different endianness at runtime\");\n      return -1;\n  }\n#endif\n\n  return 0;\n}\n\n#if PY_VERSION_HEX >= 0x03000000\n#define NUMPY_IMPORT_ARRAY_RETVAL NULL\n#else\n#define NUMPY_IMPORT_ARRAY_RETVAL\n#endif\n\n#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, \"numpy.core.multiarray failed to import\"); return NUMPY_IMPORT_ARRAY_RETVAL; } }\n\n#define import_array1(ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, \"numpy.core.multiarray failed to import\"); return ret; } }\n\n#define import_array2(msg, ret) {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, msg); return ret; } }\n\n#endif\n\n#endif\n\"\"\"\n\n\nc_template = r\"\"\"\n/* These pointers will be stored in the C-object for use in other\n    extension modules\n*/\n\nvoid *PyArray_API[] = {\n%s\n};\n\"\"\"\n\nc_api_header = \"\"\"\n===========\nNumPy C-API\n===========\n\"\"\"\n\ndef generate_api(output_dir, force=False):\n    basename = 'multiarray_api'\n\n    h_file = os.path.join(output_dir, '__%s.h' % basename)\n    c_file = os.path.join(output_dir, '__%s.c' % basename)\n    d_file = os.path.join(output_dir, '%s.txt' % basename)\n    targets = (h_file, c_file, d_file)\n\n    sources = numpy_api.multiarray_api\n\n    if (not force and not genapi.should_rebuild(targets, [numpy_api.__file__, __file__])):\n        return targets\n    else:\n        do_generate_api(targets, sources)\n\n    return targets\n\ndef do_generate_api(targets, sources):\n    header_file = targets[0]\n    c_file = targets[1]\n    doc_file = targets[2]\n\n    global_vars = sources[0]\n    scalar_bool_values = sources[1]\n    types_api = sources[2]\n    multiarray_funcs = sources[3]\n\n    multiarray_api = sources[:]\n\n    module_list = []\n    extension_list = []\n    init_list = []\n\n    # Check multiarray api indexes\n    multiarray_api_index = genapi.merge_api_dicts(multiarray_api)\n    genapi.check_api_dict(multiarray_api_index)\n\n    numpyapi_list = genapi.get_api_functions('NUMPY_API',\n                                              multiarray_funcs)\n    ordered_funcs_api = genapi.order_dict(multiarray_funcs)\n\n    # Create dict name -> *Api instance\n    api_name = 'PyArray_API'\n    multiarray_api_dict = {}\n    for f in numpyapi_list:\n        name = f.name\n        index = multiarray_funcs[name][0]\n        annotations = multiarray_funcs[name][1:]\n        multiarray_api_dict[f.name] = FunctionApi(f.name, index, annotations,\n                                                  f.return_type,\n                                                  f.args, api_name)\n\n    for name, val in global_vars.items():\n        index, type = val\n        multiarray_api_dict[name] = GlobalVarApi(name, index, type, api_name)\n\n    for name, val in scalar_bool_values.items():\n        index = val[0]\n        multiarray_api_dict[name] = BoolValuesApi(name, index, api_name)\n\n    for name, val in types_api.items():\n        index = val[0]\n        multiarray_api_dict[name] = TypeApi(name, index, 'PyTypeObject', api_name)\n\n    if len(multiarray_api_dict) != len(multiarray_api_index):\n        keys_dict = set(multiarray_api_dict.keys())\n        keys_index = set(multiarray_api_index.keys())\n        raise AssertionError(\n            \"Multiarray API size mismatch - \"\n            \"index has extra keys {}, dict has extra keys {}\"\n            .format(keys_index - keys_dict, keys_dict - keys_index)\n        )\n\n    extension_list = []\n    for name, index in genapi.order_dict(multiarray_api_index):\n        api_item = multiarray_api_dict[name]\n        extension_list.append(api_item.define_from_array_api_string())\n        init_list.append(api_item.array_api_define())\n        module_list.append(api_item.internal_define())\n\n    # Write to header\n    s = h_template % ('\\n'.join(module_list), '\\n'.join(extension_list))\n    genapi.write_file(header_file, s)\n\n    # Write to c-code\n    s = c_template % ',\\n'.join(init_list)\n    genapi.write_file(c_file, s)\n\n    # write to documentation\n    s = c_api_header\n    for func in numpyapi_list:\n        s += func.to_ReST()\n        s += '\\n\\n'\n    genapi.write_file(doc_file, s)\n\n    return targets\n", "path": "numpy/core/code_generators/generate_numpy_api.py"}]}