summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorMarten van Kerkwijk <mhvk@astro.utoronto.ca>2017-06-01 14:24:15 -0400
committerGitHub <noreply@github.com>2017-06-01 14:24:15 -0400
commit4cc8cb27e792098875edea9fa000528ca1b34f02 (patch)
treefb0e03e9af57576a56d2fc23faf96b66acfbeba0 /numpy
parentc9f79c61f5b45843a2336f24483afd507495b847 (diff)
parentb961c3cb068214aeb0628a7d48921ffe2fd3ba02 (diff)
downloadnumpy-4cc8cb27e792098875edea9fa000528ca1b34f02.tar.gz
Merge pull request #9202 from eric-wieser/move-str-repr
MAINT: Move ndarray.__str__ and ndarray.__repr__ to their own file
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/code_generators/genapi.py1
-rw-r--r--numpy/core/code_generators/generate_numpy_api.py9
-rw-r--r--numpy/core/setup.py2
-rw-r--r--numpy/core/src/multiarray/arrayobject.c187
-rw-r--r--numpy/core/src/multiarray/strfuncs.c200
-rw-r--r--numpy/core/src/multiarray/strfuncs.h13
6 files changed, 224 insertions, 188 deletions
diff --git a/numpy/core/code_generators/genapi.py b/numpy/core/code_generators/genapi.py
index b618dedf5..a64d62e6e 100644
--- a/numpy/core/code_generators/genapi.py
+++ b/numpy/core/code_generators/genapi.py
@@ -52,6 +52,7 @@ API_FILES = [join('multiarray', 'alloc.c'),
join('multiarray', 'scalarapi.c'),
join('multiarray', 'sequence.c'),
join('multiarray', 'shape.c'),
+ join('multiarray', 'strfuncs.c'),
join('multiarray', 'usertypes.c'),
join('umath', 'loops.c.src'),
join('umath', 'ufunc_object.c'),
diff --git a/numpy/core/code_generators/generate_numpy_api.py b/numpy/core/code_generators/generate_numpy_api.py
index 79d774a89..b4aeaa277 100644
--- a/numpy/core/code_generators/generate_numpy_api.py
+++ b/numpy/core/code_generators/generate_numpy_api.py
@@ -220,8 +220,13 @@ def do_generate_api(targets, sources):
multiarray_api_dict[name] = TypeApi(name, index, 'PyTypeObject', api_name)
if len(multiarray_api_dict) != len(multiarray_api_index):
- raise AssertionError("Multiarray API size mismatch %d %d" %
- (len(multiarray_api_dict), len(multiarray_api_index)))
+ keys_dict = set(multiarray_api_dict.keys())
+ keys_index = set(multiarray_api_index.keys())
+ raise AssertionError(
+ "Multiarray API size mismatch - "
+ "index has extra keys {}, dict has extra keys {}"
+ .format(keys_index - keys_dict, keys_dict - keys_index)
+ )
extension_list = []
for name, index in genapi.order_dict(multiarray_api_index):
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index e057c5614..f268258ee 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -741,6 +741,7 @@ def configuration(parent_package='',top_path=None):
join('src', 'multiarray', 'scalartypes.h'),
join('src', 'multiarray', 'sequence.h'),
join('src', 'multiarray', 'shape.h'),
+ join('src', 'multiarray', 'strfuncs.h'),
join('src', 'multiarray', 'ucsnarrow.h'),
join('src', 'multiarray', 'usertypes.h'),
join('src', 'multiarray', 'vdot.h'),
@@ -814,6 +815,7 @@ def configuration(parent_package='',top_path=None):
join('src', 'multiarray', 'shape.c'),
join('src', 'multiarray', 'scalarapi.c'),
join('src', 'multiarray', 'scalartypes.c.src'),
+ join('src', 'multiarray', 'strfuncs.c'),
join('src', 'multiarray', 'temp_elide.c'),
join('src', 'multiarray', 'usertypes.c'),
join('src', 'multiarray', 'ucsnarrow.c'),
diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c
index 062fa8879..0e655d80c 100644
--- a/numpy/core/src/multiarray/arrayobject.c
+++ b/numpy/core/src/multiarray/arrayobject.c
@@ -53,6 +53,7 @@ maintainer email: oliphant.travis@ieee.org
#include "alloc.h"
#include "mem_overlap.h"
#include "numpyos.h"
+#include "strfuncs.h"
#include "binop_override.h"
@@ -433,93 +434,6 @@ array_dealloc(PyArrayObject *self)
Py_TYPE(self)->tp_free((PyObject *)self);
}
-/*
- * Extend string. On failure, returns NULL and leaves *strp alone.
- * XXX we do this in multiple places; time for a string library?
- */
-static char *
-extend(char **strp, Py_ssize_t n, Py_ssize_t *maxp)
-{
- char *str = *strp;
- Py_ssize_t new_cap;
-
- if (n >= *maxp - 16) {
- new_cap = *maxp * 2;
-
- if (new_cap <= *maxp) { /* overflow */
- return NULL;
- }
- str = PyArray_realloc(*strp, new_cap);
- if (str != NULL) {
- *strp = str;
- *maxp = new_cap;
- }
- }
- return str;
-}
-
-static int
-dump_data(char **string, Py_ssize_t *n, Py_ssize_t *max_n, char *data, int nd,
- npy_intp *dimensions, npy_intp *strides, PyArrayObject* self)
-{
- PyArray_Descr *descr=PyArray_DESCR(self);
- PyObject *op = NULL, *sp = NULL;
- char *ostring;
- npy_intp i, N, ret = 0;
-
-#define CHECK_MEMORY do { \
- if (extend(string, *n, max_n) == NULL) { \
- ret = -1; \
- goto end; \
- } \
- } while (0)
-
- if (nd == 0) {
- if ((op = descr->f->getitem(data, self)) == NULL) {
- return -1;
- }
- sp = PyObject_Repr(op);
- if (sp == NULL) {
- ret = -1;
- goto end;
- }
- ostring = PyString_AsString(sp);
- N = PyString_Size(sp)*sizeof(char);
- *n += N;
- CHECK_MEMORY;
- memmove(*string + (*n - N), ostring, N);
- }
- else {
- CHECK_MEMORY;
- (*string)[*n] = '[';
- *n += 1;
- for (i = 0; i < dimensions[0]; i++) {
- if (dump_data(string, n, max_n,
- data + (*strides)*i,
- nd - 1, dimensions + 1,
- strides + 1, self) < 0) {
- return -1;
- }
- CHECK_MEMORY;
- if (i < dimensions[0] - 1) {
- (*string)[*n] = ',';
- (*string)[*n+1] = ' ';
- *n += 2;
- }
- }
- CHECK_MEMORY;
- (*string)[*n] = ']';
- *n += 1;
- }
-
-#undef CHECK_MEMORY
-
-end:
- Py_XDECREF(op);
- Py_XDECREF(sp);
- return ret;
-}
-
/*NUMPY_API
* Prints the raw data of the ndarray in a form useful for debugging
* low-level C issues.
@@ -582,72 +496,6 @@ PyArray_DebugPrint(PyArrayObject *obj)
fflush(stdout);
}
-static PyObject *
-array_repr_builtin(PyArrayObject *self, int repr)
-{
- PyObject *ret;
- char *string;
- /* max_n initial value is arbitrary, dump_data will extend it */
- Py_ssize_t n = 0, max_n = PyArray_NBYTES(self) * 4 + 7;
-
- if ((string = PyArray_malloc(max_n)) == NULL) {
- return PyErr_NoMemory();
- }
-
- if (dump_data(&string, &n, &max_n, PyArray_DATA(self),
- PyArray_NDIM(self), PyArray_DIMS(self),
- PyArray_STRIDES(self), self) < 0) {
- PyArray_free(string);
- return NULL;
- }
-
- if (repr) {
- if (PyArray_ISEXTENDED(self)) {
- ret = PyUString_FromFormat("array(%s, '%c%d')",
- string,
- PyArray_DESCR(self)->type,
- PyArray_DESCR(self)->elsize);
- }
- else {
- ret = PyUString_FromFormat("array(%s, '%c')",
- string,
- PyArray_DESCR(self)->type);
- }
- }
- else {
- ret = PyUString_FromStringAndSize(string, n);
- }
-
- PyArray_free(string);
- return ret;
-}
-
-static PyObject *PyArray_StrFunction = NULL;
-static PyObject *PyArray_ReprFunction = NULL;
-
-/*NUMPY_API
- * Set the array print function to be a Python function.
- */
-NPY_NO_EXPORT void
-PyArray_SetStringFunction(PyObject *op, int repr)
-{
- if (repr) {
- /* Dispose of previous callback */
- Py_XDECREF(PyArray_ReprFunction);
- /* Add a reference to new callback */
- Py_XINCREF(op);
- /* Remember new callback */
- PyArray_ReprFunction = op;
- }
- else {
- /* Dispose of previous callback */
- Py_XDECREF(PyArray_StrFunction);
- /* Add a reference to new callback */
- Py_XINCREF(op);
- /* Remember new callback */
- PyArray_StrFunction = op;
- }
-}
/*NUMPY_API
* This function is scheduled to be removed
@@ -660,39 +508,6 @@ PyArray_SetDatetimeParseFunction(PyObject *op)
}
-static PyObject *
-array_repr(PyArrayObject *self)
-{
- PyObject *s, *arglist;
-
- if (PyArray_ReprFunction == NULL) {
- s = array_repr_builtin(self, 1);
- }
- else {
- arglist = Py_BuildValue("(O)", self);
- s = PyEval_CallObject(PyArray_ReprFunction, arglist);
- Py_DECREF(arglist);
- }
- return s;
-}
-
-static PyObject *
-array_str(PyArrayObject *self)
-{
- PyObject *s, *arglist;
-
- if (PyArray_StrFunction == NULL) {
- s = array_repr_builtin(self, 0);
- }
- else {
- arglist = Py_BuildValue("(O)", self);
- s = PyEval_CallObject(PyArray_StrFunction, arglist);
- Py_DECREF(arglist);
- }
- return s;
-}
-
-
/*NUMPY_API
*/
diff --git a/numpy/core/src/multiarray/strfuncs.c b/numpy/core/src/multiarray/strfuncs.c
new file mode 100644
index 000000000..5a0d20335
--- /dev/null
+++ b/numpy/core/src/multiarray/strfuncs.c
@@ -0,0 +1,200 @@
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+#define _MULTIARRAYMODULE
+
+#include <Python.h>
+#include <numpy/arrayobject.h>
+
+#include "npy_pycompat.h"
+
+#include "strfuncs.h"
+
+static PyObject *PyArray_StrFunction = NULL;
+static PyObject *PyArray_ReprFunction = NULL;
+
+/*NUMPY_API
+ * Set the array print function to be a Python function.
+ */
+NPY_NO_EXPORT void
+PyArray_SetStringFunction(PyObject *op, int repr)
+{
+ if (repr) {
+ /* Dispose of previous callback */
+ Py_XDECREF(PyArray_ReprFunction);
+ /* Add a reference to new callback */
+ Py_XINCREF(op);
+ /* Remember new callback */
+ PyArray_ReprFunction = op;
+ }
+ else {
+ /* Dispose of previous callback */
+ Py_XDECREF(PyArray_StrFunction);
+ /* Add a reference to new callback */
+ Py_XINCREF(op);
+ /* Remember new callback */
+ PyArray_StrFunction = op;
+ }
+}
+
+
+/*
+ * Extend string. On failure, returns NULL and leaves *strp alone.
+ * XXX we do this in multiple places; time for a string library?
+ */
+static char *
+extend(char **strp, Py_ssize_t n, Py_ssize_t *maxp)
+{
+ char *str = *strp;
+ Py_ssize_t new_cap;
+
+ if (n >= *maxp - 16) {
+ new_cap = *maxp * 2;
+
+ if (new_cap <= *maxp) { /* overflow */
+ return NULL;
+ }
+ str = PyArray_realloc(*strp, new_cap);
+ if (str != NULL) {
+ *strp = str;
+ *maxp = new_cap;
+ }
+ }
+ return str;
+}
+
+
+static int
+dump_data(char **string, Py_ssize_t *n, Py_ssize_t *max_n, char *data, int nd,
+ npy_intp *dimensions, npy_intp *strides, PyArrayObject* self)
+{
+ PyArray_Descr *descr=PyArray_DESCR(self);
+ PyObject *op = NULL, *sp = NULL;
+ char *ostring;
+ npy_intp i, N, ret = 0;
+
+#define CHECK_MEMORY do { \
+ if (extend(string, *n, max_n) == NULL) { \
+ ret = -1; \
+ goto end; \
+ } \
+ } while (0)
+
+ if (nd == 0) {
+ if ((op = descr->f->getitem(data, self)) == NULL) {
+ return -1;
+ }
+ sp = PyObject_Repr(op);
+ if (sp == NULL) {
+ ret = -1;
+ goto end;
+ }
+ ostring = PyString_AsString(sp);
+ N = PyString_Size(sp)*sizeof(char);
+ *n += N;
+ CHECK_MEMORY;
+ memmove(*string + (*n - N), ostring, N);
+ }
+ else {
+ CHECK_MEMORY;
+ (*string)[*n] = '[';
+ *n += 1;
+ for (i = 0; i < dimensions[0]; i++) {
+ if (dump_data(string, n, max_n,
+ data + (*strides)*i,
+ nd - 1, dimensions + 1,
+ strides + 1, self) < 0) {
+ return -1;
+ }
+ CHECK_MEMORY;
+ if (i < dimensions[0] - 1) {
+ (*string)[*n] = ',';
+ (*string)[*n+1] = ' ';
+ *n += 2;
+ }
+ }
+ CHECK_MEMORY;
+ (*string)[*n] = ']';
+ *n += 1;
+ }
+
+#undef CHECK_MEMORY
+
+end:
+ Py_XDECREF(op);
+ Py_XDECREF(sp);
+ return ret;
+}
+
+
+static PyObject *
+array_repr_builtin(PyArrayObject *self, int repr)
+{
+ PyObject *ret;
+ char *string;
+ /* max_n initial value is arbitrary, dump_data will extend it */
+ Py_ssize_t n = 0, max_n = PyArray_NBYTES(self) * 4 + 7;
+
+ if ((string = PyArray_malloc(max_n)) == NULL) {
+ return PyErr_NoMemory();
+ }
+
+ if (dump_data(&string, &n, &max_n, PyArray_DATA(self),
+ PyArray_NDIM(self), PyArray_DIMS(self),
+ PyArray_STRIDES(self), self) < 0) {
+ PyArray_free(string);
+ return NULL;
+ }
+
+ if (repr) {
+ if (PyArray_ISEXTENDED(self)) {
+ ret = PyUString_FromFormat("array(%s, '%c%d')",
+ string,
+ PyArray_DESCR(self)->type,
+ PyArray_DESCR(self)->elsize);
+ }
+ else {
+ ret = PyUString_FromFormat("array(%s, '%c')",
+ string,
+ PyArray_DESCR(self)->type);
+ }
+ }
+ else {
+ ret = PyUString_FromStringAndSize(string, n);
+ }
+
+ PyArray_free(string);
+ return ret;
+}
+
+
+NPY_NO_EXPORT PyObject *
+array_repr(PyArrayObject *self)
+{
+ PyObject *s, *arglist;
+
+ if (PyArray_ReprFunction == NULL) {
+ s = array_repr_builtin(self, 1);
+ }
+ else {
+ arglist = Py_BuildValue("(O)", self);
+ s = PyEval_CallObject(PyArray_ReprFunction, arglist);
+ Py_DECREF(arglist);
+ }
+ return s;
+}
+
+
+NPY_NO_EXPORT PyObject *
+array_str(PyArrayObject *self)
+{
+ PyObject *s, *arglist;
+
+ if (PyArray_StrFunction == NULL) {
+ s = array_repr_builtin(self, 0);
+ }
+ else {
+ arglist = Py_BuildValue("(O)", self);
+ s = PyEval_CallObject(PyArray_StrFunction, arglist);
+ Py_DECREF(arglist);
+ }
+ return s;
+}
diff --git a/numpy/core/src/multiarray/strfuncs.h b/numpy/core/src/multiarray/strfuncs.h
new file mode 100644
index 000000000..8e80897c2
--- /dev/null
+++ b/numpy/core/src/multiarray/strfuncs.h
@@ -0,0 +1,13 @@
+#ifndef _NPY_ARRAY_STRFUNCS_H_
+#define _NPY_ARRAY_STRFUNCS_H_
+
+NPY_NO_EXPORT void
+PyArray_SetStringFunction(PyObject *op, int repr);
+
+NPY_NO_EXPORT PyObject *
+array_repr(PyArrayObject *self);
+
+NPY_NO_EXPORT PyObject *
+array_str(PyArrayObject *self);
+
+#endif