8000 BUG: allow reading from buffered stdout. · numpy/numpy@6bbdd65 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6bbdd65

Browse files
committed
BUG: allow reading from buffered stdout.
1 parent 2027418 commit 6bbdd65

File tree

1 file changed

+39
-50
lines changed

1 file changed

+39
-50
lines changed

numpy/_core/include/numpy/npy_3kcompat.h

Lines changed: 39 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,9 @@ PyUnicode_Concat2(PyObject **left, PyObject *right)
211211
static inline FILE*
212212 8000
npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
213213
{
214-
int fd, fd2, unbuf;
214+
int fd, fd2, seekable;
215215
Py_ssize_t fd2_tmp;
216-
PyObject *ret, *os, *io, *io_raw;
216+
PyObject *ret, *os;
217217
npy_off_t pos;
218218
FILE *handle;
219219

@@ -223,6 +223,17 @@ npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
223223
return PyFile_AsFile(file);
224224
}
225225
#endif
226+
// Check for seekability before performing any file operations
227+
// in case of error.
228+
ret = PyObject_CallMethod(file, "seekable", NULL);
229+
if (ret == NULL){
230+
return NULL;
231+
}
232+
seekable = PyObject_IsTrue(ret);
233+
Py_DECREF(ret);
234+
if (seekable == -1){
235+
return NULL;
236+
}
226237

227238
/* Flush first to ensure things end up in the file in the correct order */
228239
ret = PyObject_CallMethod(file, "flush", "");
@@ -276,33 +287,18 @@ npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
276287
return NULL;
277288
}
278289

290+
if (seekable == 0) {
291+
/* Set the original pos as invalid when the object is not seekable */
292+
*orig_pos = -1;
293+
return handle;
294+
}
295+
279296
/* Record the original raw file handle position */
280297
*orig_pos = npy_ftell(handle);
281298
if (*orig_pos == -1) {
282-
/* The io module is needed to determine if buffering is used */
283-
io = PyImport_ImportModule("io");
284-
if (io == NULL) {
285-
fclose(handle);
286-
return NULL;
287-
}
288-
/* File object instances of RawIOBase are unbuffered */
289-
io_raw = PyObject_GetAttrString(io, "RawIOBase");
290-
Py_DECREF(io);
291-
if (io_raw == NULL) {
292-
fclose(handle);
293-
return NULL;
294-
}
295-
unbuf = PyObject_IsInstance(file, io_raw);
296-
Py_DECREF(io_raw);
297-
if (unbuf == 1) {
298-
/* Succeed if the IO is unbuffered */
299-
return handle;
300-
}
301-
else {
302-
PyErr_SetString(PyExc_IOError, "obtaining file position failed");
303-
fclose(handle);
304-
return NULL;
305-
}
299+
PyErr_SetString(PyExc_IOError, "obtaining file position failed");
300+
fclose(handle);
301+
return NULL;
306302
}
307303

308304
/* Seek raw handle to the Python-side position */
@@ -331,8 +327,8 @@ npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
331327
static inline int
332328
npy_PyFile_DupClose2(PyObject *file, FILE* handle, npy_off_t orig_pos)
333329
{
334-
int fd, unbuf;
335-
PyObject *ret, *io, *io_raw;
330+
int fd, seekable;
331+
PyObject *ret;
336332
npy_off_t position;
337333

338334
/* For Python 2 PyFileObject, do nothing */
@@ -356,29 +352,22 @@ npy_PyFile_DupClose2(PyObject *file, FILE* handle, npy_off_t orig_pos)
356352
return -1;
357353
}
358354

359-
if (npy_lseek(fd, orig_pos, SEEK_SET) == -1) {
355+
ret = PyObject_CallMethod(file, "seekable", NULL);
356+
if (ret == NULL){
357+
return -1;
358+
}
359+
seekable = PyObject_IsTrue(ret);
360+
Py_DECREF(ret);
361+
if (seekable == -1){
362+
return -1;
363+
}
364+
else if (seekable == 0) {
365+
return 0;
366+
}
360367

361-
/* The io module is needed to determine if buffering is used */
362-
io = PyImport_ImportModule("io");
363-
if (io == NULL) {
364-
return -1;
365-
}
366-
/* File object instances of RawIOBase are unbuffered */
367-
io_raw = PyObject_GetAttrString(io, "RawIOBase");
368-
Py_DECREF(io);
369-
if (io_raw == NULL) {
370-
return -1;
371-
}
372-
unbuf = PyObject_IsInstance(file, io_raw);
373-
Py_DECREF(io_raw);
374-
if (unbuf == 1) {
375-
/* Succeed if the IO is unbuffered */
376-
return 0;
377-
}
378-
else {
379-
PyErr_SetString(PyExc_IOError, "seeking file failed");
380-
return -1;
381-
}
368+
if (npy_lseek(fd, orig_pos, SEEK_SET) == -1) {
369+
PyErr_SetString(PyExc_IOError, "seeking file failed");
370+
return -1;
382371
}
383372

384373
if (position == -1) {

0 commit comments

Comments
 (0)
0