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 1 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 * PyFile_* compatibility 00142 */ 00143 #if defined(NPY_PY3K) 00144 00145 /* 00146 * Get a FILE* handle to the file represented by the Python object 00147 */ 00148 static NPY_INLINE FILE* 00149 npy_PyFile_Dup(PyObject *file, char *mode) 00150 { 00151 int fd, fd2; 00152 PyObject *ret, *os; 00153 Py_ssize_t pos; 00154 FILE *handle; 00155 /* Flush first to ensure things end up in the file in the correct order */ 00156 ret = PyObject_CallMethod(file, "flush", ""); 00157 if (ret == NULL) { 00158 return NULL; 00159 } 00160 Py_DECREF(ret); 00161 fd = PyObject_AsFileDescriptor(file); 00162 if (fd == -1) { 00163 return NULL; 00164 } 00165 os = PyImport_ImportModule("os"); 00166 if (os == NULL) { 00167 return NULL; 00168 } 00169 ret = PyObject_CallMethod(os, "dup", "i", fd); 00170 Py_DECREF(os); 00171 if (ret == NULL) { 00172 return NULL; 00173 } 00174 fd2 = PyNumber_AsSsize_t(ret, NULL); 00175 Py_DECREF(ret); 00176 #ifdef _WIN32 00177 handle = _fdopen(fd2, mode); 00178 #else 00179 handle = fdopen(fd2, mode); 00180 #endif 00181 if (handle == NULL) { 00182 PyErr_SetString(PyExc_IOError, 00183 "Getting a FILE* from a Python file object failed"); 00184 } 00185 ret = PyObject_CallMethod(file, "tell", ""); 00186 if (ret == NULL) { 00187 fclose(handle); 00188 return NULL; 00189 } 00190 pos = PyNumber_AsSsize_t(ret, PyExc_OverflowError); 00191 Py_DECREF(ret); 00192 if (PyErr_Occurred()) { 00193 fclose(handle); 00194 return NULL; 00195 } 00196 npy_fseek(handle, pos, SEEK_SET); 00197 return handle; 00198 } 00199 00200 /* 00201 * Close the dup-ed file handle, and seek the Python one to the current position 00202 */ 00203 static NPY_INLINE int 00204 npy_PyFile_DupClose(PyObject *file, FILE* handle) 00205 { 00206 PyObject *ret; 00207 Py_ssize_t position; 00208 position = npy_ftell(handle); 00209 fclose(handle); 00210 00211 ret = PyObject_CallMethod(file, "seek", NPY_SSIZE_T_PYFMT "i", position, 0); 00212 if (ret == NULL) { 00213 return -1; 00214 } 00215 Py_DECREF(ret); 00216 return 0; 00217 } 00218 00219 static NPY_INLINE int 00220 npy_PyFile_Check(PyObject *file) 00221 { 00222 int fd; 00223 fd = PyObject_AsFileDescriptor(file); 00224 if (fd == -1) { 00225 PyErr_Clear(); 00226 return 0; 00227 } 00228 return 1; 00229 } 00230 00231 #else 00232 00233 #define npy_PyFile_Dup(file, mode) PyFile_AsFile(file) 00234 #define npy_PyFile_DupClose(file, handle) (0) 00235 #define npy_PyFile_Check PyFile_Check 00236 00237 #endif 00238 00239 static NPY_INLINE PyObject* 00240 npy_PyFile_OpenFile(PyObject *filename, const char *mode) 00241 { 00242 PyObject *open; 00243 open = PyDict_GetItemString(PyEval_GetBuiltins(), "open"); 00244 if (open == NULL) { 00245 return NULL; 00246 } 00247 return PyObject_CallFunction(open, "Os", filename, mode); 00248 } 00249 00250 static NPY_INLINE int 00251 npy_PyFile_CloseFile(PyObject *file) 00252 { 00253 PyObject *ret; 00254 00255 ret = PyObject_CallMethod(file, "close", NULL); 00256 if (ret == NULL) { 00257 return -1; 00258 } 00259 Py_DECREF(ret); 00260 return 0; 00261 } 00262 00263 /* 00264 * PyObject_Cmp 00265 */ 00266 #if defined(NPY_PY3K) 00267 static NPY_INLINE int 00268 PyObject_Cmp(PyObject *i1, PyObject *i2, int *cmp) 00269 { 00270 int v; 00271 v = PyObject_RichCompareBool(i1, i2, Py_LT); 00272 if (v == 0) { 00273 *cmp = -1; 00274 return 1; 00275 } 00276 else if (v == -1) { 00277 return -1; 00278 } 00279 00280 v = PyObject_RichCompareBool(i1, i2, Py_GT); 00281 if (v == 0) { 00282 *cmp = 1; 00283 return 1; 00284 } 00285 else if (v == -1) { 00286 return -1; 00287 } 00288 00289 v = PyObject_RichCompareBool(i1, i2, Py_EQ); 00290 if (v == 0) { 00291 *cmp = 0; 00292 return 1; 00293 } 00294 else { 00295 *cmp = 0; 00296 return -1; 00297 } 00298 } 00299 #endif 00300 00301 /* 00302 * PyCObject functions adapted to PyCapsules. 00303 * 00304 * The main job here is to get rid of the improved error handling 00305 * of PyCapsules. It's a shame... 00306 */ 00307 #if PY_VERSION_HEX >= 0x03000000 00308 00309 static NPY_INLINE PyObject * 00310 NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *)) 00311 { 00312 PyObject *ret = PyCapsule_New(ptr, NULL, dtor); 00313 if (ret == NULL) { 00314 PyErr_Clear(); 00315 } 00316 return ret; 00317 } 00318 00319 static NPY_INLINE PyObject * 00320 NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context, void (*dtor)(PyObject *)) 00321 { 00322 PyObject *ret = NpyCapsule_FromVoidPtr(ptr, dtor); 00323 if (ret != NULL && PyCapsule_SetContext(ret, context) != 0) { 00324 PyErr_Clear(); 00325 Py_DECREF(ret); 00326 ret = NULL; 00327 } 00328 return ret; 00329 } 00330 00331 static NPY_INLINE void * 00332 NpyCapsule_AsVoidPtr(PyObject *obj) 00333 { 00334 void *ret = PyCapsule_GetPointer(obj, NULL); 00335 if (ret == NULL) { 00336 PyErr_Clear(); 00337 } 00338 return ret; 00339 } 00340 00341 static NPY_INLINE void * 00342 NpyCapsule_GetDesc(PyObject *obj) 00343 { 00344 return PyCapsule_GetContext(obj); 00345 } 00346 00347 static NPY_INLINE int 00348 NpyCapsule_Check(PyObject *ptr) 00349 { 00350 return PyCapsule_CheckExact(ptr); 00351 } 00352 00353 static NPY_INLINE void 00354 simple_capsule_dtor(PyObject *cap) 00355 { 00356 PyArray_free(PyCapsule_GetPointer(cap, NULL)); 00357 } 00358 00359 #else 00360 00361 static NPY_INLINE PyObject * 00362 NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *)) 00363 { 00364 return PyCObject_FromVoidPtr(ptr, dtor); 00365 } 00366 00367 static NPY_INLINE PyObject * 00368 NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context, 00369 void (*dtor)(void *, void *)) 00370 { 00371 return PyCObject_FromVoidPtrAndDesc(ptr, context, dtor); 00372 } 00373 00374 static NPY_INLINE void * 00375 NpyCapsule_AsVoidPtr(PyObject *ptr) 00376 { 00377 return PyCObject_AsVoidPtr(ptr); 00378 } 00379 00380 static NPY_INLINE void * 00381 NpyCapsule_GetDesc(PyObject *obj) 00382 { 00383 return PyCObject_GetDesc(obj); 00384 } 00385 00386 static NPY_INLINE int 00387 NpyCapsule_Check(PyObject *ptr) 00388 { 00389 return PyCObject_Check(ptr); 00390 } 00391 00392 static NPY_INLINE void 00393 simple_capsule_dtor(void *ptr) 00394 { 00395 PyArray_free(ptr); 00396 } 00397 00398 #endif 00399 00400 #ifdef __cplusplus 00401 } 00402 #endif 00403 00404 #endif /* _NPY_3KCOMPAT_H_ */