Skip to content

Commit 69e20fe

Browse files
bpo-45944: Avoid calling isatty() for most open() calls
1 parent 0aa0bd0 commit 69e20fe

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

Lib/_pyio.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None,
237237
result = raw
238238
try:
239239
line_buffering = False
240-
if buffering == 1 or buffering < 0 and raw.isatty():
240+
if buffering == 1 or buffering < 0 and getattr(raw, '_size', 0) == 0 and raw.isatty():
241241
buffering = -1
242242
line_buffering = True
243243
if buffering < 0:
@@ -1594,6 +1594,7 @@ def __init__(self, file, mode='r', closefd=True, opener=None):
15941594
self._blksize = getattr(fdfstat, 'st_blksize', 0)
15951595
if self._blksize <= 1:
15961596
self._blksize = DEFAULT_BUFFER_SIZE
1597+
self._size = fdfstat.st_size
15971598

15981599
if _setmode:
15991600
# don't translate newlines (\r\n <=> \n)

Modules/_io/_iomodule.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,13 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
237237

238238
char rawmode[6], *m;
239239
int line_buffering, is_number;
240+
long size = 0;
240241
long isatty = 0;
241242

242243
PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL, *path_or_fd = NULL;
243244

244245
_Py_IDENTIFIER(_blksize);
246+
_Py_IDENTIFIER(_size);
245247
_Py_IDENTIFIER(isatty);
246248
_Py_IDENTIFIER(mode);
247249
_Py_IDENTIFIER(close);
@@ -381,6 +383,16 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
381383

382384
/* buffering */
383385
if (buffering < 0) {
386+
PyObject *size_obj;
387+
size_obj = _PyObject_GetAttrId(raw, &PyId__size);
388+
if (size_obj == NULL)
389+
goto error;
390+
size = PyLong_AsLong(size_obj);
391+
Py_DECREF(size_obj);
392+
if (size == -1 && PyErr_Occurred())
393+
goto error;
394+
}
395+
if (buffering < 0 && size == 0) {
384396
PyObject *res = _PyObject_CallMethodIdNoArgs(raw, &PyId_isatty);
385397
if (res == NULL)
386398
goto error;

Modules/_io/fileio.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ typedef struct {
6666
unsigned int closefd : 1;
6767
char finalizing;
6868
unsigned int blksize;
69+
unsigned int size;
6970
PyObject *weakreflist;
7071
PyObject *dict;
7172
} fileio;
@@ -186,6 +187,7 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
186187
self->appending = 0;
187188
self->seekable = -1;
188189
self->blksize = 0;
190+
self->size = 0;
189191
self->closefd = 1;
190192
self->weakreflist = NULL;
191193
}
@@ -469,6 +471,7 @@ _Py_COMP_DIAG_POP
469471
if (fdfstat.st_blksize > 1)
470472
self->blksize = fdfstat.st_blksize;
471473
#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
474+
self->size = fdfstat.st_size;
472475
}
473476

474477
#if defined(MS_WINDOWS) || defined(__CYGWIN__)
@@ -1184,6 +1187,7 @@ static PyGetSetDef fileio_getsetlist[] = {
11841187

11851188
static PyMemberDef fileio_members[] = {
11861189
{"_blksize", T_UINT, offsetof(fileio, blksize), 0},
1190+
{"_size", T_UINT, offsetof(fileio, size), 0},
11871191
{"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
11881192
{NULL}
11891193
};

0 commit comments

Comments
 (0)