bpo-30509: Clean up calling type slots. (#1883) · python/cpython@4e624ca
@@ -1398,29 +1398,23 @@ PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
13981398return type_is_subtype_base_chain(a, b);
13991399}
140014001401-/* Internal routines to do a method lookup in the type
1402- without looking in the instance dictionary
1403- (so we can't use PyObject_GetAttr) but still binding
1404- it to the instance. The arguments are the object,
1405- the method name as a C string, and the address of a
1406- static variable used to cache the interned Python string.
1401+/* Routines to do a method lookup in the type without looking in the
1402+ instance dictionary (so we can't use PyObject_GetAttr) but still
1403+ binding it to the instance.
1407140414081405 Variants:
140914061410- - lookup_maybe() returns NULL without raising an exception
1407+ - _PyObject_LookupSpecial() returns NULL without raising an exception
14111408 when the _PyType_Lookup() call fails;
141214091413- - lookup_maybe_method() and lookup_method() are similar to
1414- lookup_maybe(), but can return unbound PyFunction
1410+ - lookup_maybe_method() and lookup_method() are internal routines similar
1411+ to _PyObject_LookupSpecial(), but can return unbound PyFunction
14151412 to avoid temporary method object. Pass self as first argument when
14161413 unbound == 1.
1417-1418- - _PyObject_LookupSpecial() expose lookup_maybe for the benefit of
1419- other places.
14201414*/
142114151422-static PyObject *
1423-lookup_maybe(PyObject *self, _Py_Identifier *attrid)
1416+PyObject *
1417+_PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid)
14241418{
14251419PyObject *res;
14261420@@ -1471,12 +1465,6 @@ lookup_method(PyObject *self, _Py_Identifier *attrid, int *unbound)
14711465return res;
14721466}
147314671474-PyObject *
1475-_PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid)
1476-{
1477-return lookup_maybe(self, attrid);
1478-}
1479-14801468static PyObject*
14811469call_unbound(int unbound, PyObject *func, PyObject *self,
14821470PyObject **args, Py_ssize_t nargs)
@@ -1501,23 +1489,19 @@ call_unbound_noarg(int unbound, PyObject *func, PyObject *self)
15011489 }
15021490}
150314911504-/* A variation of PyObject_CallMethodObjArgs that uses lookup_maybe_method()
1505- instead of PyObject_GetAttrString(). This uses the same convention
1506- as lookup_maybe_method to cache the interned name string object. */
1492+/* A variation of PyObject_CallMethod* that uses lookup_maybe_method()
1493+ instead of PyObject_GetAttrString(). */
15071494static PyObject *
15081495call_method(PyObject *obj, _Py_Identifier *name,
15091496PyObject **args, Py_ssize_t nargs)
15101497{
15111498int unbound;
15121499PyObject *func, *retval;
151315001514-func = lookup_maybe_method(obj, name, &unbound);
1501+func = lookup_method(obj, name, &unbound);
15151502if (func == NULL) {
1516-if (!PyErr_Occurred())
1517-PyErr_SetObject(PyExc_AttributeError, name->object);
15181503return NULL;
15191504 }
1520-15211505retval = call_unbound(unbound, func, obj, args, nargs);
15221506Py_DECREF(func);
15231507return retval;
@@ -5960,45 +5944,19 @@ slot_sq_length(PyObject *self)
59605944return len;
59615945}
596259465963-/* Super-optimized version of slot_sq_item.
5964- Other slots could do the same... */
59655947static PyObject *
59665948slot_sq_item(PyObject *self, Py_ssize_t i)
59675949{
5968-PyObject *func, *ival = NULL, *retval = NULL;
5969-descrgetfunc f;
5970-5971-func = _PyType_LookupId(Py_TYPE(self), &PyId___getitem__);
5972-if (func == NULL) {
5973-PyObject *getitem_str = _PyUnicode_FromId(&PyId___getitem__);
5974-PyErr_SetObject(PyExc_AttributeError, getitem_str);
5975-return NULL;
5976- }
5977-5978-f = Py_TYPE(func)->tp_descr_get;
5979-if (f == NULL) {
5980-Py_INCREF(func);
5981- }
5982-else {
5983-func = f(func, self, (PyObject *)(Py_TYPE(self)));
5984-if (func == NULL) {
5985-return NULL;
5986- }
5987- }
5988-5989-ival = PyLong_FromSsize_t(i);
5950+PyObject *retval;
5951+PyObject *args[1];
5952+PyObject *ival = PyLong_FromSsize_t(i);
59905953if (ival == NULL) {
5991-goto error;
5954+return NULL;
59925955 }
5993-5994-retval = PyObject_CallFunctionObjArgs(func, ival, NULL);
5995-Py_DECREF(func);
5956+args[0] = ival;
5957+retval = call_method(self, &PyId___getitem__, args, 1);
59965958Py_DECREF(ival);
59975959return retval;
5998-5999-error:
6000-Py_DECREF(func);
6001-return NULL;
60025960}
6003596160045962static int
@@ -6223,7 +6181,7 @@ slot_tp_repr(PyObject *self)
62236181_Py_IDENTIFIER(__repr__);
62246182int unbound;
622561836226-func = lookup_method(self, &PyId___repr__, &unbound);
6184+func = lookup_maybe_method(self, &PyId___repr__, &unbound);
62276185if (func != NULL) {
62286186res = call_unbound_noarg(unbound, func, self);
62296187Py_DECREF(func);
@@ -6243,7 +6201,7 @@ slot_tp_hash(PyObject *self)
62436201Py_ssize_t h;
62446202int unbound;
624562036246-func = lookup_method(self, &PyId___hash__, &unbound);
6204+func = lookup_maybe_method(self, &PyId___hash__, &unbound);
6247620562486206if (func == Py_None) {
62496207Py_DECREF(func);
@@ -6422,7 +6380,7 @@ slot_tp_richcompare(PyObject *self, PyObject *other, int op)
64226380int unbound;
64236381PyObject *func, *res;
642463826425-func = lookup_method(self, &name_op[op], &unbound);
6383+func = lookup_maybe_method(self, &name_op[op], &unbound);
64266384if (func == NULL) {
64276385PyErr_Clear();
64286386Py_RETURN_NOTIMPLEMENTED;
@@ -6441,7 +6399,7 @@ slot_tp_iter(PyObject *self)
64416399PyObject *func, *res;
64426400_Py_IDENTIFIER(__iter__);
644364016444-func = lookup_method(self, &PyId___iter__, &unbound);
6402+func = lookup_maybe_method(self, &PyId___iter__, &unbound);
64456403if (func == Py_None) {
64466404Py_DECREF(func);
64476405PyErr_Format(PyExc_TypeError,
@@ -6457,7 +6415,7 @@ slot_tp_iter(PyObject *self)
64576415 }
6458641664596417PyErr_Clear();
6460-func = lookup_method(self, &PyId___getitem__, &unbound);
6418+func = lookup_maybe_method(self, &PyId___getitem__, &unbound);
64616419if (func == NULL) {
64626420PyErr_Format(PyExc_TypeError,
64636421"'%.200s' object is not iterable",
@@ -6597,7 +6555,7 @@ slot_am_await(PyObject *self)
65976555PyObject *func, *res;
65986556_Py_IDENTIFIER(__await__);
659965576600-func = lookup_method(self, &PyId___await__, &unbound);
6558+func = lookup_maybe_method(self, &PyId___await__, &unbound);
66016559if (func != NULL) {
66026560res = call_unbound_noarg(unbound, func, self);
66036561Py_DECREF(func);
@@ -6616,7 +6574,7 @@ slot_am_aiter(PyObject *self)
66166574PyObject *func, *res;
66176575_Py_IDENTIFIER(__aiter__);
661865766619-func = lookup_method(self, &PyId___aiter__, &unbound);
6577+func = lookup_maybe_method(self, &PyId___aiter__, &unbound);
66206578if (func != NULL) {
66216579res = call_unbound_noarg(unbound, func, self);
66226580Py_DECREF(func);
@@ -6635,7 +6593,7 @@ slot_am_anext(PyObject *self)
66356593PyObject *func, *res;
66366594_Py_IDENTIFIER(__anext__);
663765956638-func = lookup_method(self, &PyId___anext__, &unbound);
6596+func = lookup_maybe_method(self, &PyId___anext__, &unbound);
66396597if (func != NULL) {
66406598res = call_unbound_noarg(unbound, func, self);
66416599Py_DECREF(func);
@@ -7182,7 +7140,7 @@ set_names(PyTypeObject *type)
71827140return -1;
7183714171847142while (PyDict_Next(names_to_set, &i, &key, &value)) {
7185-set_name = lookup_maybe(value, &PyId___set_name__);
7143+set_name = _PyObject_LookupSpecial(value, &PyId___set_name__);
71867144if (set_name != NULL) {
71877145tmp = PyObject_CallFunctionObjArgs(set_name, type, key, NULL);
71887146Py_DECREF(set_name);