mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
merge 3.4 (#23093)
This commit is contained in:
commit
98beb7599e
5 changed files with 61 additions and 42 deletions
|
@ -812,7 +812,7 @@ class _BufferedIOMixin(BufferedIOBase):
|
||||||
clsname = self.__class__.__qualname__
|
clsname = self.__class__.__qualname__
|
||||||
try:
|
try:
|
||||||
name = self.name
|
name = self.name
|
||||||
except AttributeError:
|
except Exception:
|
||||||
return "<{}.{}>".format(modname, clsname)
|
return "<{}.{}>".format(modname, clsname)
|
||||||
else:
|
else:
|
||||||
return "<{}.{} name={!r}>".format(modname, clsname, name)
|
return "<{}.{} name={!r}>".format(modname, clsname, name)
|
||||||
|
@ -1640,13 +1640,13 @@ class TextIOWrapper(TextIOBase):
|
||||||
self.__class__.__qualname__)
|
self.__class__.__qualname__)
|
||||||
try:
|
try:
|
||||||
name = self.name
|
name = self.name
|
||||||
except AttributeError:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
result += " name={0!r}".format(name)
|
result += " name={0!r}".format(name)
|
||||||
try:
|
try:
|
||||||
mode = self.mode
|
mode = self.mode
|
||||||
except AttributeError:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
result += " mode={0!r}".format(mode)
|
result += " mode={0!r}".format(mode)
|
||||||
|
|
|
@ -697,6 +697,8 @@ class CommonBufferedTests:
|
||||||
self.assertIs(buf.detach(), raw)
|
self.assertIs(buf.detach(), raw)
|
||||||
self.assertRaises(ValueError, buf.detach)
|
self.assertRaises(ValueError, buf.detach)
|
||||||
|
|
||||||
|
repr(buf) # Should still work
|
||||||
|
|
||||||
def test_fileno(self):
|
def test_fileno(self):
|
||||||
rawio = self.MockRawIO()
|
rawio = self.MockRawIO()
|
||||||
bufio = self.tp(rawio)
|
bufio = self.tp(rawio)
|
||||||
|
@ -2087,6 +2089,12 @@ class TextIOWrapperTest(unittest.TestCase):
|
||||||
self.assertEqual(r.getvalue(), b"howdy")
|
self.assertEqual(r.getvalue(), b"howdy")
|
||||||
self.assertRaises(ValueError, t.detach)
|
self.assertRaises(ValueError, t.detach)
|
||||||
|
|
||||||
|
# Operations independent of the detached stream should still work
|
||||||
|
repr(t)
|
||||||
|
self.assertEqual(t.encoding, "ascii")
|
||||||
|
self.assertEqual(t.errors, "strict")
|
||||||
|
self.assertFalse(t.line_buffering)
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
raw = self.BytesIO("hello".encode("utf-8"))
|
raw = self.BytesIO("hello".encode("utf-8"))
|
||||||
b = self.BufferedReader(raw)
|
b = self.BufferedReader(raw)
|
||||||
|
@ -2104,6 +2112,9 @@ class TextIOWrapperTest(unittest.TestCase):
|
||||||
self.assertEqual(repr(t),
|
self.assertEqual(repr(t),
|
||||||
"<%s.TextIOWrapper name=b'dummy' mode='r' encoding='utf-8'>" % modname)
|
"<%s.TextIOWrapper name=b'dummy' mode='r' encoding='utf-8'>" % modname)
|
||||||
|
|
||||||
|
t.buffer.detach()
|
||||||
|
repr(t) # Should not raise an exception
|
||||||
|
|
||||||
def test_line_buffering(self):
|
def test_line_buffering(self):
|
||||||
r = self.BytesIO()
|
r = self.BytesIO()
|
||||||
b = self.BufferedWriter(r, 1000)
|
b = self.BufferedWriter(r, 1000)
|
||||||
|
@ -2904,6 +2915,9 @@ class CTextIOWrapperTest(TextIOWrapperTest):
|
||||||
self.assertRaises(ValueError, t.__init__, b, newline='xyzzy')
|
self.assertRaises(ValueError, t.__init__, b, newline='xyzzy')
|
||||||
self.assertRaises(ValueError, t.read)
|
self.assertRaises(ValueError, t.read)
|
||||||
|
|
||||||
|
t = self.TextIOWrapper.__new__(self.TextIOWrapper)
|
||||||
|
self.assertRaises(Exception, repr, t)
|
||||||
|
|
||||||
def test_garbage_collection(self):
|
def test_garbage_collection(self):
|
||||||
# C TextIOWrapper objects are collected, and collecting them flushes
|
# C TextIOWrapper objects are collected, and collecting them flushes
|
||||||
# all data to disk.
|
# all data to disk.
|
||||||
|
|
|
@ -196,6 +196,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #23093: In the io, module allow more operations to work on detached
|
||||||
|
streams.
|
||||||
|
|
||||||
- Issue #22585: On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(),
|
- Issue #22585: On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(),
|
||||||
instead of reading /dev/urandom, to get pseudo-random bytes.
|
instead of reading /dev/urandom, to get pseudo-random bytes.
|
||||||
|
|
||||||
|
|
|
@ -1404,7 +1404,7 @@ buffered_repr(buffered *self)
|
||||||
|
|
||||||
nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
|
nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
|
||||||
if (nameobj == NULL) {
|
if (nameobj == NULL) {
|
||||||
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
if (PyErr_ExceptionMatches(PyExc_Exception))
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -1219,25 +1219,27 @@ textiowrapper_closed_get(textio *self, void *context);
|
||||||
|
|
||||||
#define CHECK_INITIALIZED(self) \
|
#define CHECK_INITIALIZED(self) \
|
||||||
if (self->ok <= 0) { \
|
if (self->ok <= 0) { \
|
||||||
if (self->detached) { \
|
PyErr_SetString(PyExc_ValueError, \
|
||||||
PyErr_SetString(PyExc_ValueError, \
|
"I/O operation on uninitialized object"); \
|
||||||
"underlying buffer has been detached"); \
|
|
||||||
} else { \
|
|
||||||
PyErr_SetString(PyExc_ValueError, \
|
|
||||||
"I/O operation on uninitialized object"); \
|
|
||||||
} \
|
|
||||||
return NULL; \
|
return NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_INITIALIZED_INT(self) \
|
#define CHECK_ATTACHED(self) \
|
||||||
|
CHECK_INITIALIZED(self); \
|
||||||
|
if (self->detached) { \
|
||||||
|
PyErr_SetString(PyExc_ValueError, \
|
||||||
|
"underlying buffer has been detached"); \
|
||||||
|
return NULL; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_ATTACHED_INT(self) \
|
||||||
if (self->ok <= 0) { \
|
if (self->ok <= 0) { \
|
||||||
if (self->detached) { \
|
PyErr_SetString(PyExc_ValueError, \
|
||||||
PyErr_SetString(PyExc_ValueError, \
|
"I/O operation on uninitialized object"); \
|
||||||
"underlying buffer has been detached"); \
|
return -1; \
|
||||||
} else { \
|
} else if (self->detached) { \
|
||||||
PyErr_SetString(PyExc_ValueError, \
|
PyErr_SetString(PyExc_ValueError, \
|
||||||
"I/O operation on uninitialized object"); \
|
"underlying buffer has been detached"); \
|
||||||
} \
|
|
||||||
return -1; \
|
return -1; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,7 +1248,7 @@ static PyObject *
|
||||||
textiowrapper_detach(textio *self)
|
textiowrapper_detach(textio *self)
|
||||||
{
|
{
|
||||||
PyObject *buffer, *res;
|
PyObject *buffer, *res;
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
|
res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1254,7 +1256,6 @@ textiowrapper_detach(textio *self)
|
||||||
buffer = self->buffer;
|
buffer = self->buffer;
|
||||||
self->buffer = NULL;
|
self->buffer = NULL;
|
||||||
self->detached = 1;
|
self->detached = 1;
|
||||||
self->ok = 0;
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1299,7 +1300,7 @@ textiowrapper_write(textio *self, PyObject *args)
|
||||||
int haslf = 0;
|
int haslf = 0;
|
||||||
int needflush = 0, text_needflush = 0;
|
int needflush = 0, text_needflush = 0;
|
||||||
|
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "U:write", &text)) {
|
if (!PyArg_ParseTuple(args, "U:write", &text)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1562,7 +1563,7 @@ textiowrapper_read(textio *self, PyObject *args)
|
||||||
Py_ssize_t n = -1;
|
Py_ssize_t n = -1;
|
||||||
PyObject *result = NULL, *chunks = NULL;
|
PyObject *result = NULL, *chunks = NULL;
|
||||||
|
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n))
|
if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1937,7 +1938,7 @@ textiowrapper_readline(textio *self, PyObject *args)
|
||||||
{
|
{
|
||||||
Py_ssize_t limit = -1;
|
Py_ssize_t limit = -1;
|
||||||
|
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
if (!PyArg_ParseTuple(args, "|n:readline", &limit)) {
|
if (!PyArg_ParseTuple(args, "|n:readline", &limit)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2075,7 +2076,7 @@ textiowrapper_seek(textio *self, PyObject *args)
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence))
|
if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2255,7 +2256,7 @@ textiowrapper_tell(textio *self, PyObject *args)
|
||||||
Py_ssize_t dec_buffer_len;
|
Py_ssize_t dec_buffer_len;
|
||||||
int dec_flags;
|
int dec_flags;
|
||||||
|
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
CHECK_CLOSED(self);
|
CHECK_CLOSED(self);
|
||||||
|
|
||||||
if (!self->seekable) {
|
if (!self->seekable) {
|
||||||
|
@ -2458,7 +2459,7 @@ textiowrapper_truncate(textio *self, PyObject *args)
|
||||||
PyObject *pos = Py_None;
|
PyObject *pos = Py_None;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
|
|
||||||
CHECK_INITIALIZED(self)
|
CHECK_ATTACHED(self)
|
||||||
if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
|
if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2481,9 +2482,10 @@ textiowrapper_repr(textio *self)
|
||||||
res = PyUnicode_FromString("<_io.TextIOWrapper");
|
res = PyUnicode_FromString("<_io.TextIOWrapper");
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
|
nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
|
||||||
if (nameobj == NULL) {
|
if (nameobj == NULL) {
|
||||||
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
if (PyErr_ExceptionMatches(PyExc_Exception))
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
else
|
else
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -2499,7 +2501,7 @@ textiowrapper_repr(textio *self)
|
||||||
}
|
}
|
||||||
modeobj = _PyObject_GetAttrId((PyObject *) self, &PyId_mode);
|
modeobj = _PyObject_GetAttrId((PyObject *) self, &PyId_mode);
|
||||||
if (modeobj == NULL) {
|
if (modeobj == NULL) {
|
||||||
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
if (PyErr_ExceptionMatches(PyExc_Exception))
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
else
|
else
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -2528,35 +2530,35 @@ error:
|
||||||
static PyObject *
|
static PyObject *
|
||||||
textiowrapper_fileno(textio *self, PyObject *args)
|
textiowrapper_fileno(textio *self, PyObject *args)
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL);
|
return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
textiowrapper_seekable(textio *self, PyObject *args)
|
textiowrapper_seekable(textio *self, PyObject *args)
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL);
|
return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
textiowrapper_readable(textio *self, PyObject *args)
|
textiowrapper_readable(textio *self, PyObject *args)
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL);
|
return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
textiowrapper_writable(textio *self, PyObject *args)
|
textiowrapper_writable(textio *self, PyObject *args)
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL);
|
return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
textiowrapper_isatty(textio *self, PyObject *args)
|
textiowrapper_isatty(textio *self, PyObject *args)
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL);
|
return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2571,7 +2573,7 @@ textiowrapper_getstate(textio *self, PyObject *args)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
textiowrapper_flush(textio *self, PyObject *args)
|
textiowrapper_flush(textio *self, PyObject *args)
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
CHECK_CLOSED(self);
|
CHECK_CLOSED(self);
|
||||||
self->telling = self->seekable;
|
self->telling = self->seekable;
|
||||||
if (_textiowrapper_writeflush(self) < 0)
|
if (_textiowrapper_writeflush(self) < 0)
|
||||||
|
@ -2584,7 +2586,7 @@ textiowrapper_close(textio *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
int r;
|
int r;
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
|
|
||||||
res = textiowrapper_closed_get(self, NULL);
|
res = textiowrapper_closed_get(self, NULL);
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
|
@ -2626,7 +2628,7 @@ textiowrapper_iternext(textio *self)
|
||||||
{
|
{
|
||||||
PyObject *line;
|
PyObject *line;
|
||||||
|
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
|
|
||||||
self->telling = 0;
|
self->telling = 0;
|
||||||
if (Py_TYPE(self) == &PyTextIOWrapper_Type) {
|
if (Py_TYPE(self) == &PyTextIOWrapper_Type) {
|
||||||
|
@ -2662,14 +2664,14 @@ textiowrapper_iternext(textio *self)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
textiowrapper_name_get(textio *self, void *context)
|
textiowrapper_name_get(textio *self, void *context)
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
return _PyObject_GetAttrId(self->buffer, &PyId_name);
|
return _PyObject_GetAttrId(self->buffer, &PyId_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
textiowrapper_closed_get(textio *self, void *context)
|
textiowrapper_closed_get(textio *self, void *context)
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
return PyObject_GetAttr(self->buffer, _PyIO_str_closed);
|
return PyObject_GetAttr(self->buffer, _PyIO_str_closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2677,7 +2679,7 @@ static PyObject *
|
||||||
textiowrapper_newlines_get(textio *self, void *context)
|
textiowrapper_newlines_get(textio *self, void *context)
|
||||||
{
|
{
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
if (self->decoder == NULL)
|
if (self->decoder == NULL)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
|
res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
|
||||||
|
@ -2703,7 +2705,7 @@ textiowrapper_errors_get(textio *self, void *context)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
textiowrapper_chunk_size_get(textio *self, void *context)
|
textiowrapper_chunk_size_get(textio *self, void *context)
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self);
|
CHECK_ATTACHED(self);
|
||||||
return PyLong_FromSsize_t(self->chunk_size);
|
return PyLong_FromSsize_t(self->chunk_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2711,7 +2713,7 @@ static int
|
||||||
textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
|
textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
|
||||||
{
|
{
|
||||||
Py_ssize_t n;
|
Py_ssize_t n;
|
||||||
CHECK_INITIALIZED_INT(self);
|
CHECK_ATTACHED_INT(self);
|
||||||
n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
|
n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
|
||||||
if (n == -1 && PyErr_Occurred())
|
if (n == -1 && PyErr_Occurred())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue