8000 Merge pull request #8335 from potocpav/fix-tofile · numpy/numpy@6587f66 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6587f66

Browse files
authored
Merge pull request #8335 from potocpav/fix-tofile
BUG: tofile() creates a corrupt file for large arrays in "ab" mode
2 parents fc03618 + 17c32ac commit 6587f66

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

numpy/core/src/multiarray/convert.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,21 @@ npy_fallocate(npy_intp nbytes, FILE * fp)
4444
if (nbytes < 16 * 1024 * 1024) {
4545
return 0;
4646
}
47+
4748
/* btrfs can take a while to allocate making release worthwhile */
4849
NPY_BEGIN_ALLOW_THREADS;
49-
r = fallocate(fileno(fp), 0, npy_ftell(fp), nbytes);
50+
/*
51+
* flush in case there might be some unexpected interactions between the
52+
* fallocate call and unwritten data in the descriptor
53+
*/
54+
fflush(fp);
55+
/*
56+
* the flag "1" (=FALLOC_FL_KEEP_SIZE) is needed for the case of files
57+
* opened in append mode (issue #8329)
58+
*/
59+
r = fallocate(fileno(fp), 1, npy_ftell(fp), nbytes);
5060
NPY_END_ALLOW_THREADS;
61+
5162
/*
5263
* early exit on no space, other errors will also get found during fwrite
5364
*/

numpy/core/tests/test_multiarray.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3861,6 +3861,15 @@ def test_largish_file(self):
38613861
f.seek(d.nbytes)
38623862
d.tofile(f)
38633863
assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
3864+
# check append mode (gh-8329)
3865+
open(self.filename, "w").close() # delete file contents
3866+
with open(self.filename, "ab") as f:
3867+
d.tofile(f)
3868+
assert_array_equal(d, np.fromfile(self.filename))
3869+
with open(self.filename, "ab") as f:
3870+
d.tofile(f)
3871+
assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
3872+
38643873

38653874
def test_file_position_after_fromfile(self):
38663875
# gh-4118
@@ -4124,7 +4133,7 @@ def test_int_shape(self):
41244133
x = np.eye(3)
41254134
if IS_PYPY:
41264135
x.resize(3, refcheck=False)
4127-
else:
4136+
else:
41284137
x.resize(3)
41294138
assert_array_equal(x, np.eye(3)[0,:])
41304139

@@ -4153,7 +4162,7 @@ def test_zeros_appended(self):
41534162
x = np.eye(3)
41544163
if IS_PYPY:
41554164
x.resize(2, 3, 3, refcheck=False)
4156-
else:
4165+
else:
41574166
x.resize(2, 3, 3)
41584167
assert_array_equal(x[0], np.eye(3))
41594168
assert_array_equal(x[1], np.zeros((3, 3)))

0 commit comments

Comments
 (0)
0