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

``

`-

`

``

1407

`+

`

1411

1408

` when the _PyType_Lookup() call fails;

`

1412

1409

``

1413

``

`-

`

1414

``

`-

lookup_maybe(), but can return unbound PyFunction

`

``

1410

`+

`

``

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

``

`-

`

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);

`