bpo-32571: Avoid raising unneeded AttributeError and silencing it in C code (GH-5222)

Add two new private APIs: _PyObject_LookupAttr() and _PyObject_LookupAttrId()
This commit is contained in:
Serhiy Storchaka 2018-01-25 10:49:40 +02:00 committed by INADA Naoki
parent 2b822a0bb1
commit f320be77ff
22 changed files with 1455 additions and 1442 deletions

View file

@ -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;