bpo-40170: PyType_HasFeature() now always calls PyType_GetFlags() (GH… · python/cpython@45ec5b9

@@ -269,7 +269,7 @@ PyType_Modified(PyTypeObject *type)

269269

PyObject *raw, *ref;

270270

Py_ssize_t i;

271271272-

if (!PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))

272+

if (!_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))

273273

return;

274274275275

raw = type->tp_subclasses;

@@ -307,7 +307,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {

307307

PyObject *mro_meth = NULL;

308308

PyObject *type_mro_meth = NULL;

309309310-

if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))

310+

if (!_PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))

311311

return;

312312313313

if (custom) {

@@ -332,7 +332,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {

332332

assert(PyType_Check(b));

333333

cls = (PyTypeObject *)b;

334334335-

if (!PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) ||

335+

if (!_PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) ||

336336

!PyType_IsSubtype(type, cls)) {

337337

goto clear;

338338

}

@@ -356,11 +356,11 @@ assign_version_tag(PyTypeObject *type)

356356

Py_ssize_t i, n;

357357

PyObject *bases;

358358359-

if (PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))

359+

if (_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))

360360

return 1;

361-

if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))

361+

if (!_PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))

362362

return 0;

363-

if (!PyType_HasFeature(type, Py_TPFLAGS_READY))

363+

if (!_PyType_HasFeature(type, Py_TPFLAGS_READY))

364364

return 0;

365365366366

type->tp_version_tag = next_version_tag++;

@@ -1028,23 +1028,29 @@ PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)

10281028

const size_t size = _PyObject_VAR_SIZE(type, nitems+1);

10291029

/* note that we need to add one, for the sentinel */

103010301031-

if (PyType_IS_GC(type))

1031+

if (_PyType_IS_GC(type)) {

10321032

obj = _PyObject_GC_Malloc(size);

1033-

else

1033+

}

1034+

else {

10341035

obj = (PyObject *)PyObject_MALLOC(size);

1036+

}

103510371036-

if (obj == NULL)

1038+

if (obj == NULL) {

10371039

return PyErr_NoMemory();

1040+

}

1038104110391042

memset(obj, '\0', size);

104010431041-

if (type->tp_itemsize == 0)

1044+

if (type->tp_itemsize == 0) {

10421045

(void)PyObject_INIT(obj, type);

1043-

else

1046+

}

1047+

else {

10441048

(void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);

1049+

}

104510501046-

if (PyType_IS_GC(type))

1051+

if (_PyType_IS_GC(type)) {

10471052

_PyObject_GC_TRACK(obj);

1053+

}

10481054

return obj;

10491055

}

10501056

@@ -1178,7 +1184,7 @@ subtype_dealloc(PyObject *self)

1178118411791185

/* Test whether the type has GC exactly once */

118011861181-

if (!PyType_IS_GC(type)) {

1187+

if (!_PyType_IS_GC(type)) {

11821188

/* A non GC dynamic type allows certain simplifications:

11831189

there's no need to call clear_slots(), or DECREF the dict,

11841190

or clear weakrefs. */

@@ -1304,8 +1310,9 @@ subtype_dealloc(PyObject *self)

13041310

/* Call the base tp_dealloc(); first retrack self if

13051311

* basedealloc knows about gc.

13061312

*/

1307-

if (PyType_IS_GC(base))

1313+

if (_PyType_IS_GC(base)) {

13081314

_PyObject_GC_TRACK(self);

1315+

}

13091316

assert(basedealloc);

13101317

basedealloc(self);

13111318

@@ -1435,7 +1442,7 @@ lookup_maybe_method(PyObject *self, _Py_Identifier *attrid, int *unbound)

14351442

return NULL;

14361443

}

143714441438-

if (PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)) {

1445+

if (_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)) {

14391446

/* Avoid temporary PyMethodObject */

14401447

*unbound = 1;

14411448

Py_INCREF(res);

@@ -2026,7 +2033,7 @@ best_base(PyObject *bases)

20262033

if (PyType_Ready(base_i) < 0)

20272034

return NULL;

20282035

}

2029-

if (!PyType_HasFeature(base_i, Py_TPFLAGS_BASETYPE)) {

2036+

if (!_PyType_HasFeature(base_i, Py_TPFLAGS_BASETYPE)) {

20302037

PyErr_Format(PyExc_TypeError,

20312038

"type '%.100s' is not an acceptable base type",

20322039

base_i->tp_name);

@@ -2933,7 +2940,7 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)

29332940

if (base == NULL) {

29342941

goto fail;

29352942

}

2936-

if (!PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) {

2943+

if (!_PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) {

29372944

PyErr_Format(PyExc_TypeError,

29382945

"type '%.100s' is not an acceptable base type",

29392946

base->tp_name);

@@ -3051,7 +3058,7 @@ PyType_FromSpec(PyType_Spec *spec)

30513058

void *

30523059

PyType_GetSlot(PyTypeObject *type, int slot)

30533060

{

3054-

if (!PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE) || slot < 0) {

3061+

if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE) || slot < 0) {

30553062

PyErr_BadInternalCall();

30563063

return NULL;

30573064

}

@@ -3134,7 +3141,7 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)

31343141

unsigned int h;

3135314231363143

if (MCACHE_CACHEABLE_NAME(name) &&

3137-

PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) {

3144+

_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) {

31383145

/* fast path */

31393146

h = MCACHE_HASH_METHOD(type, name);

31403147

if (method_cache[h].version == type->tp_version_tag &&

@@ -5404,7 +5411,7 @@ PyType_Ready(PyTypeObject *type)

54045411

}

5405541254065413

/* Sanity check for tp_free. */

5407-

if (PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) &&

5414+

if (_PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) &&

54085415

(type->tp_free == NULL || type->tp_free == PyObject_Del)) {

54095416

/* This base class needs to call tp_free, but doesn't have

54105417

* one, or its tp_free is for non-gc'ed objects.