def collate_results(raw):
results = {}
for cls, attr, wrapper in raw:
- # XXX This should not be necessary.
- if cls == repr(bool) and attr in self.NUMERIC_METHODS:
- continue
key = cls, attr
assert key not in results, (results, key, wrapper)
results[key] = wrapper
cls, attr = key
with self.subTest(cls=cls, slotattr=attr):
actual = interp_results.pop(key)
- # XXX This should not be necessary.
- if cls == "<class 'collections.OrderedDict'>" and attr == '__len__':
- continue
self.assertEqual(actual, expected)
- # XXX This should not be necessary.
- interp_results = {k: v for k, v in interp_results.items() if k[1] != '__hash__'}
- # XXX This should not be necessary.
- interp_results.pop(("<class 'collections.OrderedDict'>", '__getitem__'), None)
self.maxDiff = None
self.assertEqual(interp_results, {})
}
}
-static PyTypeObject *
-managed_static_type_get_def(PyTypeObject *self, int isbuiltin)
-{
- size_t index = managed_static_type_index_get(self);
- size_t full_index = isbuiltin
- ? index
- : index + _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES;
- return &_PyRuntime.types.managed_static.types[full_index].def;
-}
PyObject *
_PyStaticType_ClearWeakRefs(interp, type);
managed_static_type_state_clear(interp, type, isbuiltin, final);
+ /* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */
}
void
return 0;
}
-static int add_operators(PyTypeObject *, PyTypeObject *);
+static int add_operators(PyTypeObject *type);
static int add_tp_new_wrapper(PyTypeObject *type);
#define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING)
static int
-type_ready_fill_dict(PyTypeObject *type, PyTypeObject *def)
+type_ready_fill_dict(PyTypeObject *type)
{
/* Add type-specific descriptors to tp_dict */
- if (add_operators(type, def) < 0) {
+ if (add_operators(type) < 0) {
return -1;
}
if (type_add_methods(type) < 0) {
static int
-type_ready(PyTypeObject *type, PyTypeObject *def, int initial)
+type_ready(PyTypeObject *type, int initial)
{
ASSERT_TYPE_LOCK_HELD();
if (type_ready_set_new(type, initial) < 0) {
goto error;
}
- if (type_ready_fill_dict(type, def) < 0) {
+ if (type_ready_fill_dict(type) < 0) {
goto error;
}
if (initial) {
int res;
BEGIN_TYPE_LOCK();
if (!(type->tp_flags & Py_TPFLAGS_READY)) {
- res = type_ready(type, NULL, 1);
+ res = type_ready(type, 1);
} else {
res = 0;
assert(_PyType_CheckConsistency(type));
managed_static_type_state_init(interp, self, isbuiltin, initial);
- PyTypeObject *def = managed_static_type_get_def(self, isbuiltin);
- if (initial) {
- memcpy(def, self, sizeof(PyTypeObject));
- }
-
int res;
BEGIN_TYPE_LOCK();
- res = type_ready(self, def, initial);
+ res = type_ready(self, initial);
END_TYPE_LOCK();
if (res < 0) {
_PyStaticType_ClearWeakRefs(interp, self);
managed_static_type_state_clear(interp, self, isbuiltin, initial);
}
-
return res;
}
return 0;
}
+static int
+slot_inherited(PyTypeObject *type, pytype_slotdef *slotdef, void **slot)
+{
+ void **slot_base = slotptr(type->tp_base, slotdef->offset);
+ if (slot_base == NULL || *slot != *slot_base) {
+ return 0;
+ }
+
+ /* Some slots are inherited in pairs. */
+ if (slot == (void *)&type->tp_hash) {
+ return (type->tp_richcompare == type->tp_base->tp_richcompare);
+ }
+ else if (slot == (void *)&type->tp_richcompare) {
+ return (type->tp_hash == type->tp_base->tp_hash);
+ }
+
+ /* It must be inherited (see type_ready_inherit()). */
+ return 1;
+}
+
/* This function is called by PyType_Ready() to populate the type's
dictionary with method descriptors for function slots. For each
function slot (like tp_repr) that's defined in the type, one or more
infinite recursion here.) */
static int
-add_operators(PyTypeObject *type, PyTypeObject *def)
+add_operators(PyTypeObject *type)
{
PyObject *dict = lookup_tp_dict(type);
pytype_slotdef *p;
PyObject *descr;
void **ptr;
- assert(def == NULL || (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
- if (def == NULL) {
- def = type;
- }
-
for (p = slotdefs; p->name; p++) {
if (p->wrapper == NULL)
continue;
- ptr = slotptr(def, p->offset);
+ ptr = slotptr(type, p->offset);
if (!ptr || !*ptr)
continue;
+ /* Also ignore when the type slot has been inherited. */
+ if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN
+ && type->tp_base != NULL
+ && slot_inherited(type, p, ptr))
+ {
+ continue;
+ }
int r = PyDict_Contains(dict, p->name_strobj);
if (r > 0)
continue;