numpy 2.0.0
|
00001 /* 00002 * This is a convenience header file providing compatibility utilities 00003 * for supporting Python 2 and Python 3 in the same code base. 00004 * 00005 * If you want to use this for your own projects, it's recommended to make a 00006 * copy of it. Although the stuff below is unlikely to change, we don't provide 00007 * strong backwards compatibility guarantees at the moment. 00008 */ 00009 00010 #ifndef _NPY_3KCOMPAT_H_ 00011 #define _NPY_3KCOMPAT_H_ 00012 00013 #include <Python.h> 00014 #include <stdio.h> 00015 00016 #if PY_VERSION_HEX >= 0x03000000 00017 #ifndef NPY_PY3K 00018 #define NPY_PY3K 00019 #endif 00020 #endif 00021 00022 #include "numpy/npy_common.h" 00023 #include "numpy/ndarrayobject.h" 00024 00025 #ifdef __cplusplus 00026 extern "C" { 00027 #endif 00028 00029 /* 00030 * PyInt -> PyLong 00031 */ 00032 00033 #if defined(NPY_PY3K) 00034 /* Return True only if the long fits in a C long */ 00035 static NPY_INLINE int PyInt_Check(PyObject *op) { 00036 int overflow = 0; 00037 if (!PyLong_Check(op)) { 00038 return 0; 00039 } 00040 PyLong_AsLongAndOverflow(op, &overflow); 00041 return (overflow == 0); 00042 } 00043 00044 #define PyInt_FromLong PyLong_FromLong 00045 #define PyInt_AsLong PyLong_AsLong 00046 #define PyInt_AS_LONG PyLong_AsLong 00047 #define PyInt_AsSsize_t PyLong_AsSsize_t 00048 00049 /* NOTE: 00050 * 00051 * Since the PyLong type is very different from the fixed-range PyInt, 00052 * we don't define PyInt_Type -> PyLong_Type. 00053 */ 00054 #endif /* NPY_PY3K */ 00055 00056 /* 00057 * PyString -> PyBytes 00058 */ 00059 00060 #if defined(NPY_PY3K) 00061 00062 #define PyString_Type PyBytes_Type 00063 #define PyString_Check PyBytes_Check 00064 #define PyStringObject PyBytesObject 00065 #define PyString_FromString PyBytes_FromString 00066 #define PyString_FromStringAndSize PyBytes_FromStringAndSize 00067 #define PyString_AS_STRING PyBytes_AS_STRING 00068 #define PyString_AsStringAndSize PyBytes_AsStringAndSize 00069 #define PyString_FromFormat PyBytes_FromFormat 00070 #define PyString_Concat PyBytes_Concat 00071 #define PyString_ConcatAndDel PyBytes_ConcatAndDel 00072 #define PyString_AsString PyBytes_AsString 00073 #define PyString_GET_SIZE PyBytes_GET_SIZE 00074 #define PyString_Size PyBytes_Size 00075 00076 #define PyUString_Type PyUnicode_Type 00077 #define PyUString_Check PyUnicode_Check 00078 #define PyUStringObject PyUnicodeObject 00079 #define PyUString_FromString PyUnicode_FromString 00080 #define PyUString_FromStringAndSize PyUnicode_FromStringAndSize 00081 #define PyUString_FromFormat PyUnicode_FromFormat 00082 #define PyUString_Concat PyUnicode_Concat2 00083 #define PyUString_ConcatAndDel PyUnicode_ConcatAndDel 00084 #define PyUString_GET_SIZE PyUnicode_GET_SIZE 00085 #define PyUString_Size PyUnicode_Size 00086 #define PyUString_InternFromString PyUnicode_InternFromString 00087 #define PyUString_Format PyUnicode_Format 00088 00089 #else 00090 00091 #define PyBytes_Type PyString_Type 00092 #define PyBytes_Check PyString_Check 00093 #define PyBytesObject PyStringObject 00094 #define PyBytes_FromString PyString_FromString 00095 #define PyBytes_FromStringAndSize PyString_FromStringAndSize 00096 #define PyBytes_AS_STRING PyString_AS_STRING 00097 #define PyBytes_AsStringAndSize PyString_AsStringAndSize 00098 #define PyBytes_FromFormat PyString_FromFormat 00099 #define PyBytes_Concat PyString_Concat 00100 #define PyBytes_ConcatAndDel PyString_ConcatAndDel 00101 #define PyBytes_AsString PyString_AsString 00102 #define PyBytes_GET_SIZE PyString_GET_SIZE 00103 #define PyBytes_Size PyString_Size 00104 00105 #define PyUString_Type PyString_Type 00106 #define PyUString_Check PyString_Check 00107 #define PyUStringObject PyStringObject 00108 #define PyUString_FromString PyString_FromString 00109 #define PyUString_FromStringAndSize PyString_FromStringAndSize 00110 #define PyUString_FromFormat PyString_FromFormat 00111 #define PyUString_Concat PyString_Concat 00112 #define PyUString_ConcatAndDel PyString_ConcatAndDel 00113 #define PyUString_GET_SIZE PyString_GET_SIZE 00114 #define PyUString_Size PyString_Size 00115 #define PyUString_InternFromString PyString_InternFromString 00116 #define PyUString_Format PyString_Format 00117 00118 #endif /* NPY_PY3K */ 00119 00120 00121 static NPY_INLINE void 00122 PyUnicode_ConcatAndDel(PyObject **left, PyObject *right) 00123 { 00124 PyObject *newobj; 00125 newobj = PyUnicode_Concat(*left, right); 00126 Py_DECREF(*left); 00127 Py_DECREF(right); 00128 *left = newobj; 00129 } 00130 00131 static NPY_INLINE void 00132 PyUnicode_Concat2(PyObject **left, PyObject *right) 00133 { 00134 PyObject *newobj; 00135 newobj = PyUnicode_Concat(*left, right); 00136 Py_DECREF(*left); 00137 *left = newobj; 00138 } 00139 00140 00141 /* 00142 * Accessing items of ob_base 00143 */ 00144 00145 #if (PY_VERSION_HEX < 0x02060000) 00146 #define Py_TYPE(o) (((PyObject*)(o))->ob_type) 00147 #define Py_REFCNT(o) (((PyObject*)(o))->ob_refcnt) 00148 #define Py_SIZE(o) (((PyVarObject*)(o))->ob_size) 00149 #endif 00150 00151 /* 00152 * PyFile_* compatibility 00153 */ 00154 #if defined(NPY_PY3K) 00155 00156 /* 00157 * Get a FILE* handle to the file represented by the Python object 00158 */ 00159 static NPY_INLINE FILE* 00160 npy_PyFile_Dup(PyObject *file, char *mode) 00161 { 00162 int fd, fd2; 00163 PyObject *ret, *os; 00164 Py_ssize_t pos; 00165 FILE *handle; 00166 /* Flush first to ensure things end up in the file in the correct order */ 00167 ret = PyObject_CallMethod(file, "flush", ""); 00168 if (ret == NULL) { 00169 return NULL; 00170 } 00171 Py_DECREF(ret); 00172 fd = PyObject_AsFileDescriptor(file); 00173 if (fd == -1) { 00174 return NULL; 00175 } 00176 os = PyImport_ImportModule("os"); 00177 if (os == NULL) { 00178 return NULL; 00179 } 00180 ret = PyObject_CallMethod(os, "dup", "i", fd); 00181 Py_DECREF(os); 00182 if (ret == NULL) { 00183 return NULL; 00184 } 00185 fd2 = PyNumber_AsSsize_t(ret, NULL); 00186 Py_DECREF(ret); 00187 #ifdef _WIN32 00188 handle = _fdopen(fd2, mode); 00189 #else 00190 handle = fdopen(fd2, mode); 00191 #endif 00192 if (handle == NULL) { 00193 PyErr_SetString(PyExc_IOError, 00194 "Getting a FILE* from a Python file object failed"); 00195 } 00196 ret = PyObject_CallMethod(file, "tell", ""); 00197 if (ret == NULL) { 00198 fclose(handle); 00199 return NULL; 00200 } 00201 pos = PyNumber_AsSsize_t(ret, PyExc_OverflowError); 00202 Py_DECREF(ret); 00203 if (PyErr_Occurred()) { 00204 fclose(handle); 00205 return NULL; 00206 } 00207 fseek(handle, pos, SEEK_SET); 00208 return handle; 00209 } 00210 00211 /* 00212 * Close the dup-ed file handle, and seek the Python one to the current position 00213 */ 00214 static NPY_INLINE int 00215 npy_PyFile_DupClose(PyObject *file, FILE* handle) 00216 { 00217 PyObject *ret; 00218 long position; 00219 position = ftell(handle); 00220 fclose(handle); 00221 00222 ret = PyObject_CallMethod(file, "seek", "li", position, 0); 00223 if (ret == NULL) { 00224 return -1; 00225 } 00226 Py_DECREF(ret); 00227 return 0; 00228 } 00229 00230 static NPY_INLINE int 00231 npy_PyFile_Check(PyObject *file) 00232 { 00233 int fd; 00234 fd = PyObject_AsFileDescriptor(file); 00235 if (fd == -1) { 00236 PyErr_Clear(); 00237 return 0; 00238 } 00239 return 1; 00240 } 00241 00242 #else 00243 00244 #define npy_PyFile_Dup(file, mode) PyFile_AsFile(file) 00245 #define npy_PyFile_DupClose(file, handle) (0) 00246 #define npy_PyFile_Check PyFile_Check 00247 00248 #endif 00249 00250 static NPY_INLINE PyObject* 00251 npy_PyFile_OpenFile(PyObject *filename, char *mode) 00252 { 00253 PyObject *open; 00254 open = PyDict_GetItemString(PyEval_GetBuiltins(), "open"); 00255 if (open == NULL) { 00256 return NULL; 00257 } 00258 return PyObject_CallFunction(open, "Os", filename, mode); 00259 } 00260 00261 /* 00262 * PyObject_Cmp 00263 */ 00264 #if defined(NPY_PY3K) 00265 static NPY_INLINE int 00266 PyObject_Cmp(PyObject *i1, PyObject *i2, int *cmp) 00267 { 00268 int v; 00269 v = PyObject_RichCompareBool(i1, i2, Py_LT); 00270 if (v == 0) { 00271 *cmp = -1; 00272 return 1; 00273 } 00274 else if (v == -1) { 00275 return -1; 00276 } 00277 00278 v = PyObject_RichCompareBool(i1, i2, Py_GT); 00279 if (v == 0) { 00280 *cmp = 1; 00281 return 1; 00282 } 00283 else if (v == -1) { 00284 return -1; 00285 } 00286 00287 v = PyObject_RichCompareBool(i1, i2, Py_EQ); 00288 if (v == 0) { 00289 *cmp = 0; 00290 return 1; 00291 } 00292 else { 00293 *cmp = 0; 00294 return -1; 00295 } 00296 } 00297 #endif 00298 00299 /* 00300 * PyCObject functions adapted to PyCapsules. 00301 * 00302 * The main job here is to get rid of the improved error handling 00303 * of PyCapsules. It's a shame... 00304 */ 00305 #if PY_VERSION_HEX >= 0x03000000 00306 00307 static NPY_INLINE PyObject * 00308 NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *)) 00309 { 00310 PyObject *ret = PyCapsule_New(ptr, NULL, dtor); 00311 if (ret == NULL) { 00312 PyErr_Clear(); 00313 } 00314 return ret; 00315 } 00316 00317 static NPY_INLINE PyObject * 00318 NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context, void (*dtor)(PyObject *)) 00319 { 00320 PyObject *ret = NpyCapsule_FromVoidPtr(ptr, dtor); 00321 if (ret != NULL && PyCapsule_SetContext(ret, context) != 0) { 00322 PyErr_Clear(); 00323 Py_DECREF(ret); 00324 ret = NULL; 00325 } 00326 return ret; 00327 } 00328 00329 static NPY_INLINE void * 00330 NpyCapsule_AsVoidPtr(PyObject *obj) 00331 { 00332 void *ret = PyCapsule_GetPointer(obj, NULL); 00333 if (ret == NULL) { 00334 PyErr_Clear(); 00335 } 00336 return ret; 00337 } 00338 00339 static NPY_INLINE void * 00340 NpyCapsule_GetDesc(PyObject *obj) 00341 { 00342 return PyCapsule_GetContext(obj); 00343 } 00344 00345 static NPY_INLINE int 00346 NpyCapsule_Check(PyObject *ptr) 00347 { 00348 return PyCapsule_CheckExact(ptr); 00349 } 00350 00351 static NPY_INLINE void 00352 simple_capsule_dtor(PyObject *cap) 00353 { 00354 PyArray_free(PyCapsule_GetPointer(cap, NULL)); 00355 } 00356 00357 #else 00358 00359 static NPY_INLINE PyObject * 00360 NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *)) 00361 { 00362 return PyCObject_FromVoidPtr(ptr, dtor); 00363 } 00364 00365 static NPY_INLINE PyObject * 00366 NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context, 00367 void (*dtor)(void *, void *)) 00368 { 00369 return PyCObject_FromVoidPtrAndDesc(ptr, context, dtor); 00370 } 00371 00372 static NPY_INLINE void * 00373 NpyCapsule_AsVoidPtr(PyObject *ptr) 00374 { 00375 return PyCObject_AsVoidPtr(ptr); 00376 } 00377 00378 static NPY_INLINE void * 00379 NpyCapsule_GetDesc(PyObject *obj) 00380 { 00381 return PyCObject_GetDesc(obj); 00382 } 00383 00384 static NPY_INLINE int 00385 NpyCapsule_Check(PyObject *ptr) 00386 { 00387 return PyCObject_Check(ptr); 00388 } 00389 00390 static NPY_INLINE void 00391 simple_capsule_dtor(void *ptr) 00392 { 00393 PyArray_free(ptr); 00394 } 00395 00396 #endif 00397 00398 #ifdef __cplusplus 00399 } 00400 #endif 00401 00402 #endif /* _NPY_3KCOMPAT_H_ */