summaryrefslogtreecommitdiff
path: root/numpy/core/src
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2013-07-08 15:30:20 -0700
committerCharles Harris <charlesr.harris@gmail.com>2013-07-08 15:30:20 -0700
commit884c403605d5679d4e224bb24263a490f1249b6f (patch)
treefed8c433f150f0e0a9c1d590ec5174ad8d717285 /numpy/core/src
parentf1c776657467391781767780bb0a783d24bb8d50 (diff)
parent97372dbe877f19ae73a070b05c380cfea0871dc0 (diff)
downloadnumpy-884c403605d5679d4e224bb24263a490f1249b6f.tar.gz
Merge pull request #3491 from ContinuumIO/astype_fix2
Fix creation of string arrays from object types
Diffstat (limited to 'numpy/core/src')
-rw-r--r--numpy/core/src/multiarray/convert_datatype.c50
-rw-r--r--numpy/core/src/multiarray/ctors.c31
2 files changed, 61 insertions, 20 deletions
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c
index 8cdd65d7b..2dae2f88d 100644
--- a/numpy/core/src/multiarray/convert_datatype.c
+++ b/numpy/core/src/multiarray/convert_datatype.c
@@ -226,24 +226,36 @@ PyArray_AdaptFlexibleDType(PyObject *data_obj, PyArray_Descr *data_dtype,
break;
case NPY_OBJECT:
size = 64;
- /*
- * If we're adapting a string dtype for an array of string
- * objects, call GetArrayParamsFromObject to figure out
- * maximum string size, and use that as new dtype size.
- */
if ((flex_type_num == NPY_STRING ||
flex_type_num == NPY_UNICODE) &&
data_obj != NULL) {
- /*
- * Convert data array to list of objects since
- * GetArrayParamsFromObject won't iterate through
- * items in an array.
- */
- list = PyArray_ToList(data_obj);
- if (list != NULL) {
+ if (PyArray_CheckScalar(data_obj)) {
+ PyObject *scalar = PyArray_ToList(data_obj);
+ if (scalar != NULL) {
+ PyObject *s = PyObject_Str(scalar);
+ if (s == NULL) {
+ Py_DECREF(scalar);
+ Py_DECREF(*flex_dtype);
+ *flex_dtype = NULL;
+ return;
+ }
+ else {
+ size = PyObject_Length(s);
+ Py_DECREF(s);
+ }
+ Py_DECREF(scalar);
+ }
+ }
+ else if (PyArray_Check(data_obj)) {
+ /*
+ * Convert data array to list of objects since
+ * GetArrayParamsFromObject won't iterate over
+ * array.
+ */
+ list = PyArray_ToList(data_obj);
result = PyArray_GetArrayParamsFromObject(
list,
- flex_dtype,
+ *flex_dtype,
0, &dtype,
&ndim, dims, &arr, NULL);
if (result == 0 && dtype != NULL) {
@@ -256,6 +268,18 @@ PyArray_AdaptFlexibleDType(PyObject *data_obj, PyArray_Descr *data_dtype,
}
Py_DECREF(list);
}
+ else if (PyArray_IsPythonScalar(data_obj)) {
+ PyObject *s = PyObject_Str(data_obj);
+ if (s == NULL) {
+ Py_DECREF(*flex_dtype);
+ *flex_dtype = NULL;
+ return;
+ }
+ else {
+ size = PyObject_Length(s);
+ Py_DECREF(s);
+ }
+ }
}
break;
case NPY_STRING:
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index 3734a72c2..41a56431b 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -521,7 +521,7 @@ PyArray_AssignFromSequence(PyArrayObject *self, PyObject *v)
*/
static int
-discover_itemsize(PyObject *s, int nd, int *itemsize)
+discover_itemsize(PyObject *s, int nd, int *itemsize, int size_as_string)
{
int n, r, i;
@@ -532,14 +532,26 @@ discover_itemsize(PyObject *s, int nd, int *itemsize)
if ((nd == 0) || PyString_Check(s) ||
#if defined(NPY_PY3K)
- PyMemoryView_Check(s) ||
+ PyMemoryView_Check(s) ||
#else
- PyBuffer_Check(s) ||
+ PyBuffer_Check(s) ||
#endif
- PyUnicode_Check(s)) {
+ PyUnicode_Check(s)) {
/* If an object has no length, leave it be */
- n = PyObject_Length(s);
+ if (size_as_string && s != NULL && !PyString_Check(s)) {
+ PyObject *s_string = PyObject_Str(s);
+ if (s_string) {
+ n = PyObject_Length(s_string);
+ Py_DECREF(s_string);
+ }
+ else {
+ n = -1;
+ }
+ }
+ else {
+ n = PyObject_Length(s);
+ }
if (n == -1) {
PyErr_Clear();
}
@@ -557,7 +569,7 @@ discover_itemsize(PyObject *s, int nd, int *itemsize)
return -1;
}
- r = discover_itemsize(e,nd-1,itemsize);
+ r = discover_itemsize(e, nd - 1, itemsize, size_as_string);
Py_DECREF(e);
if (r == -1) {
return -1;
@@ -1528,7 +1540,12 @@ PyArray_GetArrayParamsFromObject(PyObject *op,
if ((*out_dtype)->elsize == 0 &&
PyTypeNum_ISEXTENDED((*out_dtype)->type_num)) {
int itemsize = 0;
- if (discover_itemsize(op, *out_ndim, &itemsize) < 0) {
+ int size_as_string = 0;
+ if ((*out_dtype)->type_num == NPY_STRING ||
+ (*out_dtype)->type_num == NPY_UNICODE) {
+ size_as_string = 1;
+ }
+ if (discover_itemsize(op, *out_ndim, &itemsize, size_as_string) < 0) {
Py_DECREF(*out_dtype);
if (PyErr_Occurred() &&
PyErr_GivenExceptionMatches(PyErr_Occurred(),