10000 ENH: pathlib support for fromfile(), .tofile() and .dump() (#12915) · numpy/numpy@afc6981 · GitHub
[go: up one dir, main page]

Skip to content

Commit afc6981

Browse files
sorenrasmussenaimattip
authored andcommitted
ENH: pathlib support for fromfile(), .tofile() and .dump() (#12915)
* ENH: pathlib support for fromfile(), .tofile() and .dump()
1 parent 40ada70 commit afc6981

File tree

6 files changed

+74
-3
lines changed

6 files changed

+74
-3
lines changed

doc/release/1.17.0-notes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,11 @@ concatenation.
328328
In some cases where ``np.interp`` would previously return ``np.nan``, it now
329329
returns an appropriate infinity.
330330

331+
Pathlib support for ``np.fromfile``, ``ndarray.tofile`` and ``ndarray.dump``
332+
----------------------------------------------------------------------------
333+
``np.fromfile``, ``np.ndarray.tofile`` and ``np.ndarray.dump`` now support
334+
the `pathlib.Path` type for the ``file``/``fid`` parameter.
335+
331336
Specialized ``np.isnan``, ``np.isinf``, and ``np.isfinite`` ufuncs for bool and int types
332337
-----------------------------------------------------------------------------------------
333338
The boolean and integer types are incapable of storing ``np.nan`` and

numpy/core/_add_newdocs.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,8 +1152,12 @@
11521152
11531153
Parameters
11541154
----------
1155-
file : file or str
1155+
file : file or str or Path
11561156
Open file object or filename.
1157 10000 +
1158+
.. versionchanged:: 1.17.0
1159+
`pathlib.Path` objects are now accepted.
1160+
11571161
dtype : data-type
11581162
Data type of the returned array.
11591163
For binary files, it is used to determine the size and byte-order
@@ -2962,9 +2966,12 @@
29622966
29632967
Parameters
29642968
----------
2965-
file : str
2969+
file : str or Path
29662970
A string naming the dump file.
29672971
2972+
.. versionchanged:: 1.17.0
2973+
`pathlib.Path` objects are now accepted.
2974+
29682975
"""))
29692976

29702977

@@ -4009,8 +4016,12 @@
40094016
40104017
Parameters
40114018
----------
4012-
fid : file or str
4019+
fid : file or str or Path
40134020
An open file object, or a string containing a filename.
4021+
4022+
.. versionchanged:: 1.17.0
4023+
`pathlib.Path` objects are now accepted.
4024+
40144025
sep : str
40154026
Separator between array items for text output.
40164027
If "" (empty), a binary file is written, equivalent to

numpy/core/src/multiarray/methods.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,10 @@ array_tofile(PyArrayObject *self, PyObject *args, PyObject *kwds)
577577
return NULL;
578578
}
579579

580+
file = NpyPath_PathlikeToFspath(file);
581+
if (file == NULL) {
582+
return NULL;
583+
}
580584
if (PyBytes_Check(file) || PyUnicode_Check(file)) {
581585
file = npy_PyFile_OpenFile(file, "wb");
582586
if (file == NULL) {

numpy/core/src/multiarray/methods.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,32 @@
11
#ifndef _NPY_ARRAY_METHODS_H_
22
#define _NPY_ARRAY_METHODS_H_
33

4+
#include "npy_import.h"
5+
46
extern NPY_NO_EXPORT PyMethodDef array_methods[];
57

68
NPY_NO_EXPORT const char *
79
npy_casting_to_string(NPY_CASTING casting);
810

11+
/* Pathlib support */
12+
static inline PyObject *
13+
NpyPath_PathlikeToFspath(PyObject *file)
14+
{
15+
static PyObject *os_PathLike = NULL;
16+
static PyObject *os_fspath = NULL;
17+
npy_cache_import("numpy.compat", "os_PathLike", &os_PathLike);
18+
if (os_PathLike == NULL) {
19+
return NULL;
20+
}
21+
npy_cache_import("numpy.compat", "os_fspath", &os_fspath);
22+
if (os_fspath == NULL) {
23+
return NULL;
24+
}
25+
26+
if (!PyObject_IsInstance(file, os_PathLike)) {
27+
return file;
28+
}
29+
return PyObject_CallFunctionObjArgs(os_fspath, file, NULL);
30+
}
31+
932
#endif

numpy/core/src/multiarray/multiarraymodule.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,6 +2078,12 @@ array_fromfile(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds)
20782078
Py_XDECREF(type);
20792079
return NULL;
20802080
}
2081+
2082+
file = NpyPath_PathlikeToFspath(file);
2083+
if (file == NULL) {
2084+
return NULL;
2085+
}
2086+
20812087
if (offset != 0 && strcmp(sep, "") != 0) {
20822088
PyErr_SetString(PyExc_TypeError, "'offset' argument only permitted for binary files");
20832089
return NULL;

numpy/core/tests/test_multiarray.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@
2323

2424
from numpy.compat import pickle
2525

26+
try:
27+
import pathlib
28+
except ImportError:
29+
try:
30+
import pathlib2 as pathlib
31+
except ImportError:
32+
pathlib = None
33+
2634
if sys.version_info[0] >= 3:
2735
import builtins
2836
else:
@@ -4639,6 +4647,20 @@ def test_roundtrip_filename(self):
46394647
y = np.fromfile(self.filename, dtype=self.dtype)
46404648
assert_array_equal(y, self.x.flat)
46414649

4650+
@pytest.mark.skipif(pathlib is None, reason="pathlib not found")
4651+
def test_roundtrip_pathlib(self):
4652+
p = pathlib.Path(self.filename)
4653+
self.x.tofile(p)
4654+
y = np.fromfile(p, dtype=self.dtype)
4655+
assert_array_equal(y, self.x.flat)
4656+
4657+
@pytest.mark.skipif(pathlib is None, reason="pathlib not found")
4658+
def test_roundtrip_dump_pathlib(self):
4659+
p = pathlib.Path(self.filename)
4660+
self.x.dump(p)
4661+
y = np.load(p, allow_pickle=True)
4662+
assert_array_equal(y, self.x)
4663+
46424664
def test_roundtrip_binary_str(self):
46434665
s = self.x.tobytes()
46444666
y = np.frombuffer(s, dtype=self.dtype)

0 commit comments

Comments
 (0)
0