//----------------------------------------------------------------------------- // cxBuffer_FromObject() // Populate the string buffer from a unicode object. //----------------------------------------------------------------------------- static int cxBuffer_FromObject( udt_Buffer *buf, // buffer to fill PyObject *obj, // object (string or Unicode object) const char *encoding) // encoding to use, if applicable { if (!obj) return cxBuffer_Init(buf); if (encoding && PyUnicode_Check(obj)) { buf->obj = PyUnicode_AsEncodedString(obj, encoding, NULL); if (!buf->obj) return -1; buf->ptr = PyBytes_AS_STRING(buf->obj); buf->size = PyBytes_GET_SIZE(buf->obj); buf->numCharacters = PyUnicode_GET_SIZE(obj); } else if (PyBytes_Check(obj)) { Py_INCREF(obj); buf->obj = obj; buf->ptr = PyBytes_AS_STRING(buf->obj); buf->size = buf->numCharacters = PyBytes_GET_SIZE(buf->obj); #if PY_MAJOR_VERSION < 3 } else if (PyBuffer_Check(obj)) { if (PyObject_AsReadBuffer(obj, &buf->ptr, &buf->size) < 0) return -1; Py_INCREF(obj); buf->obj = obj; buf->numCharacters = buf->size; #endif } else { PyErr_SetString(PyExc_TypeError, CXORA_TYPE_ERROR); return -1; } return 0; }
/*NUMPY_API * Get buffer chunk from object * * this function takes a Python object which exposes the (single-segment) * buffer interface and returns a pointer to the data segment * * You should increment the reference count by one of buf->base * if you will hang on to a reference * * You only get a borrowed reference to the object. Do not free the * memory... */ NPY_NO_EXPORT int PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf) { Py_ssize_t buflen; buf->ptr = NULL; buf->flags = BEHAVED; buf->base = NULL; if (obj == Py_None) { return PY_SUCCEED; } if (PyObject_AsWriteBuffer(obj, &(buf->ptr), &buflen) < 0) { PyErr_Clear(); buf->flags &= ~WRITEABLE; if (PyObject_AsReadBuffer(obj, (const void **)&(buf->ptr), &buflen) < 0) { return PY_FAIL; } } buf->len = (intp) buflen; /* Point to the base of the buffer object if present */ if (PyBuffer_Check(obj)) { buf->base = ((PyArray_Chunk *)obj)->base; } if (buf->base == NULL) { buf->base = obj; } return PY_SUCCEED; }
/*NUMPY_API * Get buffer chunk from object * * this function takes a Python object which exposes the (single-segment) * buffer interface and returns a pointer to the data segment * * You should increment the reference count by one of buf->base * if you will hang on to a reference * * You only get a borrowed reference to the object. Do not free the * memory... */ NPY_NO_EXPORT int PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf) { #if defined(NPY_PY3K) Py_buffer view; #else Py_ssize_t buflen; #endif buf->ptr = NULL; buf->flags = NPY_ARRAY_BEHAVED; buf->base = NULL; if (obj == Py_None) { return NPY_SUCCEED; } #if defined(NPY_PY3K) if (PyObject_GetBuffer(obj, &view, PyBUF_ANY_CONTIGUOUS|PyBUF_WRITABLE) != 0) { PyErr_Clear(); buf->flags &= ~NPY_ARRAY_WRITEABLE; if (PyObject_GetBuffer(obj, &view, PyBUF_ANY_CONTIGUOUS) != 0) { return NPY_FAIL; } } buf->ptr = view.buf; buf->len = (npy_intp) view.len; /* * XXX: PyObject_AsWriteBuffer does also this, but it is unsafe, as there is * no strict guarantee that the buffer sticks around after being released. */ PyBuffer_Release(&view); /* Point to the base of the buffer object if present */ if (PyMemoryView_Check(obj)) { buf->base = PyMemoryView_GET_BASE(obj); } #else if (PyObject_AsWriteBuffer(obj, &(buf->ptr), &buflen) < 0) { PyErr_Clear(); buf->flags &= ~NPY_ARRAY_WRITEABLE; if (PyObject_AsReadBuffer(obj, (const void **)&(buf->ptr), &buflen) < 0) { return NPY_FAIL; } } buf->len = (npy_intp) buflen; /* Point to the base of the buffer object if present */ if (PyBuffer_Check(obj)) { buf->base = ((PyArray_Chunk *)obj)->base; } #endif if (buf->base == NULL) { buf->base = obj; } return NPY_SUCCEED; }
Py_ssize_t PyBuffer_Size(PyObject* self) { if (!PyBuffer_Check(self)) { PyErr_SetString(PyExc_TypeError, "Not a buffer!"); return 0; } Py_ssize_t total_len = 0; self->ob_type->tp_as_buffer->bf_getsegcount(self, &total_len); return total_len; }
//Free the buffer given by grab_image //Expects free_image(handle, buffer) //Returns 0 for success static PyObject *free_image(PyObject *self, PyObject *args){ PyObject *obj, *buffer; int dev; struct image_cap *image_struct; //Get the buffer object from the arguments if (!PyArg_ParseTuple(args, "iO", &dev, &obj)){ PyErr_SetString(PyExc_TypeError, "Invalid arguments to free_image"); return NULL; } //Make sure it's a valid buffer object if (!PyBuffer_Check(obj)){ PyErr_SetString(PyExc_TypeError, "Invalid argument: not a PyBuffer"); return NULL; } //Convert the object to a buffer object buffer = PyBuffer_FromObject(obj, 0, Py_END_OF_BUFFER); //This shouldn't be an error if the object passes the previous check if (buffer->ob_type->tp_as_buffer->bf_getreadbuffer == NULL){ PyErr_SetString(PyExc_TypeError, "Invalid argument: not a readable PyBuffer"); return NULL; } //Create an image_cap structure image_struct = malloc(sizeof(struct image_cap)); //This call puts the size of PyBuffer object into image_struct.size //and sets the image_struct->data pointer to the beginning of the //PyBuffer's buffer image_struct->size = (int)(buffer->ob_type->tp_as_buffer->bf_getreadbuffer)\ (buffer, 0, &(image_struct->data)); image_struct->handle = dev; if (Cfree_image(image_struct)){ free(image_struct); PyErr_SetString(PyExc_IOError, "Error in C function call"); return NULL; } return PyInt_FromLong(0L); }
// @pymethod <o Py_nsIID>|xpcom|IID|Creates a new IID object PYXPCOM_EXPORT PyObject *PyXPCOMMethod_IID(PyObject *self, PyObject *args) { PyObject *obIID; PyObject *obBuf; if ( PyArg_ParseTuple(args, "O", &obBuf)) { if (PyBuffer_Check(obBuf)) { PyBufferProcs *pb = NULL; pb = obBuf->ob_type->tp_as_buffer; void *buf = NULL; int size = (*pb->bf_getreadbuffer)(obBuf, 0, &buf); if (size != sizeof(nsIID) || buf==NULL) { #ifdef VBOX PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %d bytes long", (int)sizeof(nsIID)); #else PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %d bytes long", sizeof(nsIID)); #endif return NULL; } nsIID iid; unsigned char *ptr = (unsigned char *)buf; iid.m0 = XPT_SWAB32(*((PRUint32 *)ptr)); ptr = ((unsigned char *)buf) + offsetof(nsIID, m1); iid.m1 = XPT_SWAB16(*((PRUint16 *)ptr)); ptr = ((unsigned char *)buf) + offsetof(nsIID, m2); iid.m2 = XPT_SWAB16(*((PRUint16 *)ptr)); ptr = ((unsigned char *)buf) + offsetof(nsIID, m3); for (int i=0;i<8;i++) { iid.m3[i] = *((PRUint8 *)ptr); ptr += sizeof(PRUint8); } return new Py_nsIID(iid); } } PyErr_Clear(); // @pyparm string/Unicode|iidString||A string representation of an IID, or a ContractID. if ( !PyArg_ParseTuple(args, "O", &obIID) ) return NULL; nsIID iid; if (!Py_nsIID::IIDFromPyObject(obIID, &iid)) return NULL; return new Py_nsIID(iid); }
static PyObject * _PyBuffer_FromObject(PyObject *base, int offset, int size, getreadbufferproc proc, int readonly) { PyBufferProcs *pb = base->ob_type->tp_as_buffer; void *p; int count; if ( offset < 0 ) { PyErr_SetString(PyExc_ValueError, "offset must be zero or positive"); return NULL; } if ( (*pb->bf_getsegcount)(base, NULL) != 1 ) { PyErr_SetString(PyExc_TypeError, "single-segment buffer object expected"); return NULL; } if ( (count = (*proc)(base, 0, &p)) < 0 ) return NULL; /* apply constraints to the start/end */ if ( size == Py_END_OF_BUFFER || size < 0 ) size = count; if ( offset > count ) offset = count; if ( offset + size > count ) size = count - offset; /* if the base object is another buffer, then "deref" it, * except if the base of the other buffer is NULL */ if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) base = ((PyBufferObject *)base)->b_base; return _PyBuffer_FromMemory(base, (char *)p + offset, size, readonly); }
static PyObject * buffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly) { if (offset < 0) { PyErr_SetString(PyExc_ValueError, "offset must be zero or positive"); return NULL; } if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) { /* another buffer, refer to the base object */ PyBufferObject *b = (PyBufferObject *)base; if (b->b_size != Py_END_OF_BUFFER) { Py_ssize_t base_size = b->b_size - offset; if (base_size < 0) base_size = 0; if (size == Py_END_OF_BUFFER || size > base_size) size = base_size; } offset += b->b_offset; base = b->b_base; } return buffer_from_memory(base, size, offset, NULL, readonly); }
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter) { int rc = SQLITE_OK; long longval; #ifdef HAVE_LONG_LONG PY_LONG_LONG longlongval; #endif const char* buffer; char* string; Py_ssize_t buflen; PyObject* stringval; if (parameter == Py_None) { rc = sqlite3_bind_null(self->st, pos); } else if (PyInt_Check(parameter)) { longval = PyInt_AsLong(parameter); rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longval); #ifdef HAVE_LONG_LONG } else if (PyLong_Check(parameter)) { longlongval = PyLong_AsLongLong(parameter); /* in the overflow error case, longlongval is -1, and an exception is set */ rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longlongval); #endif } else if (PyFloat_Check(parameter)) { rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter)); } else if (PyBuffer_Check(parameter)) { if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) == 0) { rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT); } else { PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); rc = -1; } } else if PyString_Check(parameter) { string = PyString_AsString(parameter); rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT); } else if PyUnicode_Check(parameter) {
/*NUMPY_API * Get buffer chunk from object * * this function takes a Python object which exposes the (single-segment) * buffer interface and returns a pointer to the data segment * * You should increment the reference count by one of buf->base * if you will hang on to a reference * * You only get a borrowed reference to the object. Do not free the * memory... */ NPY_NO_EXPORT int PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf) { Py_ssize_t buflen; buf->ptr = NULL; buf->flags = NPY_ARRAY_BEHAVED; buf->base = NULL; if (obj == Py_None) { return NPY_SUCCEED; } if (PyObject_AsWriteBuffer(obj, &(buf->ptr), &buflen) < 0) { PyErr_Clear(); buf->flags &= ~NPY_ARRAY_WRITEABLE; if (PyObject_AsReadBuffer(obj, (const void **)&(buf->ptr), &buflen) < 0) { return NPY_FAIL; } } buf->len = (npy_intp) buflen; /* Point to the base of the buffer object if present */ #if defined(NPY_PY3K) if (PyMemoryView_Check(obj)) { buf->base = PyMemoryView_GET_BASE(obj); } #else if (PyBuffer_Check(obj)) { buf->base = ((PyArray_Chunk *)obj)->base; } #endif if (buf->base == NULL) { buf->base = obj; } return NPY_SUCCEED; }
static PyObject * binary_quote(binaryObject *self) { char *to = NULL; const char *buffer = NULL; Py_ssize_t buffer_len; size_t len = 0; PyObject *rv = NULL; #if HAS_MEMORYVIEW Py_buffer view; int got_view = 0; #endif /* if we got a plain string or a buffer we escape it and save the buffer */ #if HAS_MEMORYVIEW if (PyObject_CheckBuffer(self->wrapped)) { if (0 > PyObject_GetBuffer(self->wrapped, &view, PyBUF_CONTIG_RO)) { goto exit; } got_view = 1; buffer = (const char *)(view.buf); buffer_len = view.len; } #endif #if HAS_BUFFER if (!buffer && (Bytes_Check(self->wrapped) || PyBuffer_Check(self->wrapped))) { if (PyObject_AsReadBuffer(self->wrapped, (const void **)&buffer, &buffer_len) < 0) { goto exit; } } #endif if (!buffer) { goto exit; } /* escape and build quoted buffer */ to = (char *)binary_escape((unsigned char*)buffer, (size_t) buffer_len, &len, self->conn ? ((connectionObject*)self->conn)->pgconn : NULL); if (to == NULL) { PyErr_NoMemory(); goto exit; } if (len > 0) rv = Bytes_FromFormat( (self->conn && ((connectionObject*)self->conn)->equote) ? "E'%s'::bytea" : "'%s'::bytea" , to); else rv = Bytes_FromString("''::bytea"); exit: if (to) { PQfreemem(to); } #if HAS_MEMORYVIEW if (got_view) { PyBuffer_Release(&view); } #endif /* Allow Binary(None) to work */ if (self->wrapped == Py_None) { Py_INCREF(psyco_null); rv = psyco_null; } /* if the wrapped object is not bytes or a buffer, this is an error */ if (!rv && !PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "can't escape %s to binary", Py_TYPE(self->wrapped)->tp_name); } return rv; }
static bool GetParameterInfo(Cursor* cur, Py_ssize_t index, PyObject* param, ParamInfo& info) { // Determines the type of SQL parameter that will be used for this parameter based on the Python data type. // // Populates `info`. // TODO: if the param is a SQLParameter object, then bind to the wrapped value and use the input/output type from that // Hold a reference to param until info is freed, because info will often be holding data borrowed from param. if (PyObject_TypeCheck(param, (PyTypeObject*)SQLParameter_type)) { info.pParam = ((SQLParameter*)param)->value; info.InputOutputType = ((SQLParameter*)param)->type; } else { info.pParam = param; info.InputOutputType = SQL_PARAM_INPUT; } if (info.pParam == Py_None) return GetNullInfo(cur, index, info); if (info.pParam == null_binary) return GetNullBinaryInfo(cur, index, info); if (PyBytes_Check(info.pParam)) return GetBytesInfo(cur, index, info.pParam, info); if (PyUnicode_Check(info.pParam)) return GetUnicodeInfo(cur, index, info.pParam, info); if (PyBool_Check(info.pParam)) return GetBooleanInfo(cur, index, info.pParam, info); if (PyDateTime_Check(info.pParam)) return GetDateTimeInfo(cur, index, info.pParam, info); if (PyDate_Check(info.pParam)) return GetDateInfo(cur, index, info.pParam, info); if (PyTime_Check(info.pParam)) return GetTimeInfo(cur, index, info.pParam, info); if (PyLong_Check(info.pParam)) return GetLongInfo(cur, index, info.pParam, info); if (PyFloat_Check(info.pParam)) return GetFloatInfo(cur, index, info.pParam, info); if (PyDecimal_Check(info.pParam)) return GetDecimalInfo(cur, index, info.pParam, info); #if PY_VERSION_HEX >= 0x02060000 if (PyByteArray_Check(info.pParam)) return GetByteArrayInfo(cur, index, info.pParam, info); #endif #if PY_MAJOR_VERSION < 3 if (PyInt_Check(info.pParam)) return GetIntInfo(cur, index, info.pParam, info); if (PyBuffer_Check(info.pParam)) return GetBufferInfo(cur, index, info.pParam, info); #endif RaiseErrorV("HY105", ProgrammingError, "Invalid parameter type. param-index=%zd param-type=%s", index, Py_TYPE(info.pParam)->tp_name); return false; }
/* @returns tuple of a python string and an ending index into its string parameter */ static PyObject *decode_raw_string(PyObject *self, PyObject *args) { PyObject *dataobj = NULL; int dataptrlen; int index, strlength, dataend; char *dataptr, *digitptr, *colonptr; PyObject *excval; /*printf("args = %p\n", args);*/ if (!PyArg_ParseTuple(args, "Oi:decode_raw_string", &dataobj, &index)) { excval = Py_BuildValue("(is)", 0, "expected a string and an integer as parameters"); if (excval != NULL) { PyErr_SetObject(PyExc_ValueError, excval); Py_DECREF(excval); } return NULL; } /*printf("dataobj = %p, index = %d\n", dataobj, index);*/ if (index < 0) { excval = Py_BuildValue("(is)", 0, "index must be a non-negative integer"); if (excval != NULL) { PyErr_SetObject(PyExc_ValueError, excval); Py_DECREF(excval); } return NULL; } if (PyString_Check(dataobj)) { /*PyString_AsStringAndSize(dataobj, &dataptr, &dataptrlen); */ /* python 1.5.2 doesn't have this function */ dataptrlen = PyString_Size(dataobj); dataptr = PyString_AsString(dataobj); if (!dataptr) { excval = Py_BuildValue("(is)", 0, "first parameter was not a python object?"); if (excval != NULL) { PyErr_SetObject(PyExc_TypeError, excval); Py_DECREF(excval); } return NULL; } if (index > dataptrlen) { excval = Py_BuildValue("(is)", 0, "index is greater than the string length"); if (excval != NULL) { PyErr_SetObject(PyExc_ValueError, excval); Py_DECREF(excval); } return NULL; } dataptr = dataptr + index; dataptrlen = dataptrlen - index; } else if (PyBuffer_Check(dataobj)) { /* TODO accept buffer objects */ excval = Py_BuildValue("(is)", 0, "Buffer objects are not yet supported"); if (excval != NULL) { PyErr_SetObject(PyExc_TypeError, excval); Py_DECREF(excval); } return NULL; } else { excval = Py_BuildValue("(is)", 0, "parameter must be a python String object"); if (excval != NULL) { PyErr_SetObject(PyExc_TypeError, excval); Py_DECREF(excval); } return NULL; } /*printf("dataptr = %p, dataptrlen = %d\n", dataptr, dataptrlen);*/ /*printf("*dataptr = %s\n", dataptr);*/ colonptr = strchr(dataptr, ':'); if (!colonptr || (colonptr > dataptr + dataptrlen)) { excval = Py_BuildValue("(is)", 0, "bad string length"); if (excval != NULL) { PyErr_SetObject(MencodeError, excval); Py_DECREF(excval); } return NULL; } /* we don't use atoi() because it doesn't check for bad characters. (does strtol?) */ strlength = 0; digitptr = dataptr; while (digitptr < colonptr) { char digit = *digitptr; if ((digit < '0') || (digit > '9')) { excval = Py_BuildValue("(is)", 0, "length contained non-digit character"); if (excval != NULL) { PyErr_SetObject(MencodeError, excval); Py_DECREF(excval); } return NULL; } strlength = (10*strlength) + (digit - '0'); digitptr++; } if ((strlength != 0) && (*dataptr == '0')) { excval = Py_BuildValue("(is)", 0, "positive string length must not begin with `0'"); if (excval != NULL) { PyErr_SetObject(MencodeError, excval); Py_DECREF(excval); } return NULL; } dataend = colonptr + 1 + strlength - dataptr; if (dataend > dataptrlen) { excval = Py_BuildValue("(is)", 0, "unexpected end of string"); if (excval != NULL) { PyErr_SetObject(MencodeError, excval); Py_DECREF(excval); } return NULL; } /* TODO return a buffer object instead of a string if strlength is over a determined threshold (40 chars or so?) */ return Py_BuildValue("s#i", colonptr+1, strlength, dataend + index); }
NPY_NO_EXPORT int PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims, PyArray_Descr **out_dtype, int string_type) { int i, size; PyArray_Descr *dtype = NULL; PyObject *ip; Py_buffer buffer_view; /* Check if it's an ndarray */ if (PyArray_Check(obj)) { dtype = PyArray_DESCR((PyArrayObject *)obj); Py_INCREF(dtype); goto promote_types; } /* See if it's a python None */ if (obj == Py_None) { dtype = PyArray_DescrFromType(NPY_OBJECT); if (dtype == NULL) { goto fail; } Py_INCREF(dtype); goto promote_types; } /* Check if it's a NumPy scalar */ else if (PyArray_IsScalar(obj, Generic)) { if (!string_type) { dtype = PyArray_DescrFromScalar(obj); if (dtype == NULL) { goto fail; } } else { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's a Python scalar */ dtype = _array_find_python_scalar_type(obj); if (dtype != NULL) { if (string_type) { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's an ASCII string */ if (PyBytes_Check(obj)) { int itemsize = PyString_GET_SIZE(obj); /* If it's already a big enough string, don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_STRING && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_STRING); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* Check if it's a Unicode string */ if (PyUnicode_Check(obj)) { int itemsize = PyUnicode_GET_DATA_SIZE(obj); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif /* * If it's already a big enough unicode object, * don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_UNICODE && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_UNICODE); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* PEP 3118 buffer interface */ if (PyObject_CheckBuffer(obj) == 1) { memset(&buffer_view, 0, sizeof(Py_buffer)); if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT|PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT) == 0) { PyErr_Clear(); dtype = _descriptor_from_pep3118_format(buffer_view.format); PyBuffer_Release(&buffer_view); if (dtype) { goto promote_types; } } else if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_SIMPLE) == 0) { PyErr_Clear(); dtype = PyArray_DescrNewFromType(NPY_VOID); dtype->elsize = buffer_view.itemsize; PyBuffer_Release(&buffer_view); goto promote_types; } else { PyErr_Clear(); } } /* The array interface */ ip = PyArray_GetAttrString_SuppressException(obj, "__array_interface__"); if (ip != NULL) { if (PyDict_Check(ip)) { PyObject *typestr; #if defined(NPY_PY3K) PyObject *tmp = NULL; #endif typestr = PyDict_GetItemString(ip, "typestr"); #if defined(NPY_PY3K) /* Allow unicode type strings */ if (PyUnicode_Check(typestr)) { tmp = PyUnicode_AsASCIIString(typestr); typestr = tmp; } #endif if (typestr && PyBytes_Check(typestr)) { dtype =_array_typedescr_fromstr(PyBytes_AS_STRING(typestr)); #if defined(NPY_PY3K) if (tmp == typestr) { Py_DECREF(tmp); } #endif Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } /* The array struct interface */ ip = PyArray_GetAttrString_SuppressException(obj, "__array_struct__"); if (ip != NULL) { PyArrayInterface *inter; char buf[40]; if (NpyCapsule_Check(ip)) { inter = (PyArrayInterface *)NpyCapsule_AsVoidPtr(ip); if (inter->two == 2) { PyOS_snprintf(buf, sizeof(buf), "|%c%d", inter->typekind, inter->itemsize); dtype = _array_typedescr_fromstr(buf); Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } /* The old buffer interface */ #if !defined(NPY_PY3K) if (PyBuffer_Check(obj)) { dtype = PyArray_DescrNewFromType(NPY_VOID); if (dtype == NULL) { goto fail; } dtype->elsize = Py_TYPE(obj)->tp_as_sequence->sq_length(obj); PyErr_Clear(); goto promote_types; } #endif /* The __array__ attribute */ ip = PyArray_GetAttrString_SuppressException(obj, "__array__"); if (ip != NULL) { Py_DECREF(ip); ip = PyObject_CallMethod(obj, "__array__", NULL); if(ip && PyArray_Check(ip)) { dtype = PyArray_DESCR((PyArrayObject *)ip); Py_INCREF(dtype); Py_DECREF(ip); goto promote_types; } Py_XDECREF(ip); if (PyErr_Occurred()) { goto fail; } } /* Not exactly sure what this is about... */ #if !defined(NPY_PY3K) if (PyInstance_Check(obj)) { dtype = _use_default_type(obj); if (dtype == NULL) { goto fail; } else { goto promote_types; } } #endif /* * If we reached the maximum recursion depth without hitting one * of the above cases, the output dtype should be OBJECT */ if (maxdims == 0 || !PySequence_Check(obj)) { if (*out_dtype == NULL || (*out_dtype)->type_num != NPY_OBJECT) { Py_XDECREF(*out_dtype); *out_dtype = PyArray_DescrFromType(NPY_OBJECT); if (*out_dtype == NULL) { return -1; } } return 0; } /* Recursive case */ size = PySequence_Size(obj); if (size < 0) { goto fail; } /* Recursive call for each sequence item */ for (i = 0; i < size; ++i) { int res; ip = PySequence_GetItem(obj, i); if (ip == NULL) { goto fail; } res = PyArray_DTypeFromObjectHelper(ip, maxdims - 1, out_dtype, string_type); if (res < 0) { Py_DECREF(ip); goto fail; } else if (res > 0) { Py_DECREF(ip); return res; } Py_DECREF(ip); } return 0; promote_types: /* Set 'out_dtype' if it's NULL */ if (*out_dtype == NULL) { if (!string_type && dtype->type_num == NPY_STRING) { Py_DECREF(dtype); return RETRY_WITH_STRING; } if (!string_type && dtype->type_num == NPY_UNICODE) { Py_DECREF(dtype); return RETRY_WITH_UNICODE; } *out_dtype = dtype; return 0; } /* Do type promotion with 'out_dtype' */ else { PyArray_Descr *res_dtype = PyArray_PromoteTypes(dtype, *out_dtype); Py_DECREF(dtype); if (res_dtype == NULL) { return -1; } if (!string_type && res_dtype->type_num == NPY_UNICODE && (*out_dtype)->type_num != NPY_UNICODE) { Py_DECREF(res_dtype); return RETRY_WITH_UNICODE; } if (!string_type && res_dtype->type_num == NPY_STRING && (*out_dtype)->type_num != NPY_STRING) { Py_DECREF(res_dtype); return RETRY_WITH_STRING; } Py_DECREF(*out_dtype); *out_dtype = res_dtype; return 0; } fail: Py_XDECREF(*out_dtype); *out_dtype = NULL; return -1; } #undef RETRY_WITH_STRING #undef RETRY_WITH_UNICODE /* new reference */ NPY_NO_EXPORT PyArray_Descr * _array_typedescr_fromstr(char *c_str) { PyArray_Descr *descr = NULL; PyObject *stringobj = PyString_FromString(c_str); if (stringobj == NULL) { return NULL; } if (PyArray_DescrConverter(stringobj, &descr) != NPY_SUCCEED) { Py_DECREF(stringobj); return NULL; } Py_DECREF(stringobj); return descr; } NPY_NO_EXPORT char * index2ptr(PyArrayObject *mp, npy_intp i) { npy_intp dim0; if (PyArray_NDIM(mp) == 0) { PyErr_SetString(PyExc_IndexError, "0-d arrays can't be indexed"); return NULL; } dim0 = PyArray_DIMS(mp)[0]; if (check_and_adjust_index(&i, dim0, 0) < 0) return NULL; if (i == 0) { return PyArray_DATA(mp); } return PyArray_BYTES(mp)+i*PyArray_STRIDES(mp)[0]; }
NPY_NO_EXPORT int PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims, PyArray_Descr **out_dtype, int string_type) { int i, size; PyArray_Descr *dtype = NULL; PyObject *ip; Py_buffer buffer_view; /* types for sequence handling */ PyObject ** objects; PyObject * seq; PyTypeObject * common_type; /* Check if it's an ndarray */ if (PyArray_Check(obj)) { dtype = PyArray_DESCR((PyArrayObject *)obj); Py_INCREF(dtype); goto promote_types; } /* See if it's a python None */ if (obj == Py_None) { dtype = PyArray_DescrFromType(NPY_OBJECT); if (dtype == NULL) { goto fail; } Py_INCREF(dtype); goto promote_types; } /* Check if it's a NumPy scalar */ else if (PyArray_IsScalar(obj, Generic)) { if (!string_type) { dtype = PyArray_DescrFromScalar(obj); if (dtype == NULL) { goto fail; } } else { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's a Python scalar */ dtype = _array_find_python_scalar_type(obj); if (dtype != NULL) { if (string_type) { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's an ASCII string */ if (PyBytes_Check(obj)) { int itemsize = PyString_GET_SIZE(obj); /* If it's already a big enough string, don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_STRING && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_STRING); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* Check if it's a Unicode string */ if (PyUnicode_Check(obj)) { int itemsize = PyUnicode_GET_DATA_SIZE(obj); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif /* * If it's already a big enough unicode object, * don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_UNICODE && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_UNICODE); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* PEP 3118 buffer interface */ if (PyObject_CheckBuffer(obj) == 1) { memset(&buffer_view, 0, sizeof(Py_buffer)); if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT|PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT) == 0) { PyErr_Clear(); dtype = _descriptor_from_pep3118_format(buffer_view.format); PyBuffer_Release(&buffer_view); if (dtype) { goto promote_types; } } else if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_SIMPLE) == 0) { PyErr_Clear(); dtype = PyArray_DescrNewFromType(NPY_VOID); dtype->elsize = buffer_view.itemsize; PyBuffer_Release(&buffer_view); goto promote_types; } else { PyErr_Clear(); } } /* The array interface */ ip = PyArray_LookupSpecial_OnInstance(obj, "__array_interface__"); if (ip != NULL) { if (PyDict_Check(ip)) { PyObject *typestr; #if defined(NPY_PY3K) PyObject *tmp = NULL; #endif typestr = PyDict_GetItemString(ip, "typestr"); #if defined(NPY_PY3K) /* Allow unicode type strings */ if (PyUnicode_Check(typestr)) { tmp = PyUnicode_AsASCIIString(typestr); typestr = tmp; } #endif if (typestr && PyBytes_Check(typestr)) { dtype =_array_typedescr_fromstr(PyBytes_AS_STRING(typestr)); #if defined(NPY_PY3K) if (tmp == typestr) { Py_DECREF(tmp); } #endif Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } /* The array struct interface */ ip = PyArray_LookupSpecial_OnInstance(obj, "__array_struct__"); if (ip != NULL) { PyArrayInterface *inter; char buf[40]; if (NpyCapsule_Check(ip)) { inter = (PyArrayInterface *)NpyCapsule_AsVoidPtr(ip); if (inter->two == 2) { PyOS_snprintf(buf, sizeof(buf), "|%c%d", inter->typekind, inter->itemsize); dtype = _array_typedescr_fromstr(buf); Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } /* The old buffer interface */ #if !defined(NPY_PY3K) if (PyBuffer_Check(obj)) { dtype = PyArray_DescrNewFromType(NPY_VOID); if (dtype == NULL) { goto fail; } dtype->elsize = Py_TYPE(obj)->tp_as_sequence->sq_length(obj); PyErr_Clear(); goto promote_types; } #endif /* The __array__ attribute */ ip = PyArray_LookupSpecial_OnInstance(obj, "__array__"); if (ip != NULL) { Py_DECREF(ip); ip = PyObject_CallMethod(obj, "__array__", NULL); if(ip && PyArray_Check(ip)) { dtype = PyArray_DESCR((PyArrayObject *)ip); Py_INCREF(dtype); Py_DECREF(ip); goto promote_types; } Py_XDECREF(ip); if (PyErr_Occurred()) { goto fail; } } /* * If we reached the maximum recursion depth without hitting one * of the above cases, and obj isn't a sequence-like object, the output * dtype should be either OBJECT or a user-defined type. * * Note that some libraries define sequence-like classes but want them to * be treated as objects, and they expect numpy to treat it as an object if * __len__ is not defined. */ if (maxdims == 0 || !PySequence_Check(obj) || PySequence_Size(obj) < 0) { // clear any PySequence_Size error, which corrupts further calls to it PyErr_Clear(); if (*out_dtype == NULL || (*out_dtype)->type_num != NPY_OBJECT) { Py_XDECREF(*out_dtype); *out_dtype = PyArray_DescrFromType(NPY_OBJECT); if (*out_dtype == NULL) { return -1; } } return 0; } /* Recursive case, first check the sequence contains only one type */ seq = PySequence_Fast(obj, "Could not convert object to sequence"); if (seq == NULL) { goto fail; } size = PySequence_Fast_GET_SIZE(seq); objects = PySequence_Fast_ITEMS(seq); common_type = size > 0 ? Py_TYPE(objects[0]) : NULL; for (i = 1; i < size; ++i) { if (Py_TYPE(objects[i]) != common_type) { common_type = NULL; break; } } /* all types are the same and scalar, one recursive call is enough */ if (common_type != NULL && !string_type && (common_type == &PyFloat_Type || /* TODO: we could add longs if we add a range check */ #if !defined(NPY_PY3K) common_type == &PyInt_Type || #endif common_type == &PyBool_Type || common_type == &PyComplex_Type)) { size = 1; } /* Recursive call for each sequence item */ for (i = 0; i < size; ++i) { int res = PyArray_DTypeFromObjectHelper(objects[i], maxdims - 1, out_dtype, string_type); if (res < 0) { Py_DECREF(seq); goto fail; } else if (res > 0) { Py_DECREF(seq); return res; } } Py_DECREF(seq); return 0; promote_types: /* Set 'out_dtype' if it's NULL */ if (*out_dtype == NULL) { if (!string_type && dtype->type_num == NPY_STRING) { Py_DECREF(dtype); return RETRY_WITH_STRING; } if (!string_type && dtype->type_num == NPY_UNICODE) { Py_DECREF(dtype); return RETRY_WITH_UNICODE; } *out_dtype = dtype; return 0; } /* Do type promotion with 'out_dtype' */ else { PyArray_Descr *res_dtype = PyArray_PromoteTypes(dtype, *out_dtype); Py_DECREF(dtype); if (res_dtype == NULL) { return -1; } if (!string_type && res_dtype->type_num == NPY_UNICODE && (*out_dtype)->type_num != NPY_UNICODE) { Py_DECREF(res_dtype); return RETRY_WITH_UNICODE; } if (!string_type && res_dtype->type_num == NPY_STRING && (*out_dtype)->type_num != NPY_STRING) { Py_DECREF(res_dtype); return RETRY_WITH_STRING; } Py_DECREF(*out_dtype); *out_dtype = res_dtype; return 0; } fail: Py_XDECREF(*out_dtype); *out_dtype = NULL; return -1; } #undef RETRY_WITH_STRING #undef RETRY_WITH_UNICODE /* new reference */ NPY_NO_EXPORT PyArray_Descr * _array_typedescr_fromstr(char *c_str) { PyArray_Descr *descr = NULL; PyObject *stringobj = PyString_FromString(c_str); if (stringobj == NULL) { return NULL; } if (PyArray_DescrConverter(stringobj, &descr) != NPY_SUCCEED) { Py_DECREF(stringobj); return NULL; } Py_DECREF(stringobj); return descr; } NPY_NO_EXPORT char * index2ptr(PyArrayObject *mp, npy_intp i) { npy_intp dim0; if (PyArray_NDIM(mp) == 0) { PyErr_SetString(PyExc_IndexError, "0-d arrays can't be indexed"); return NULL; } dim0 = PyArray_DIMS(mp)[0]; if (check_and_adjust_index(&i, dim0, 0, NULL) < 0) return NULL; if (i == 0) { return PyArray_DATA(mp); } return PyArray_BYTES(mp)+i*PyArray_STRIDES(mp)[0]; }
/* * Recursively examines the object to determine an appropriate dtype * to use for converting to an ndarray. * * 'obj' is the object to be converted to an ndarray. * * 'maxdims' is the maximum recursion depth. * * 'out_contains_na' gets set to 1 if an np.NA object is encountered. * The NA does not affect the dtype produced, so if this is set to 1 * and the result is for an array without NA support, the dtype should * be switched to NPY_OBJECT. When adding multi-NA support, this should * also signal whether just regular NAs or NAs with payloads were seen. * * 'out_dtype' should be either NULL or a minimal starting dtype when * the function is called. It is updated with the results of type * promotion. This dtype does not get updated when processing NA objects. * This is reset to NULL on failure. * * Returns 0 on success, -1 on failure. */ NPY_NO_EXPORT int PyArray_DTypeFromObject(PyObject *obj, int maxdims, int *out_contains_na, PyArray_Descr **out_dtype) { int i, size; PyArray_Descr *dtype = NULL; PyObject *ip; #if PY_VERSION_HEX >= 0x02060000 Py_buffer buffer_view; #endif /* Check if it's an ndarray */ if (PyArray_Check(obj)) { /* Check for any NAs in the array */ int containsna = PyArray_ContainsNA((PyArrayObject *)obj, NULL, NULL); if (containsna == -1) { goto fail; } else if (containsna) { *out_contains_na = 1; } dtype = PyArray_DESCR((PyArrayObject *)obj); Py_INCREF(dtype); goto promote_types; } /* Check if it's a NumPy scalar */ if (PyArray_IsScalar(obj, Generic)) { dtype = PyArray_DescrFromScalar(obj); if (dtype == NULL) { goto fail; } goto promote_types; } /* Check if it's a Python scalar */ dtype = _array_find_python_scalar_type(obj); if (dtype != NULL) { goto promote_types; } /* Check if it's an NA */ if (NpyNA_Check(obj)) { *out_contains_na = 1; return 0; } /* Check if it's an ASCII string */ if (PyBytes_Check(obj)) { int itemsize = PyString_GET_SIZE(obj); /* If it's already a big enough string, don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_STRING && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_STRING); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* Check if it's a Unicode string */ if (PyUnicode_Check(obj)) { int itemsize = PyUnicode_GET_DATA_SIZE(obj); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif /* * If it's already a big enough unicode object, * don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_UNICODE && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_UNICODE); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } #if PY_VERSION_HEX >= 0x02060000 /* PEP 3118 buffer interface */ memset(&buffer_view, 0, sizeof(Py_buffer)); if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT|PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT) == 0) { PyErr_Clear(); dtype = _descriptor_from_pep3118_format(buffer_view.format); PyBuffer_Release(&buffer_view); if (dtype) { goto promote_types; } } else if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_SIMPLE) == 0) { PyErr_Clear(); dtype = PyArray_DescrNewFromType(NPY_VOID); dtype->elsize = buffer_view.itemsize; PyBuffer_Release(&buffer_view); goto promote_types; } else { PyErr_Clear(); } #endif /* The array interface */ ip = PyObject_GetAttrString(obj, "__array_interface__"); if (ip != NULL) { if (PyDict_Check(ip)) { PyObject *typestr; typestr = PyDict_GetItemString(ip, "typestr"); if (typestr && PyString_Check(typestr)) { dtype =_array_typedescr_fromstr(PyString_AS_STRING(typestr)); Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } else { PyErr_Clear(); } /* The array struct interface */ ip = PyObject_GetAttrString(obj, "__array_struct__"); if (ip != NULL) { PyArrayInterface *inter; char buf[40]; if (NpyCapsule_Check(ip)) { inter = (PyArrayInterface *)NpyCapsule_AsVoidPtr(ip); if (inter->two == 2) { PyOS_snprintf(buf, sizeof(buf), "|%c%d", inter->typekind, inter->itemsize); dtype = _array_typedescr_fromstr(buf); Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } else { PyErr_Clear(); } /* The old buffer interface */ #if !defined(NPY_PY3K) if (PyBuffer_Check(obj)) { dtype = PyArray_DescrNewFromType(NPY_VOID); if (dtype == NULL) { goto fail; } dtype->elsize = Py_TYPE(obj)->tp_as_sequence->sq_length(obj); PyErr_Clear(); goto promote_types; } #endif /* The __array__ attribute */ if (PyObject_HasAttrString(obj, "__array__")) { ip = PyObject_CallMethod(obj, "__array__", NULL); if(ip && PyArray_Check(ip)) { dtype = PyArray_DESCR((PyArrayObject *)ip); Py_INCREF(dtype); Py_DECREF(ip); goto promote_types; } Py_XDECREF(ip); if (PyErr_Occurred()) { goto fail; } } /* Not exactly sure what this is about... */ #if !defined(NPY_PY3K) if (PyInstance_Check(obj)) { dtype = _use_default_type(obj); if (dtype == NULL) { goto fail; } else { goto promote_types; } } #endif /* * If we reached the maximum recursion depth without hitting one * of the above cases, the output dtype should be OBJECT */ if (maxdims == 0 || !PySequence_Check(obj)) { if (*out_dtype == NULL || (*out_dtype)->type_num != NPY_OBJECT) { Py_XDECREF(*out_dtype); *out_dtype = PyArray_DescrFromType(NPY_OBJECT); if (*out_dtype == NULL) { return -1; } } return 0; } /* Recursive case */ size = PySequence_Size(obj); if (size < 0) { goto fail; } /* Recursive call for each sequence item */ for (i = 0; i < size; ++i) { ip = PySequence_GetItem(obj, i); if (ip==NULL) { goto fail; } if (PyArray_DTypeFromObject(ip, maxdims - 1, out_contains_na, out_dtype) < 0) { Py_DECREF(ip); goto fail; } Py_DECREF(ip); } return 0; promote_types: /* Set 'out_dtype' if it's NULL */ if (*out_dtype == NULL) { *out_dtype = dtype; return 0; } /* Do type promotion with 'out_dtype' */ else { PyArray_Descr *res_dtype = PyArray_PromoteTypes(dtype, *out_dtype); Py_DECREF(dtype); if (res_dtype == NULL) { return -1; } Py_DECREF(*out_dtype); *out_dtype = res_dtype; return 0; } fail: Py_XDECREF(*out_dtype); *out_dtype = NULL; return -1; }
/*NUMPY_API * Get buffer chunk from object * * this function takes a Python object which exposes the (single-segment) * buffer interface and returns a pointer to the data segment * * You should increment the reference count by one of buf->base * if you will hang on to a reference * * You only get a borrowed reference to the object. Do not free the * memory... */ NPY_NO_EXPORT int PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf) { #if defined(NPY_PY3K) Py_buffer view; #else Py_ssize_t buflen; #endif buf->ptr = NULL; buf->flags = NPY_ARRAY_BEHAVED; buf->base = NULL; if (obj == Py_None) { return NPY_SUCCEED; } #if defined(NPY_PY3K) if (PyObject_GetBuffer(obj, &view, PyBUF_ANY_CONTIGUOUS|PyBUF_WRITABLE|PyBUF_SIMPLE) != 0) { PyErr_Clear(); buf->flags &= ~NPY_ARRAY_WRITEABLE; if (PyObject_GetBuffer(obj, &view, PyBUF_ANY_CONTIGUOUS|PyBUF_SIMPLE) != 0) { return NPY_FAIL; } } buf->ptr = view.buf; buf->len = (npy_intp) view.len; /* * In Python 3 both of the deprecated functions PyObject_AsWriteBuffer and * PyObject_AsReadBuffer that this code replaces release the buffer. It is * up to the object that supplies the buffer to guarantee that the buffer * sticks around after the release. */ PyBuffer_Release(&view); _dealloc_cached_buffer_info(obj); /* Point to the base of the buffer object if present */ if (PyMemoryView_Check(obj)) { buf->base = PyMemoryView_GET_BASE(obj); } #else if (PyObject_AsWriteBuffer(obj, &(buf->ptr), &buflen) < 0) { PyErr_Clear(); buf->flags &= ~NPY_ARRAY_WRITEABLE; if (PyObject_AsReadBuffer(obj, (const void **)&(buf->ptr), &buflen) < 0) { return NPY_FAIL; } } buf->len = (npy_intp) buflen; /* Point to the base of the buffer object if present */ if (PyBuffer_Check(obj)) { buf->base = ((PyArray_Chunk *)obj)->base; } #endif if (buf->base == NULL) { buf->base = obj; } return NPY_SUCCEED; }