| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Speed up calls to :func:`hasattr` and three-argument :func:`getattr` for | ||
| 2 | + unassigned attributes in an object's :attr:`~object.__slots__` by roughly 6x. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1924,6 +1924,19 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, | |||
| 1924 | 1924 | if (descr != NULL) { | |
| 1925 | 1925 | f = Py_TYPE(descr)->tp_descr_get; | |
| 1926 | 1926 | if (f != NULL && PyDescr_IsData(descr)) { | |
| 1927 | + // gh-157840: We special-case member descriptors here to avoid | ||
| 1928 | + // allocating an extra AttributeError | ||
| 1929 | + if (suppress && Py_IS_TYPE(descr, &PyMemberDescr_Type)) { | ||
| 1930 | + PyMemberDef *member = ((PyMemberDescrObject *)descr)->d_member; | ||
| 1931 | + if (member->type == Py_T_OBJECT_EX | ||
| 1932 | + && !(member->flags & Py_AUDIT_READ) | ||
| 1933 | + && PyObject_TypeCheck(obj, PyDescr_TYPE(descr))) { | ||
| 1934 | + PyObject **addr = _PyMember_GetOffset(obj, member); | ||
| 1935 | + if (FT_ATOMIC_LOAD_PTR(*addr) == NULL) { | ||
| 1936 | + goto done; | ||
| 1937 | + } | ||
| 1938 | + } | ||
| 1939 | + } | ||
| 1927 | 1940 | res = f(descr, obj, (PyObject *)Py_TYPE(obj)); | |
| 1928 | 1941 | if (res == NULL && suppress && | |
| 1929 | 1942 | PyErr_ExceptionMatches(PyExc_AttributeError)) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments