8000 Merge pull request #8339 from charris/backport-8335 · numpy/numpy@4876f24 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4876f24

Browse files
authored
Merge pull request #8339 from charris/backport-8335
BUG: Fix ndarray.tofile large file corruption in append mode.
2 parents 47c18a0 + 8bc0ed1 commit 4876f24

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
@@ -3843,6 +3843,15 @@ def test_largish_file(self):
38433843
f.seek(d.nbytes)
38443844
d.tofile(f)
38453845
assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
3846+
# check append mode (gh-8329)
3847+
open(self.filename, "w").close() # delete file contents
3848+
with open(self.filename, "ab") as f:
3849+
d.tofile(f)
3850+
assert_array_equal(d, np.fromfile(self.filename))
3851+
with open(self.filename, "ab") as f:
3852+
d.tofile(f)
3853+
assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
3854+
38463855

38473856
def test_file_position_after_fromfile(self):
38483857
# gh-4118
@@ -4106,7 +4115,7 @@ def test_int_shape(self):
41064115
x = np.eye(3)
41074116
if IS_PYPY:
41084117
x.resize(3, refcheck=False)
4109-
else:
4118+
else:
41104119
x.resize(3)
41114120
assert_array_equal(x, np.eye(3)[0,:])
41124121

@@ -4135,7 +4144,7 @@ def test_zeros_appended(self):
41354144
x = np.eye(3)
41364145
if IS_PYPY:
41374146
x.resize(2, 3, 3, refcheck=False)
4138-
else:
4147+
else:
41394148
x.resize(2, 3, 3)
41404149
assert_array_equal(x[0], np.eye(3))
41414150
assert_array_equal(x[1], np.zeros((3, 3)))

0 commit comments

Comments
 (0)
0