bpo-30509: Clean up calling type slots. (#1883) · python/cpython@4e624ca (original) (raw)
`@@ -1398,29 +1398,23 @@ PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
`
1398
1398
`return type_is_subtype_base_chain(a, b);
`
1399
1399
`}
`
1400
1400
``
1401
``
`-
/* 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.
`
1407
1404
``
1408
1405
` Variants:
`
1409
1406
``
1410
``
`-
- lookup_maybe() returns NULL without raising an exception
`
``
1407
`+
- _PyObject_LookupSpecial() returns NULL without raising an exception
`
1411
1408
` when the _PyType_Lookup() call fails;
`
1412
1409
``
1413
``
`-
- 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
`
1415
1412
` to avoid temporary method object. Pass self as first argument when
`
1416
1413
` unbound == 1.
`
1417
``
-
1418
``
`-
- _PyObject_LookupSpecial() expose lookup_maybe for the benefit of
`
1419
``
`-
other places.
`
1420
1414
`*/
`
1421
1415
``
1422
``
`-
static PyObject *
`
1423
``
`-
lookup_maybe(PyObject *self, _Py_Identifier *attrid)
`
``
1416
`+
PyObject *
`
``
1417
`+
_PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid)
`
1424
1418
`{
`
1425
1419
`PyObject *res;
`
1426
1420
``
`@@ -1471,12 +1465,6 @@ lookup_method(PyObject *self, _Py_Identifier *attrid, int *unbound)
`
1471
1465
`return res;
`
1472
1466
`}
`
1473
1467
``
1474
``
`-
PyObject *
`
1475
``
`-
_PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid)
`
1476
``
`-
{
`
1477
``
`-
return lookup_maybe(self, attrid);
`
1478
``
`-
}
`
1479
``
-
1480
1468
`static PyObject*
`
1481
1469
`call_unbound(int unbound, PyObject *func, PyObject *self,
`
1482
1470
`PyObject **args, Py_ssize_t nargs)
`
`@@ -1501,23 +1489,19 @@ call_unbound_noarg(int unbound, PyObject *func, PyObject *self)
`
1501
1489
` }
`
1502
1490
`}
`
1503
1491
``
1504
``
`-
/* 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(). */
`
1507
1494
`static PyObject *
`
1508
1495
`call_method(PyObject *obj, _Py_Identifier *name,
`
1509
1496
`PyObject **args, Py_ssize_t nargs)
`
1510
1497
`{
`
1511
1498
`int unbound;
`
1512
1499
`PyObject *func, *retval;
`
1513
1500
``
1514
``
`-
func = lookup_maybe_method(obj, name, &unbound);
`
``
1501
`+
func = lookup_method(obj, name, &unbound);
`
1515
1502
`if (func == NULL) {
`
1516
``
`-
if (!PyErr_Occurred())
`
1517
``
`-
PyErr_SetObject(PyExc_AttributeError, name->object);
`
1518
1503
`return NULL;
`
1519
1504
` }
`
1520
``
-
1521
1505
`retval = call_unbound(unbound, func, obj, args, nargs);
`
1522
1506
`Py_DECREF(func);
`
1523
1507
`return retval;
`
`@@ -5960,45 +5944,19 @@ slot_sq_length(PyObject *self)
`
5960
5944
`return len;
`
5961
5945
`}
`
5962
5946
``
5963
``
`-
/* Super-optimized version of slot_sq_item.
`
5964
``
`-
Other slots could do the same... */
`
5965
5947
`static PyObject *
`
5966
5948
`slot_sq_item(PyObject *self, Py_ssize_t i)
`
5967
5949
`{
`
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);
`
5990
5953
`if (ival == NULL) {
`
5991
``
`-
goto error;
`
``
5954
`+
return NULL;
`
5992
5955
` }
`
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);
`
5996
5958
`Py_DECREF(ival);
`
5997
5959
`return retval;
`
5998
``
-
5999
``
`-
error:
`
6000
``
`-
Py_DECREF(func);
`
6001
``
`-
return NULL;
`
6002
5960
`}
`
6003
5961
``
6004
5962
`static int
`
`@@ -6223,7 +6181,7 @@ slot_tp_repr(PyObject *self)
`
6223
6181
`_Py_IDENTIFIER(repr);
`
6224
6182
`int unbound;
`
6225
6183
``
6226
``
`-
func = lookup_method(self, &PyId___repr__, &unbound);
`
``
6184
`+
func = lookup_maybe_method(self, &PyId___repr__, &unbound);
`
6227
6185
`if (func != NULL) {
`
6228
6186
`res = call_unbound_noarg(unbound, func, self);
`
6229
6187
`Py_DECREF(func);
`
`@@ -6243,7 +6201,7 @@ slot_tp_hash(PyObject *self)
`
6243
6201
`Py_ssize_t h;
`
6244
6202
`int unbound;
`
6245
6203
``
6246
``
`-
func = lookup_method(self, &PyId___hash__, &unbound);
`
``
6204
`+
func = lookup_maybe_method(self, &PyId___hash__, &unbound);
`
6247
6205
``
6248
6206
`if (func == Py_None) {
`
6249
6207
`Py_DECREF(func);
`
`@@ -6422,7 +6380,7 @@ slot_tp_richcompare(PyObject *self, PyObject *other, int op)
`
6422
6380
`int unbound;
`
6423
6381
`PyObject *func, *res;
`
6424
6382
``
6425
``
`-
func = lookup_method(self, &name_op[op], &unbound);
`
``
6383
`+
func = lookup_maybe_method(self, &name_op[op], &unbound);
`
6426
6384
`if (func == NULL) {
`
6427
6385
`PyErr_Clear();
`
6428
6386
`Py_RETURN_NOTIMPLEMENTED;
`
`@@ -6441,7 +6399,7 @@ slot_tp_iter(PyObject *self)
`
6441
6399
`PyObject *func, *res;
`
6442
6400
`_Py_IDENTIFIER(iter);
`
6443
6401
``
6444
``
`-
func = lookup_method(self, &PyId___iter__, &unbound);
`
``
6402
`+
func = lookup_maybe_method(self, &PyId___iter__, &unbound);
`
6445
6403
`if (func == Py_None) {
`
6446
6404
`Py_DECREF(func);
`
6447
6405
`PyErr_Format(PyExc_TypeError,
`
`@@ -6457,7 +6415,7 @@ slot_tp_iter(PyObject *self)
`
6457
6415
` }
`
6458
6416
``
6459
6417
`PyErr_Clear();
`
6460
``
`-
func = lookup_method(self, &PyId___getitem__, &unbound);
`
``
6418
`+
func = lookup_maybe_method(self, &PyId___getitem__, &unbound);
`
6461
6419
`if (func == NULL) {
`
6462
6420
`PyErr_Format(PyExc_TypeError,
`
6463
6421
`"'%.200s' object is not iterable",
`
`@@ -6597,7 +6555,7 @@ slot_am_await(PyObject *self)
`
6597
6555
`PyObject *func, *res;
`
6598
6556
`_Py_IDENTIFIER(await);
`
6599
6557
``
6600
``
`-
func = lookup_method(self, &PyId___await__, &unbound);
`
``
6558
`+
func = lookup_maybe_method(self, &PyId___await__, &unbound);
`
6601
6559
`if (func != NULL) {
`
6602
6560
`res = call_unbound_noarg(unbound, func, self);
`
6603
6561
`Py_DECREF(func);
`
`@@ -6616,7 +6574,7 @@ slot_am_aiter(PyObject *self)
`
6616
6574
`PyObject *func, *res;
`
6617
6575
`_Py_IDENTIFIER(aiter);
`
6618
6576
``
6619
``
`-
func = lookup_method(self, &PyId___aiter__, &unbound);
`
``
6577
`+
func = lookup_maybe_method(self, &PyId___aiter__, &unbound);
`
6620
6578
`if (func != NULL) {
`
6621
6579
`res = call_unbound_noarg(unbound, func, self);
`
6622
6580
`Py_DECREF(func);
`
`@@ -6635,7 +6593,7 @@ slot_am_anext(PyObject *self)
`
6635
6593
`PyObject *func, *res;
`
6636
6594
`_Py_IDENTIFIER(anext);
`
6637
6595
``
6638
``
`-
func = lookup_method(self, &PyId___anext__, &unbound);
`
``
6596
`+
func = lookup_maybe_method(self, &PyId___anext__, &unbound);
`
6639
6597
`if (func != NULL) {
`
6640
6598
`res = call_unbound_noarg(unbound, func, self);
`
6641
6599
`Py_DECREF(func);
`
`@@ -7182,7 +7140,7 @@ set_names(PyTypeObject *type)
`
7182
7140
`return -1;
`
7183
7141
``
7184
7142
`while (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_);
`
7186
7144
`if (set_name != NULL) {
`
7187
7145
`tmp = PyObject_CallFunctionObjArgs(set_name, type, key, NULL);
`
7188
7146
`Py_DECREF(set_name);
`