summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorsorenrasmussenai <47032123+sorenrasmussenai@users.noreply.github.com>2019-06-04 06:39:08 +0200
committerMatti Picus <matti.picus@gmail.com>2019-06-04 07:39:08 +0300
commitafc69816fd2aedf513d4f4e497f28d68e0b2b3d5 (patch)
tree0da5e8a4758563c28939e2e10189df41e316de9d /numpy
parent40ada70d9efc903097b2ff3f968c23a7e2f14296 (diff)
downloadnumpy-afc69816fd2aedf513d4f4e497f28d68e0b2b3d5.tar.gz
ENH: pathlib support for fromfile(), .tofile() and .dump() (#12915)
* ENH: pathlib support for fromfile(), .tofile() and .dump()
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/_add_newdocs.py17
-rw-r--r--numpy/core/src/multiarray/methods.c4
-rw-r--r--numpy/core/src/multiarray/methods.h23
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c6
-rw-r--r--numpy/core/tests/test_multiarray.py22
5 files changed, 69 insertions, 3 deletions
diff --git a/numpy/core/_add_newdocs.py b/numpy/core/_add_newdocs.py
index bdff64b20..78bd882f1 100644
--- a/numpy/core/_add_newdocs.py
+++ b/numpy/core/_add_newdocs.py
@@ -1152,8 +1152,12 @@ add_newdoc('numpy.core.multiarray', 'fromfile',
Parameters
----------
- file : file or str
+ file : file or str or Path
Open file object or filename.
+
+ .. versionchanged:: 1.17.0
+ `pathlib.Path` objects are now accepted.
+
dtype : data-type
Data type of the returned array.
For binary files, it is used to determine the size and byte-order
@@ -2962,9 +2966,12 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('dump',
Parameters
----------
- file : str
+ file : str or Path
A string naming the dump file.
+ .. versionchanged:: 1.17.0
+ `pathlib.Path` objects are now accepted.
+
"""))
@@ -4009,8 +4016,12 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('tofile',
Parameters
----------
- fid : file or str
+ fid : file or str or Path
An open file object, or a string containing a filename.
+
+ .. versionchanged:: 1.17.0
+ `pathlib.Path` objects are now accepted.
+
sep : str
Separator between array items for text output.
If "" (empty), a binary file is written, equivalent to
diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c
index 3d7e035ac..97eb06769 100644
--- a/numpy/core/src/multiarray/methods.c
+++ b/numpy/core/src/multiarray/methods.c
@@ -577,6 +577,10 @@ array_tofile(PyArrayObject *self, PyObject *args, PyObject *kwds)
return NULL;
}
+ file = NpyPath_PathlikeToFspath(file);
+ if (file == NULL) {
+ return NULL;
+ }
if (PyBytes_Check(file) || PyUnicode_Check(file)) {
file = npy_PyFile_OpenFile(file, "wb");
if (file == NULL) {
diff --git a/numpy/core/src/multiarray/methods.h b/numpy/core/src/multiarray/methods.h
index 7bf87f42d..b96a3c8a8 100644
--- a/numpy/core/src/multiarray/methods.h
+++ b/numpy/core/src/multiarray/methods.h
@@ -1,9 +1,32 @@
#ifndef _NPY_ARRAY_METHODS_H_
#define _NPY_ARRAY_METHODS_H_
+#include "npy_import.h"
+
extern NPY_NO_EXPORT PyMethodDef array_methods[];
NPY_NO_EXPORT const char *
npy_casting_to_string(NPY_CASTING casting);
+/* Pathlib support */
+static inline PyObject *
+NpyPath_PathlikeToFspath(PyObject *file)
+{
+ static PyObject *os_PathLike = NULL;
+ static PyObject *os_fspath = NULL;
+ npy_cache_import("numpy.compat", "os_PathLike", &os_PathLike);
+ if (os_PathLike == NULL) {
+ return NULL;
+ }
+ npy_cache_import("numpy.compat", "os_fspath", &os_fspath);
+ if (os_fspath == NULL) {
+ return NULL;
+ }
+
+ if (!PyObject_IsInstance(file, os_PathLike)) {
+ return file;
+ }
+ return PyObject_CallFunctionObjArgs(os_fspath, file, NULL);
+}
+
#endif
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index 23195cead..915c9fcd9 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -2078,6 +2078,12 @@ array_fromfile(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds)
Py_XDECREF(type);
return NULL;
}
+
+ file = NpyPath_PathlikeToFspath(file);
+ if (file == NULL) {
+ return NULL;
+ }
+
if (offset != 0 && strcmp(sep, "") != 0) {
PyErr_SetString(PyExc_TypeError, "'offset' argument only permitted for binary files");
return NULL;
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index b9eca45a3..86af9853d 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -23,6 +23,14 @@ from contextlib import contextmanager
from numpy.compat import pickle
+try:
+ import pathlib
+except ImportError:
+ try:
+ import pathlib2 as pathlib
+ except ImportError:
+ pathlib = None
+
if sys.version_info[0] >= 3:
import builtins
else:
@@ -4639,6 +4647,20 @@ class TestIO(object):
y = np.fromfile(self.filename, dtype=self.dtype)
assert_array_equal(y, self.x.flat)
+ @pytest.mark.skipif(pathlib is None, reason="pathlib not found")
+ def test_roundtrip_pathlib(self):
+ p = pathlib.Path(self.filename)
+ self.x.tofile(p)
+ y = np.fromfile(p, dtype=self.dtype)
+ assert_array_equal(y, self.x.flat)
+
+ @pytest.mark.skipif(pathlib is None, reason="pathlib not found")
+ def test_roundtrip_dump_pathlib(self):
+ p = pathlib.Path(self.filename)
+ self.x.dump(p)
+ y = np.load(p, allow_pickle=True)
+ assert_array_equal(y, self.x)
+
def test_roundtrip_binary_str(self):
s = self.x.tobytes()
y = np.frombuffer(s, dtype=self.dtype)