diff options
author | sorenrasmussenai <47032123+sorenrasmussenai@users.noreply.github.com> | 2019-06-04 06:39:08 +0200 |
---|---|---|
committer | Matti Picus <matti.picus@gmail.com> | 2019-06-04 07:39:08 +0300 |
commit | afc69816fd2aedf513d4f4e497f28d68e0b2b3d5 (patch) | |
tree | 0da5e8a4758563c28939e2e10189df41e316de9d /numpy | |
parent | 40ada70d9efc903097b2ff3f968c23a7e2f14296 (diff) | |
download | numpy-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.py | 17 | ||||
-rw-r--r-- | numpy/core/src/multiarray/methods.c | 4 | ||||
-rw-r--r-- | numpy/core/src/multiarray/methods.h | 23 | ||||
-rw-r--r-- | numpy/core/src/multiarray/multiarraymodule.c | 6 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 22 |
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) |