@@ -211,9 +211,9 @@ PyUnicode_Concat2(PyObject **left, PyObject *right)
211
211
static inline FILE *
212
212
8000
npy_PyFile_Dup2 (PyObject * file , char * mode , npy_off_t * orig_pos )
213
213
{
214
- int fd , fd2 , unbuf ;
214
+ int fd , fd2 , seekable ;
215
215
Py_ssize_t fd2_tmp ;
216
- PyObject * ret , * os , * io , * io_raw ;
216
+ PyObject * ret , * os ;
217
217
npy_off_t pos ;
218
218
FILE * handle ;
219
219
@@ -223,6 +223,17 @@ npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
223
223
return PyFile_AsFile (file );
224
224
}
225
225
#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
+ }
226
237
227
238
/* Flush first to ensure things end up in the file in the correct order */
228
239
ret = PyObject_CallMethod (file , "flush" , "" );
@@ -276,33 +287,18 @@ npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
276
287
return NULL ;
277
288
}
278
289
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
+
279
296
/* Record the original raw file handle position */
280
297
* orig_pos = npy_ftell (handle );
281
298
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 ;
306
302
}
307
303
308
304
/* Seek raw handle to the Python-side position */
@@ -331,8 +327,8 @@ npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
331
327
static inline int
332
328
npy_PyFile_DupClose2 (PyObject * file , FILE * handle , npy_off_t orig_pos )
333
329
{
334
- int fd , unbuf ;
335
- PyObject * ret , * io , * io_raw ;
330
+ int fd , seekable ;
331
+ PyObject * ret ;
336
332
npy_off_t position ;
337
333
338
334
/* For Python 2 PyFileObject, do nothing */
@@ -356,29 +352,22 @@ npy_PyFile_DupClose2(PyObject *file, FILE* handle, npy_off_t orig_pos)
356
352
return -1 ;
357
353
}
358
354
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
+ }
360
367
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 ;
382
371
}
383
372
384
373
if (position == -1 ) {
0 commit comments