mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
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:
parent
2b822a0bb1
commit
f320be77ff
22 changed files with 1455 additions and 1442 deletions
2218
Python/Python-ast.c
2218
Python/Python-ast.c
File diff suppressed because it is too large
Load diff
|
@ -80,11 +80,8 @@ get_warnings_attr(_Py_Identifier *attr_id, int try_import)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
obj = _PyObject_GetAttrId(warnings_module, attr_id);
|
||||
(void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj);
|
||||
Py_DECREF(warnings_module);
|
||||
if (obj == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -893,13 +890,10 @@ get_source_line(PyObject *module_globals, int lineno)
|
|||
Py_INCREF(module_name);
|
||||
|
||||
/* Make sure the loader implements the optional get_source() method. */
|
||||
get_source = _PyObject_GetAttrId(loader, &PyId_get_source);
|
||||
(void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source);
|
||||
Py_DECREF(loader);
|
||||
if (!get_source) {
|
||||
Py_DECREF(module_name);
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/* Call get_source() to get the source code. */
|
||||
|
|
|
@ -71,12 +71,10 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
|
|||
}
|
||||
continue;
|
||||
}
|
||||
meth = _PyObject_GetAttrId(base, &PyId___mro_entries__);
|
||||
if (_PyObject_LookupAttrId(base, &PyId___mro_entries__, &meth) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (!meth) {
|
||||
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
goto error;
|
||||
}
|
||||
PyErr_Clear();
|
||||
if (new_bases) {
|
||||
if (PyList_Append(new_bases, base) < 0) {
|
||||
goto error;
|
||||
|
@ -218,18 +216,11 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
|
|||
}
|
||||
/* else: meta is not a class, so we cannot do the metaclass
|
||||
calculation, so we will use the explicitly given object as it is */
|
||||
prep = _PyObject_GetAttrId(meta, &PyId___prepare__);
|
||||
if (prep == NULL) {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
PyErr_Clear();
|
||||
ns = PyDict_New();
|
||||
}
|
||||
else {
|
||||
Py_DECREF(meta);
|
||||
Py_XDECREF(mkw);
|
||||
Py_DECREF(bases);
|
||||
return NULL;
|
||||
}
|
||||
if (_PyObject_LookupAttrId(meta, &PyId___prepare__, &prep) < 0) {
|
||||
ns = NULL;
|
||||
}
|
||||
else if (prep == NULL) {
|
||||
ns = PyDict_New();
|
||||
}
|
||||
else {
|
||||
PyObject *pargs[2] = {name, bases};
|
||||
|
@ -1127,8 +1118,7 @@ builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
|
|||
return NULL;
|
||||
}
|
||||
if (dflt != NULL) {
|
||||
result = _PyObject_GetAttrWithoutError(v, name);
|
||||
if (result == NULL && !PyErr_Occurred()) {
|
||||
if (_PyObject_LookupAttr(v, name, &result) == 0) {
|
||||
Py_INCREF(dflt);
|
||||
return dflt;
|
||||
}
|
||||
|
@ -1191,13 +1181,12 @@ builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name)
|
|||
"hasattr(): attribute name must be string");
|
||||
return NULL;
|
||||
}
|
||||
v = _PyObject_GetAttrWithoutError(obj, name);
|
||||
if (v == NULL) {
|
||||
if (!PyErr_Occurred()) {
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
if (_PyObject_LookupAttr(obj, name, &v) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (v == NULL) {
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
Py_DECREF(v);
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
|
|
@ -4813,13 +4813,12 @@ import_from(PyObject *v, PyObject *name)
|
|||
_Py_IDENTIFIER(__name__);
|
||||
PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown, *errmsg;
|
||||
|
||||
x = PyObject_GetAttr(v, name);
|
||||
if (x != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
if (_PyObject_LookupAttr(v, name, &x) != 0) {
|
||||
return x;
|
||||
}
|
||||
/* Issue #17636: in case this failed because of a circular relative
|
||||
import, try to fallback on reading the module directly from
|
||||
sys.modules. */
|
||||
PyErr_Clear();
|
||||
pkgname = _PyObject_GetAttrId(v, &PyId___name__);
|
||||
if (pkgname == NULL) {
|
||||
goto error;
|
||||
|
@ -4881,21 +4880,20 @@ import_all_from(PyObject *locals, PyObject *v)
|
|||
{
|
||||
_Py_IDENTIFIER(__all__);
|
||||
_Py_IDENTIFIER(__dict__);
|
||||
PyObject *all = _PyObject_GetAttrId(v, &PyId___all__);
|
||||
PyObject *dict, *name, *value;
|
||||
PyObject *all, *dict, *name, *value;
|
||||
int skip_leading_underscores = 0;
|
||||
int pos, err;
|
||||
|
||||
if (_PyObject_LookupAttrId(v, &PyId___all__, &all) < 0) {
|
||||
return -1; /* Unexpected error */
|
||||
}
|
||||
if (all == NULL) {
|
||||
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
return -1; /* Unexpected error */
|
||||
PyErr_Clear();
|
||||
dict = _PyObject_GetAttrId(v, &PyId___dict__);
|
||||
if (_PyObject_LookupAttrId(v, &PyId___dict__, &dict) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (dict == NULL) {
|
||||
if (!PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||
return -1;
|
||||
PyErr_SetString(PyExc_ImportError,
|
||||
"from-import-* object has no __dict__ and no __all__");
|
||||
"from-import-* object has no __dict__ and no __all__");
|
||||
return -1;
|
||||
}
|
||||
all = PyMapping_Keys(dict);
|
||||
|
|
|
@ -540,15 +540,11 @@ PyObject * _PyCodec_LookupTextEncoding(const char *encoding,
|
|||
* attribute.
|
||||
*/
|
||||
if (!PyTuple_CheckExact(codec)) {
|
||||
attr = _PyObject_GetAttrId(codec, &PyId__is_text_encoding);
|
||||
if (attr == NULL) {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||
PyErr_Clear();
|
||||
} else {
|
||||
Py_DECREF(codec);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (_PyObject_LookupAttrId(codec, &PyId__is_text_encoding, &attr) < 0) {
|
||||
Py_DECREF(codec);
|
||||
return NULL;
|
||||
}
|
||||
if (attr != NULL) {
|
||||
is_text_codec = PyObject_IsTrue(attr);
|
||||
Py_DECREF(attr);
|
||||
if (is_text_codec <= 0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue