Index: Lib/_pyio.py =================================================================== --- Lib/_pyio.py (révision 85851) +++ Lib/_pyio.py (copie de travail) @@ -596,6 +596,12 @@ implementation, but wrap one. """ + def getblocking(self) -> bool: + self._unsupported("getblocking") + + def setblocking(self, blocking): + self._unsupported("setblocking") + def read(self, n: int = None) -> bytes: """Read and return up to n bytes. @@ -764,7 +770,13 @@ def isatty(self): return self.raw.isatty() + def getblocking(self): + return self.raw.getblocking() + def setblocking(self, blocking): + self.raw.setblocking(blocking) + + class BytesIO(BufferedIOBase): """Buffered I/O implementation using an in-memory bytes buffer.""" @@ -915,6 +927,8 @@ mode. If n is negative, read until EOF or until read() would block. """ + if not self.getblocking(): + return self.read1(n) if n is not None and n < -1: raise ValueError("invalid number of bytes to read") with self._read_lock: Index: Modules/_io/fileio.c =================================================================== --- Modules/_io/fileio.c (révision 85851) +++ Modules/_io/fileio.c (copie de travail) @@ -57,6 +57,7 @@ unsigned int closefd : 1; PyObject *weakreflist; PyObject *dict; + int blocking; } fileio; PyTypeObject PyFileIO_Type; @@ -127,6 +128,7 @@ self = (fileio *) type->tp_alloc(type, 0); if (self != NULL) { + self->blocking = 1; self->fd = -1; self->readable = 0; self->writable = 0; @@ -915,7 +917,54 @@ return PyBool_FromLong(res); } +static PyObject * +fileio_getblocking(fileio *self) +{ + return PyBool_FromLong(self->blocking); +} +#ifdef HAVE_FCNTL_H +static PyObject * +fileio_setblocking(fileio *self, PyObject *args) +{ + int blocking, ret; + long flags; + + if (self->fd < 0) + return err_closed(); + + if (!PyArg_ParseTuple(args, "i", &blocking)) + return NULL; + + flags = 0xaabbccdd; + Py_BEGIN_ALLOW_THREADS + flags = fcntl(self->fd, F_GETFL); + Py_END_ALLOW_THREADS + if (flags == -1) { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + + if (blocking) + flags |= O_NONBLOCK; + else + flags &= ~O_NONBLOCK; + + Py_BEGIN_ALLOW_THREADS + ret = fcntl(self->fd, F_SETFL, flags); + Py_END_ALLOW_THREADS + if (ret != 0) { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + + self->blocking = blocking; + + Py_RETURN_NONE; +} +#endif + + PyDoc_STRVAR(fileio_doc, "file(name: str[, mode: str]) -> file IO object\n" "\n" @@ -992,6 +1041,14 @@ PyDoc_STRVAR(writable_doc, "writable() -> bool. True if file was opened in a write mode."); +PyDoc_STRVAR(getblocking_doc, +"getblocking() -> bool. Get blocking or non-blocking mode of the file."); + +#ifdef HAVE_FCNTL_H +PyDoc_STRVAR(setblocking_doc, +"setblocking(blocking: bool). Set blocking or non-blocking mode of the file."); +#endif + static PyMethodDef fileio_methods[] = { {"read", (PyCFunction)fileio_read, METH_VARARGS, read_doc}, {"readall", (PyCFunction)fileio_readall, METH_NOARGS, readall_doc}, @@ -1008,6 +1065,10 @@ {"writable", (PyCFunction)fileio_writable, METH_NOARGS, writable_doc}, {"fileno", (PyCFunction)fileio_fileno, METH_NOARGS, fileno_doc}, {"isatty", (PyCFunction)fileio_isatty, METH_NOARGS, isatty_doc}, + {"getblocking",(PyCFunction)fileio_getblocking, METH_NOARGS, getblocking_doc}, +#ifdef HAVE_FCNTL_H + {"setblocking",(PyCFunction)fileio_setblocking, METH_VARARGS, setblocking_doc}, +#endif {NULL, NULL} /* sentinel */ };