summaryrefslogtreecommitdiffstats
path: root/Modules/_io
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2018-01-25 08:49:40 (GMT)
committerINADA Naoki <methane@users.noreply.github.com>2018-01-25 08:49:40 (GMT)
commitf320be77ffb73e3b9e7fc98c37b8df3975d84b40 (patch)
tree552338f0200938249233fa4aa7b00add61965337 /Modules/_io
parent2b822a0bb1de2612c85d8f75e3ce89eda2ac9f68 (diff)
downloadcpython-f320be77ffb73e3b9e7fc98c37b8df3975d84b40.zip
cpython-f320be77ffb73e3b9e7fc98c37b8df3975d84b40.tar.gz
cpython-f320be77ffb73e3b9e7fc98c37b8df3975d84b40.tar.bz2
bpo-32571: Avoid raising unneeded AttributeError and silencing it in C code (GH-5222)
Add two new private APIs: _PyObject_LookupAttr() and _PyObject_LookupAttrId()
Diffstat (limited to 'Modules/_io')
-rw-r--r--Modules/_io/bufferedio.c7
-rw-r--r--Modules/_io/fileio.c8
-rw-r--r--Modules/_io/iobase.c38
-rw-r--r--Modules/_io/textio.c48
4 files changed, 37 insertions, 64 deletions
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index b81abde..2b7aaaf 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -1541,7 +1541,9 @@ _bufferedreader_read_all(buffered *self)
}
_bufferedreader_reset_buf(self);
- readall = _PyObject_GetAttrWithoutError(self->raw, _PyIO_str_readall);
+ if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) {
+ goto cleanup;
+ }
if (readall) {
tmp = _PyObject_CallNoArg(readall);
Py_DECREF(readall);
@@ -1561,9 +1563,6 @@ _bufferedreader_read_all(buffered *self)
}
goto cleanup;
}
- else if (PyErr_Occurred()) {
- goto cleanup;
- }
chunks = PyList_New(0);
if (chunks == NULL)
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
index 269142c..0d5bf3b 100644
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -1073,12 +1073,10 @@ fileio_repr(fileio *self)
if (self->fd < 0)
return PyUnicode_FromFormat("<_io.FileIO [closed]>");
- nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
+ if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) {
+ return NULL;
+ }
if (nameobj == NULL) {
- if (PyErr_ExceptionMatches(PyExc_AttributeError))
- PyErr_Clear();
- else
- return NULL;
res = PyUnicode_FromFormat(
"<_io.FileIO fd=%d mode='%s' closefd=%s>",
self->fd, mode_string(self), self->closefd ? "True" : "False");
diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c
index 348d449..0c329bf 100644
--- a/Modules/_io/iobase.c
+++ b/Modules/_io/iobase.c
@@ -133,18 +133,12 @@ static int
iobase_is_closed(PyObject *self)
{
PyObject *res;
+ int ret;
/* This gets the derived attribute, which is *not* __IOBase_closed
in most cases! */
- res = _PyObject_GetAttrId(self, &PyId___IOBase_closed);
- if (res == NULL) {
- if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
- return -1;
- }
- PyErr_Clear();
- return 0;
- }
- Py_DECREF(res);
- return 1;
+ ret = _PyObject_LookupAttrId(self, &PyId___IOBase_closed, &res);
+ Py_XDECREF(res);
+ return ret;
}
/* Flush and close methods */
@@ -190,20 +184,16 @@ iobase_check_closed(PyObject *self)
int closed;
/* This gets the derived attribute, which is *not* __IOBase_closed
in most cases! */
- res = _PyObject_GetAttrWithoutError(self, _PyIO_str_closed);
- if (res == NULL) {
- if (PyErr_Occurred()) {
+ closed = _PyObject_LookupAttr(self, _PyIO_str_closed, &res);
+ if (closed > 0) {
+ closed = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ if (closed > 0) {
+ PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
return -1;
}
- return 0;
- }
- closed = PyObject_IsTrue(res);
- Py_DECREF(res);
- if (closed <= 0) {
- return closed;
}
- PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
- return -1;
+ return closed;
}
PyObject *
@@ -273,8 +263,7 @@ iobase_finalize(PyObject *self)
/* If `closed` doesn't exist or can't be evaluated as bool, then the
object is probably in an unusable state, so ignore. */
- res = _PyObject_GetAttrWithoutError(self, _PyIO_str_closed);
- if (res == NULL) {
+ if (_PyObject_LookupAttr(self, _PyIO_str_closed, &res) <= 0) {
PyErr_Clear();
closed = -1;
}
@@ -538,8 +527,7 @@ _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit)
PyObject *peek, *buffer, *result;
Py_ssize_t old_size = -1;
- peek = _PyObject_GetAttrWithoutError(self, _PyIO_str_peek);
- if (peek == NULL && PyErr_Occurred()) {
+ if (_PyObject_LookupAttr(self, _PyIO_str_peek, &peek) < 0) {
return NULL;
}
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index 9f3fd2d..717b56a 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -924,14 +924,10 @@ _textiowrapper_set_encoder(textio *self, PyObject *codec_info,
return -1;
/* Get the normalized named of the codec */
- res = _PyObject_GetAttrId(codec_info, &PyId_name);
- if (res == NULL) {
- if (PyErr_ExceptionMatches(PyExc_AttributeError))
- PyErr_Clear();
- else
- return -1;
+ if (_PyObject_LookupAttrId(codec_info, &PyId_name, &res) < 0) {
+ return -1;
}
- else if (PyUnicode_Check(res)) {
+ if (res != NULL && PyUnicode_Check(res)) {
const encodefuncentry *e = encodefuncs;
while (e->name != NULL) {
if (_PyUnicode_EqualToASCIIString(res, e->name)) {
@@ -1177,19 +1173,17 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
if (Py_TYPE(buffer) == &PyBufferedReader_Type ||
Py_TYPE(buffer) == &PyBufferedWriter_Type ||
- Py_TYPE(buffer) == &PyBufferedRandom_Type) {
- raw = _PyObject_GetAttrId(buffer, &PyId_raw);
+ Py_TYPE(buffer) == &PyBufferedRandom_Type)
+ {
+ if (_PyObject_LookupAttrId(buffer, &PyId_raw, &raw) < 0)
+ goto error;
/* Cache the raw FileIO object to speed up 'closed' checks */
- if (raw == NULL) {
- if (PyErr_ExceptionMatches(PyExc_AttributeError))
- PyErr_Clear();
+ if (raw != NULL) {
+ if (Py_TYPE(raw) == &PyFileIO_Type)
+ self->raw = raw;
else
- goto error;
+ Py_DECREF(raw);
}
- else if (Py_TYPE(raw) == &PyFileIO_Type)
- self->raw = raw;
- else
- Py_DECREF(raw);
}
res = _PyObject_CallMethodId(buffer, &PyId_seekable, NULL);
@@ -1201,17 +1195,12 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
goto error;
self->seekable = self->telling = r;
- res = _PyObject_GetAttrWithoutError(buffer, _PyIO_str_read1);
- if (res != NULL) {
- Py_DECREF(res);
- self->has_read1 = 1;
- }
- else if (!PyErr_Occurred()) {
- self->has_read1 = 0;
- }
- else {
+ r = _PyObject_LookupAttr(buffer, _PyIO_str_read1, &res);
+ if (r < 0) {
goto error;
}
+ Py_XDECREF(res);
+ self->has_read1 = r;
self->encoding_start_of_stream = 0;
if (_textiowrapper_fix_encoder_state(self) < 0) {
@@ -3020,10 +3009,9 @@ textiowrapper_newlines_get(textio *self, void *context)
{
PyObject *res;
CHECK_ATTACHED(self);
- if (self->decoder == NULL)
- Py_RETURN_NONE;
- res = _PyObject_GetAttrWithoutError(self->decoder, _PyIO_str_newlines);
- if (res == NULL && !PyErr_Occurred()) {
+ if (self->decoder == NULL ||
+ _PyObject_LookupAttr(self->decoder, _PyIO_str_newlines, &res) == 0)
+ {
Py_RETURN_NONE;
}
return res;