]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-93955: Use unbound methods for slot `__getattr__` and `__getattribute__` (GH-93956)
authorKen Jin <kenjin@python.org>
Sat, 18 Jun 2022 14:42:42 +0000 (22:42 +0800)
committerGitHub <noreply@github.com>
Sat, 18 Jun 2022 14:42:42 +0000 (22:42 +0800)
Misc/NEWS.d/next/Core and Builtins/2022-06-17-16-30-24.gh-issue-93955.LmiAe9.rst [new file with mode: 0644]
Objects/typeobject.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-06-17-16-30-24.gh-issue-93955.LmiAe9.rst b/Misc/NEWS.d/next/Core and Builtins/2022-06-17-16-30-24.gh-issue-93955.LmiAe9.rst
new file mode 100644 (file)
index 0000000..3b2f0e8
--- /dev/null
@@ -0,0 +1 @@
+Improve performance of attribute lookups on objects with custom ``__getattribute__`` and ``__getattr__``. Patch by Ken Jin.
index db4682c69ed0e36d61a4b521d68404e7b14eafa4..513055168062f192c5e52be6f01ce327487d91f6 100644 (file)
@@ -7782,10 +7782,17 @@ slot_tp_getattro(PyObject *self, PyObject *name)
     return vectorcall_method(&_Py_ID(__getattribute__), stack, 2);
 }
 
-static PyObject *
+static inline PyObject *
 call_attribute(PyObject *self, PyObject *attr, PyObject *name)
 {
     PyObject *res, *descr = NULL;
+
+    if (_PyType_HasFeature(Py_TYPE(attr), Py_TPFLAGS_METHOD_DESCRIPTOR)) {
+        PyObject *args[] = { self, name };
+        res = PyObject_Vectorcall(attr, args, 2, NULL);
+        return res;
+    }
+
     descrgetfunc f = Py_TYPE(attr)->tp_descr_get;
 
     if (f != NULL) {