diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 53403ebcfc0043..04eae0c39b0477 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -810,7 +810,7 @@ static inline PyObject ** _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) { if (PyType_Check(op) && - ((PyTypeObject *)op)->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + _PyType_HasFeature((PyTypeObject *)op, _Py_TPFLAGS_STATIC_BUILTIN)) { PyInterpreterState *interp = _PyInterpreterState_GET(); managed_static_type_state *state = _PyStaticType_GetState( interp, (PyTypeObject *)op); @@ -837,7 +837,7 @@ static inline PyWeakReference ** _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(PyObject *op) { assert(!PyType_Check(op) || - ((PyTypeObject *)op)->tp_flags & Py_TPFLAGS_HEAPTYPE); + _PyType_HasFeature((PyTypeObject *)op, Py_TPFLAGS_HEAPTYPE)); Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; return (PyWeakReference **)((char *)op + offset); } @@ -935,7 +935,7 @@ typedef union { static inline PyManagedDictPointer * _PyObject_ManagedDictPointer(PyObject *obj) { - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT)); return (PyManagedDictPointer *)((char *)obj + MANAGED_DICT_OFFSET); } @@ -951,8 +951,8 @@ _PyObject_InlineValues(PyObject *obj) { PyTypeObject *tp = Py_TYPE(obj); assert(tp->tp_basicsize > 0 && (size_t)tp->tp_basicsize % sizeof(PyObject *) == 0); - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES); - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_INLINE_VALUES)); + assert(_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT)); return (PyDictValues *)((char *)obj + tp->tp_basicsize); } diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index 581153344a8e05..4d5acf2160913b 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -10,6 +10,7 @@ extern "C" { #include "pycore_moduleobject.h" // PyModuleObject #include "pycore_lock.h" // PyMutex +#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_ULONG_RELAXED /* state */ @@ -207,7 +208,7 @@ static inline void * _PyType_GetModuleState(PyTypeObject *type) { assert(PyType_Check(type)); - assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE); + assert((FT_ATOMIC_LOAD_ULONG_RELAXED(type->tp_flags) & Py_TPFLAGS_HEAPTYPE)); PyHeapTypeObject *et = (PyHeapTypeObject *)type; assert(et->ht_module); PyModuleObject *mod = (PyModuleObject *)(et->ht_module); diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index c03652259d0e50..5cb30943ecdfca 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -1911,7 +1911,7 @@ get_tlbc_id(PyObject *Py_UNUSED(module), PyObject *obj) static PyObject * has_inline_values(PyObject *self, PyObject *obj) { - if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES) && + if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_INLINE_VALUES) && _PyObject_InlineValues(obj)->valid) { Py_RETURN_TRUE; } diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 8a30c4082e9236..199cb3629981af 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -6718,9 +6718,9 @@ _PyDict_NewKeysForClass(PyHeapTypeObject *cls) void _PyObject_InitInlineValues(PyObject *obj, PyTypeObject *tp) { - assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); - assert(tp->tp_flags & Py_TPFLAGS_INLINE_VALUES); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)); + assert(_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)); + assert(_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)); PyDictKeysObject *keys = CACHED_KEYS(tp); assert(keys != NULL); OBJECT_STAT_INC(inline_values); @@ -6840,7 +6840,7 @@ store_instance_attr_lock_held(PyObject *obj, PyDictValues *values, PyDictKeysObject *keys = CACHED_KEYS(Py_TYPE(obj)); assert(keys != NULL); assert(values != NULL); - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_INLINE_VALUES)); Py_ssize_t ix = DKIX_EMPTY; PyDictObject *dict = _PyObject_GetManagedDict(obj); assert(dict == NULL || ((PyDictObject *)dict)->ma_values == values); @@ -7005,7 +7005,7 @@ int _PyObject_ManagedDictValidityCheck(PyObject *obj) { PyTypeObject *tp = Py_TYPE(obj); - CHECK(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + CHECK(_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)); PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(obj); if (_PyManagedDictPointer_IsValues(*managed_dict)) { PyDictValues *values = _PyManagedDictPointer_GetValues(*managed_dict); @@ -7117,7 +7117,7 @@ _PyObject_IsInstanceDictEmpty(PyObject *obj) return 1; } PyDictObject *dict; - if (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)) { PyDictValues *values = _PyObject_InlineValues(obj); if (FT_ATOMIC_LOAD_UINT8(values->valid)) { PyDictKeysObject *keys = CACHED_KEYS(tp); @@ -7130,7 +7130,7 @@ _PyObject_IsInstanceDictEmpty(PyObject *obj) } dict = _PyObject_GetManagedDict(obj); } - else if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + else if (_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)) { dict = _PyObject_GetManagedDict(obj); } else { @@ -7147,10 +7147,10 @@ int PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) { PyTypeObject *tp = Py_TYPE(obj); - if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + if(!_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)) { return 0; } - if (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)) { PyDictValues *values = _PyObject_InlineValues(obj); if (values->valid) { for (Py_ssize_t i = 0; i < values->capacity; i++) { @@ -7265,7 +7265,7 @@ decref_maybe_delay(PyObject *obj, bool delay) int _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict) { - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT)); #ifndef NDEBUG Py_BEGIN_CRITICAL_SECTION(obj); assert(_PyObject_InlineValuesConsistencyCheck(obj)); @@ -7273,7 +7273,7 @@ _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict) #endif int err = 0; PyTypeObject *tp = Py_TYPE(obj); - if (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)) { #ifdef Py_GIL_DISABLED PyDictObject *prev_dict; if (!try_set_dict_inline_only_or_other_dict(obj, new_dict, &prev_dict)) { @@ -7359,7 +7359,7 @@ detach_dict_from_object(PyDictObject *mp, PyObject *obj) ASSERT_WORLD_STOPPED_OR_OBJ_LOCKED(mp); assert(mp->ma_values->embedded == 1); assert(mp->ma_values->valid == 1); - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_INLINE_VALUES)); PyDictValues *values = copy_values(mp->ma_values); @@ -7382,7 +7382,7 @@ PyObject_ClearManagedDict(PyObject *obj) { // This is called when the object is being freed or cleared // by the GC and therefore known to have no references. - if (Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_INLINE_VALUES)) { PyDictObject *dict = _PyObject_GetManagedDict(obj); if (dict == NULL) { // We have no materialized dictionary and inline values @@ -7436,7 +7436,7 @@ ensure_managed_dict(PyObject *obj) PyDictObject *dict = _PyObject_GetManagedDict(obj); if (dict == NULL) { PyTypeObject *tp = Py_TYPE(obj); - if ((tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) && + if (_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES) && FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(obj)->valid)) { dict = _PyObject_MaterializeManagedDict(obj); } @@ -7702,10 +7702,10 @@ _PyDict_SendEvent(int watcher_bits, static int _PyObject_InlineValuesConsistencyCheck(PyObject *obj) { - if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES) == 0) { + if (!_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_INLINE_VALUES)) { return 1; } - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT)); PyDictObject *dict = _PyObject_GetManagedDict(obj); if (dict == NULL) { return 1; diff --git a/Objects/object.c b/Objects/object.c index 051b668dfcbb64..a0812ff2375b5c 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1484,7 +1484,7 @@ PyObject ** _PyObject_ComputedDictPointer(PyObject *obj) { PyTypeObject *tp = Py_TYPE(obj); - assert((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); + assert(!_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)); Py_ssize_t dictoffset = tp->tp_dictoffset; if (dictoffset == 0) { @@ -1518,11 +1518,11 @@ _PyObject_ComputedDictPointer(PyObject *obj) PyObject ** _PyObject_GetDictPtr(PyObject *obj) { - if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + if (!_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT)) { return _PyObject_ComputedDictPointer(obj); } PyDictObject *dict = _PyObject_GetManagedDict(obj); - if (dict == NULL && Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + if (dict == NULL && _PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_INLINE_VALUES)) { dict = _PyObject_MaterializeManagedDict(obj); if (dict == NULL) { PyErr_Clear(); @@ -1598,7 +1598,7 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) } } PyObject *dict, *attr; - if ((tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) && + if (_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES) && _PyObject_TryGetInstanceAttribute(obj, name, &attr)) { if (attr != NULL) { *method = attr; @@ -1607,7 +1607,7 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) } dict = NULL; } - else if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + else if (_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)) { dict = (PyObject *)_PyObject_GetManagedDict(obj); } else { @@ -1700,7 +1700,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, } } if (dict == NULL) { - if ((tp->tp_flags & Py_TPFLAGS_INLINE_VALUES)) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)) { if (PyUnicode_CheckExact(name) && _PyObject_TryGetInstanceAttribute(obj, name, &res)) { if (res != NULL) { @@ -1715,7 +1715,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, } } } - else if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + else if (_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)) { dict = (PyObject *)_PyObject_GetManagedDict(obj); } else { @@ -1816,12 +1816,12 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, if (dict == NULL) { PyObject **dictptr; - if ((tp->tp_flags & Py_TPFLAGS_INLINE_VALUES)) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)) { res = _PyObject_StoreInstanceAttribute(obj, name, value); goto error_check; } - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)) { PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(obj); dictptr = (PyObject **)&managed_dict->dict; } diff --git a/Objects/structseq.c b/Objects/structseq.c index b62317e1cf3732..dbec7c61f15b84 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -111,7 +111,7 @@ static int structseq_traverse(PyObject *op, visitproc visit, void *arg) { PyStructSequence *obj = (PyStructSequence *)op; - if (Py_TYPE(obj)->tp_flags & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_HEAPTYPE)) { Py_VISIT(Py_TYPE(obj)); } Py_ssize_t i, size; @@ -577,6 +577,8 @@ initialize_static_fields(PyTypeObject *type, PyStructSequence_Desc *desc, type->tp_base = &PyTuple_Type; type->tp_methods = structseq_methods; type->tp_new = structseq_new; + // Note that it is thread-safe to not use an atomic operation to set flags + // here since PyType_Ready() will be called later. type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags; type->tp_traverse = structseq_traverse; type->tp_members = tp_members; @@ -613,7 +615,7 @@ _PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp, Py_ssize_t n_members = count_members(desc, &n_unnamed_members); PyMemberDef *members = NULL; - if ((type->tp_flags & Py_TPFLAGS_READY) == 0) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_READY)) { assert(type->tp_name == NULL); assert(type->tp_members == NULL); assert(type->tp_base == NULL); @@ -632,7 +634,7 @@ _PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp, assert(type->tp_name != NULL); assert(type->tp_members != NULL); assert(type->tp_base == &PyTuple_Type); - assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + assert(_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)); assert(_Py_IsImmortal(type)); } #endif @@ -710,7 +712,7 @@ _PyStructSequence_FiniBuiltin(PyInterpreterState *interp, PyTypeObject *type) // Ensure that the type is initialized assert(type->tp_name != NULL); assert(type->tp_base == &PyTuple_Type); - assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + assert(_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)); assert(_Py_IsImmortal(type)); // Cannot delete a type if it still has subclasses diff --git a/Objects/typeobject.c b/Objects/typeobject.c index bc840ed51ffe4c..685bab0c1736c5 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -194,7 +194,7 @@ managed_static_type_state_get(PyInterpreterState *interp, PyTypeObject *self) managed_static_type_state * _PyStaticType_GetState(PyInterpreterState *interp, PyTypeObject *self) { - assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)); return managed_static_type_state_get(interp, self); } @@ -347,7 +347,7 @@ _PyStaticType_GetBuiltins(void) static void type_set_flags(PyTypeObject *tp, unsigned long flags) { - if (tp->tp_flags & Py_TPFLAGS_READY) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_READY)) { // It's possible the type object has been exposed to other threads // if it's been marked ready. In that case, the type lock should be // held when flags are modified. @@ -381,7 +381,7 @@ type_clear_flags(PyTypeObject *tp, unsigned long flag) static inline void start_readying(PyTypeObject *type) { - if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)) { PyInterpreterState *interp = _PyInterpreterState_GET(); managed_static_type_state *state = managed_static_type_state_get(interp, type); assert(state != NULL); @@ -389,14 +389,14 @@ start_readying(PyTypeObject *type) state->readying = 1; return; } - assert((type->tp_flags & Py_TPFLAGS_READYING) == 0); + assert(!_PyType_HasFeature(type, Py_TPFLAGS_READYING)); type_add_flags(type, Py_TPFLAGS_READYING); } static inline void stop_readying(PyTypeObject *type) { - if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)) { PyInterpreterState *interp = _PyInterpreterState_GET(); managed_static_type_state *state = managed_static_type_state_get(interp, type); assert(state != NULL); @@ -404,20 +404,20 @@ stop_readying(PyTypeObject *type) state->readying = 0; return; } - assert(type->tp_flags & Py_TPFLAGS_READYING); + assert(_PyType_HasFeature(type, Py_TPFLAGS_READYING)); type_clear_flags(type, Py_TPFLAGS_READYING); } static inline int is_readying(PyTypeObject *type) { - if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)) { PyInterpreterState *interp = _PyInterpreterState_GET(); managed_static_type_state *state = managed_static_type_state_get(interp, type); assert(state != NULL); return state->readying; } - return (type->tp_flags & Py_TPFLAGS_READYING) != 0; + return _PyType_HasFeature(type, Py_TPFLAGS_READYING); } @@ -426,7 +426,7 @@ is_readying(PyTypeObject *type) static inline PyObject * lookup_tp_dict(PyTypeObject *self) { - if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)) { PyInterpreterState *interp = _PyInterpreterState_GET(); managed_static_type_state *state = _PyStaticType_GetState(interp, self); assert(state != NULL); @@ -452,7 +452,7 @@ PyType_GetDict(PyTypeObject *self) static inline void set_tp_dict(PyTypeObject *self, PyObject *dict) { - if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)) { PyInterpreterState *interp = _PyInterpreterState_GET(); managed_static_type_state *state = _PyStaticType_GetState(interp, self); assert(state != NULL); @@ -465,7 +465,7 @@ set_tp_dict(PyTypeObject *self, PyObject *dict) static inline void clear_tp_dict(PyTypeObject *self) { - if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)) { PyInterpreterState *interp = _PyInterpreterState_GET(); managed_static_type_state *state = _PyStaticType_GetState(interp, self); assert(state != NULL); @@ -499,7 +499,7 @@ static inline void set_tp_bases(PyTypeObject *self, PyObject *bases, int initial) { assert(PyTuple_CheckExact(bases)); - if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)) { // XXX tp_bases can probably be statically allocated for each // static builtin type. assert(initial); @@ -510,7 +510,7 @@ set_tp_bases(PyTypeObject *self, PyObject *bases, int initial) else { assert(PyTuple_GET_SIZE(bases) == 1); assert(PyTuple_GET_ITEM(bases, 0) == (PyObject *)self->tp_base); - assert(self->tp_base->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(_PyType_HasFeature(self->tp_base, _Py_TPFLAGS_STATIC_BUILTIN)); assert(_Py_IsImmortal(self->tp_base)); } _Py_SetImmortal(bases); @@ -521,7 +521,7 @@ set_tp_bases(PyTypeObject *self, PyObject *bases, int initial) static inline void clear_tp_bases(PyTypeObject *self, int final) { - if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)) { if (final) { if (self->tp_bases != NULL) { if (PyTuple_GET_SIZE(self->tp_bases) == 0) { @@ -572,7 +572,7 @@ static inline void set_tp_mro(PyTypeObject *self, PyObject *mro, int initial) { assert(PyTuple_CheckExact(mro)); - if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)) { // XXX tp_mro can probably be statically allocated for each // static builtin type. assert(initial); @@ -586,7 +586,7 @@ set_tp_mro(PyTypeObject *self, PyObject *mro, int initial) static inline void clear_tp_mro(PyTypeObject *self, int final) { - if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)) { if (final) { if (self->tp_mro != NULL) { if (PyTuple_GET_SIZE(self->tp_mro) == 0) { @@ -611,7 +611,7 @@ init_tp_subclasses(PyTypeObject *self) if (subclasses == NULL) { return NULL; } - if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)) { PyInterpreterState *interp = _PyInterpreterState_GET(); managed_static_type_state *state = _PyStaticType_GetState(interp, self); state->tp_subclasses = subclasses; @@ -627,7 +627,7 @@ clear_tp_subclasses(PyTypeObject *self) /* Delete the dictionary to save memory. _PyStaticType_Dealloc() callers also test if tp_subclasses is NULL to check if a static type has no subclass. */ - if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)) { PyInterpreterState *interp = _PyInterpreterState_GET(); managed_static_type_state *state = _PyStaticType_GetState(interp, self); Py_CLEAR(state->tp_subclasses); @@ -639,7 +639,7 @@ clear_tp_subclasses(PyTypeObject *self) static inline PyObject * lookup_tp_subclasses(PyTypeObject *self) { - if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)) { PyInterpreterState *interp = _PyInterpreterState_GET(); managed_static_type_state *state = _PyStaticType_GetState(interp, self); assert(state != NULL); @@ -652,7 +652,7 @@ int _PyType_HasSubclasses(PyTypeObject *self) { PyInterpreterState *interp = _PyInterpreterState_GET(); - if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN + if (_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN) // XXX _PyStaticType_GetState() should never return NULL. && _PyStaticType_GetState(interp, self) == NULL) { @@ -762,7 +762,7 @@ _PyType_CheckConsistency(PyTypeObject *type) CHECK(!_PyObject_IsFreed((PyObject *)type)); - if (!(type->tp_flags & Py_TPFLAGS_READY)) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_READY)) { /* don't check static types before PyType_Ready() */ return 1; } @@ -773,13 +773,13 @@ _PyType_CheckConsistency(PyTypeObject *type) CHECK(!is_readying(type)); CHECK(lookup_tp_dict(type) != NULL); - if (type->tp_flags & Py_TPFLAGS_HAVE_GC) { + if (_PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)) { // bpo-44263: tp_traverse is required if Py_TPFLAGS_HAVE_GC is set. // Note: tp_clear is optional. CHECK(type->tp_traverse != NULL); } - if (type->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION) { + if (_PyType_HasFeature(type, Py_TPFLAGS_DISALLOW_INSTANTIATION)) { CHECK(type->tp_new == NULL); CHECK(PyDict_Contains(lookup_tp_dict(type), &_Py_ID(__new__)) == 0); } @@ -1078,7 +1078,7 @@ type_modified_unlocked(PyTypeObject *type) return; } // Cannot modify static builtin types. - assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) == 0); + assert(!_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)); PyObject *subclasses = lookup_tp_subclasses(type); if (subclasses != NULL) { @@ -1196,7 +1196,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { return; clear: - assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + assert(!_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)); set_version_unlocked(type, 0); /* 0 is not a valid version tag */ type->tp_versions_used = _Py_ATTR_CACHE_UNUSED; if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { @@ -1283,7 +1283,7 @@ assign_version_tag(PyInterpreterState *interp, PyTypeObject *type) return 0; } } - if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { + if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { /* static types */ if (NEXT_GLOBAL_VERSION_TAG > _Py_MAX_GLOBAL_TYPE_VERSION_TAG) { /* We have run out of version numbers */ @@ -1371,7 +1371,7 @@ static PyObject * type_name(PyObject *tp, void *Py_UNUSED(closure)) { PyTypeObject *type = PyTypeObject_CAST(tp); - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { PyHeapTypeObject* et = (PyHeapTypeObject*)type; return Py_NewRef(et->ht_name); } @@ -1384,7 +1384,7 @@ static PyObject * type_qualname(PyObject *tp, void *Py_UNUSED(closure)) { PyTypeObject *type = PyTypeObject_CAST(tp); - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { PyHeapTypeObject* et = (PyHeapTypeObject*)type; return Py_NewRef(et->ht_qualname); } @@ -1448,7 +1448,7 @@ static PyObject * type_module(PyTypeObject *type) { PyObject *mod; - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { PyObject *dict = lookup_tp_dict(type); if (PyDict_GetItemRef(dict, &_Py_ID(__module__), &mod) == 0) { PyErr_Format(PyExc_AttributeError, "__module__"); @@ -1498,7 +1498,7 @@ type_set_module(PyObject *tp, PyObject *value, void *Py_UNUSED(closure)) PyObject * _PyType_GetFullyQualifiedName(PyTypeObject *type, char sep) { - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { return PyUnicode_FromString(type->tp_name); } @@ -1868,7 +1868,7 @@ type_get_doc(PyObject *tp, void *Py_UNUSED(closure)) { PyTypeObject *type = PyTypeObject_CAST(tp); PyObject *result; - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) { return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc); } PyObject *dict = lookup_tp_dict(type); @@ -1906,7 +1906,7 @@ static PyObject * type_get_annotate(PyObject *tp, void *Py_UNUSED(closure)) { PyTypeObject *type = PyTypeObject_CAST(tp); - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { PyErr_Format(PyExc_AttributeError, "type object '%s' has no attribute '__annotate__'", type->tp_name); return NULL; } @@ -1978,7 +1978,7 @@ static PyObject * type_get_annotations(PyObject *tp, void *Py_UNUSED(closure)) { PyTypeObject *type = PyTypeObject_CAST(tp); - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { PyErr_Format(PyExc_AttributeError, "type object '%s' has no attribute '__annotations__'", type->tp_name); return NULL; } @@ -2266,7 +2266,7 @@ type_call(PyObject *self, PyObject *args, PyObject *kwds) PyObject * _PyType_NewManagedObject(PyTypeObject *type) { - assert(type->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(type, Py_TPFLAGS_INLINE_VALUES)); assert(_PyType_IS_GC(type)); assert(type->tp_new == PyBaseObject_Type.tp_new); assert(type->tp_alloc == PyType_GenericAlloc); @@ -2291,7 +2291,7 @@ _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems) size_t size = _PyObject_VAR_SIZE(type, nitems+1); const size_t presize = _PyType_PreHeaderSize(type); - if (type->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + if (_PyType_HasFeature(type, Py_TPFLAGS_INLINE_VALUES)) { assert(type->tp_itemsize == 0); size += _PyInlineValuesSize(type); } @@ -2317,7 +2317,7 @@ _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems) else { _PyObject_InitVar((PyVarObject *)obj, type, nitems); } - if (type->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + if (_PyType_HasFeature(type, Py_TPFLAGS_INLINE_VALUES)) { _PyObject_InitInlineValues(obj, type); } return obj; @@ -2395,7 +2395,7 @@ subtype_traverse(PyObject *self, visitproc visit, void *arg) if (type->tp_dictoffset != base->tp_dictoffset) { assert(base->tp_dictoffset == 0); - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)) { assert(type->tp_dictoffset == -1); int err = PyObject_VisitManagedDict(self, visit, arg); if (err) { @@ -2410,8 +2410,8 @@ subtype_traverse(PyObject *self, visitproc visit, void *arg) } } - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE - && (!basetraverse || !(base->tp_flags & Py_TPFLAGS_HEAPTYPE))) { + if (_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE) + && (!basetraverse || !_PyType_HasFeature(base, Py_TPFLAGS_HEAPTYPE))) { /* For a heaptype, the instances count as references to the type. Traverse the type so the collector can find cycles involving this link. @@ -2465,13 +2465,13 @@ subtype_clear(PyObject *self) /* Clear the instance dict (if any), to break cycles involving only __dict__ slots (as in the case 'self.__dict__ is self'). */ - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - if ((base->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + if (_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)) { + if (!_PyType_HasFeature(base, Py_TPFLAGS_MANAGED_DICT)) { PyObject_ClearManagedDict(self); } else { - assert((base->tp_flags & Py_TPFLAGS_INLINE_VALUES) == - (type->tp_flags & Py_TPFLAGS_INLINE_VALUES)); + assert(_PyType_HasFeature(base, Py_TPFLAGS_INLINE_VALUES) == + _PyType_HasFeature(type, Py_TPFLAGS_INLINE_VALUES)); } } else if (type->tp_dictoffset != base->tp_dictoffset) { @@ -2494,7 +2494,7 @@ subtype_dealloc(PyObject *self) /* Extract the type; we expect it to be a heap type */ type = Py_TYPE(self); - _PyObject_ASSERT((PyObject *)type, type->tp_flags & Py_TPFLAGS_HEAPTYPE); + _PyObject_ASSERT((PyObject *)type, _PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)); /* Test whether the type has GC exactly once */ @@ -2527,10 +2527,10 @@ subtype_dealloc(PyObject *self) // Don't read type memory after calling basedealloc() since basedealloc() // can deallocate the type and free its memory. - int type_needs_decref = (type->tp_flags & Py_TPFLAGS_HEAPTYPE - && !(base->tp_flags & Py_TPFLAGS_HEAPTYPE)); + int type_needs_decref = (_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE) + && !_PyType_HasFeature(base, Py_TPFLAGS_HEAPTYPE)); - assert((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); + assert(!_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)); /* Call the base tp_dealloc() */ assert(basedealloc); @@ -2614,7 +2614,7 @@ subtype_dealloc(PyObject *self) } /* If we added a dict, DECREF it, or free inline values. */ - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)) { PyObject_ClearManagedDict(self); } else if (type->tp_dictoffset && !base->tp_dictoffset) { @@ -2640,8 +2640,8 @@ subtype_dealloc(PyObject *self) // Don't read type memory after calling basedealloc() since basedealloc() // can deallocate the type and free its memory. - int type_needs_decref = (type->tp_flags & Py_TPFLAGS_HEAPTYPE - && !(base->tp_flags & Py_TPFLAGS_HEAPTYPE)); + int type_needs_decref = (_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE) + && !_PyType_HasFeature(base, Py_TPFLAGS_HEAPTYPE)); assert(basedealloc); basedealloc(self); @@ -3370,7 +3370,7 @@ mro_internal_unlocked(PyTypeObject *type, int initial, PyObject **p_old_mro) type_mro_modified(type, lookup_tp_bases(type)); // XXX Expand this to Py_TPFLAGS_IMMUTABLETYPE? - if (!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)) { + if (!_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)) { type_modified_unlocked(type); } else { @@ -3501,7 +3501,7 @@ get_builtin_base_with_dict(PyTypeObject *type) { while (type->tp_base != NULL) { if (type->tp_dictoffset != 0 && - !(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) + !_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) return type; type = type->tp_base; } @@ -3580,7 +3580,7 @@ subtype_setdict(PyObject *obj, PyObject *value, void *context) return -1; } - if (Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT)) { return _PyObject_SetManagedDict(obj, value); } else { @@ -4210,12 +4210,12 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type) } if (ctx->add_weak) { - assert((type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) == 0); + assert(!_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_WEAKREF)); type_add_flags(type, Py_TPFLAGS_MANAGED_WEAKREF); type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET; } if (ctx->add_dict) { - assert((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); + assert(!_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)); type_add_flags(type, Py_TPFLAGS_MANAGED_DICT); type->tp_dictoffset = -1; } @@ -4969,7 +4969,7 @@ PyType_FromMetaclass( /* Inheriting variable-sized types is limited */ if (base->tp_itemsize - && !((base->tp_flags | spec->flags) & Py_TPFLAGS_ITEMS_AT_END)) + && !((PyType_GetFlags(base) | spec->flags) & Py_TPFLAGS_ITEMS_AT_END)) { PyErr_SetString( PyExc_SystemError, @@ -5805,7 +5805,7 @@ static void set_flags_recursive(PyTypeObject *self, unsigned long mask, unsigned long flags) { if (PyType_HasFeature(self, Py_TPFLAGS_IMMUTABLETYPE) || - (self->tp_flags & mask) == flags) + (PyType_GetFlags(self) & mask) == flags) { return; } @@ -5984,7 +5984,7 @@ type_setattro(PyObject *self, PyObject *name, PyObject *value) { PyTypeObject *type = PyTypeObject_CAST(self); int res; - if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { + if (_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) { PyErr_Format( PyExc_TypeError, "cannot set %R attribute of immutable type '%s'", @@ -6109,7 +6109,7 @@ clear_static_tp_subclasses(PyTypeObject *type, int isbuiltin) continue; } // All static builtin subtypes should have been finalized already. - assert(!isbuiltin || !(subclass->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + assert(!isbuiltin || !_PyType_HasFeature(subclass, _Py_TPFLAGS_STATIC_BUILTIN)); Py_DECREF(subclass); } #else @@ -6137,7 +6137,7 @@ static void fini_static_type(PyInterpreterState *interp, PyTypeObject *type, int isbuiltin, int final) { - assert(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)); assert(_Py_IsImmortal((PyObject *)type)); type_dealloc_common(type); @@ -6186,7 +6186,7 @@ type_dealloc(PyObject *self) PyTypeObject *type = PyTypeObject_CAST(self); // Assert this is a heap-allocated type object - _PyObject_ASSERT((PyObject *)type, type->tp_flags & Py_TPFLAGS_HEAPTYPE); + _PyObject_ASSERT((PyObject *)type, _PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)); _PyObject_GC_UNTRACK(type); type_dealloc_common(type); @@ -6341,7 +6341,7 @@ type___sizeof___impl(PyTypeObject *self) /*[clinic end generated code: output=766f4f16cd3b1854 input=99398f24b9cf45d6]*/ { size_t size; - if (self->tp_flags & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(self, Py_TPFLAGS_HEAPTYPE)) { PyHeapTypeObject* et = (PyHeapTypeObject*)self; size = sizeof(PyHeapTypeObject); if (et->ht_cached_keys) @@ -6380,7 +6380,7 @@ type_traverse(PyObject *self, visitproc visit, void *arg) /* Because of type_is_gc(), the collector only calls this for heaptypes. */ - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { char msg[200]; sprintf(msg, "type_traverse() called on non-heap type '%.100s'", type->tp_name); @@ -6411,7 +6411,7 @@ type_clear(PyObject *self) /* Because of type_is_gc(), the collector only calls this for heaptypes. */ - _PyObject_ASSERT((PyObject *)type, type->tp_flags & Py_TPFLAGS_HEAPTYPE); + _PyObject_ASSERT((PyObject *)type, _PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)); /* We need to invalidate the method cache carefully before clearing the dict, so that other objects caught in a reference cycle @@ -6603,7 +6603,7 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } - if (type->tp_flags & Py_TPFLAGS_IS_ABSTRACT) { + if (_PyType_HasFeature(type, Py_TPFLAGS_IS_ABSTRACT)) { PyObject *abstract_methods; PyObject *sorted_methods; PyObject *joined; @@ -6767,8 +6767,8 @@ compatible_with_tp_base(PyTypeObject *child) child->tp_itemsize == parent->tp_itemsize && child->tp_dictoffset == parent->tp_dictoffset && child->tp_weaklistoffset == parent->tp_weaklistoffset && - ((child->tp_flags & Py_TPFLAGS_HAVE_GC) == - (parent->tp_flags & Py_TPFLAGS_HAVE_GC)) && + (_PyType_HasFeature(child, Py_TPFLAGS_HAVE_GC) == + _PyType_HasFeature(parent, Py_TPFLAGS_HAVE_GC)) && (child->tp_dealloc == subtype_dealloc || child->tp_dealloc == parent->tp_dealloc)); } @@ -6788,8 +6788,8 @@ same_slots_added(PyTypeObject *a, PyTypeObject *b) size += sizeof(PyObject *); /* Check slots compliance */ - if (!(a->tp_flags & Py_TPFLAGS_HEAPTYPE) || - !(b->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (!_PyType_HasFeature(a, Py_TPFLAGS_HEAPTYPE) || + !_PyType_HasFeature(b, Py_TPFLAGS_HEAPTYPE)) { return 0; } slots_a = ((PyHeapTypeObject *)a)->ht_slots; @@ -6837,14 +6837,14 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const char* !same_slots_added(newbase, oldbase))) { goto differs; } - if ((oldto->tp_flags & Py_TPFLAGS_INLINE_VALUES) != - ((newto->tp_flags & Py_TPFLAGS_INLINE_VALUES))) + if (_PyType_HasFeature(oldto, Py_TPFLAGS_INLINE_VALUES) != + _PyType_HasFeature(newto, Py_TPFLAGS_INLINE_VALUES)) { goto differs; } /* The above does not check for the preheader */ - if ((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == - ((newto->tp_flags & Py_TPFLAGS_PREHEADER))) + if ((PyType_GetFlags(oldto) & Py_TPFLAGS_PREHEADER) == + ((PyType_GetFlags(newto) & Py_TPFLAGS_PREHEADER))) { return 1; } @@ -6927,7 +6927,7 @@ object_set_class_world_stopped(PyObject *self, PyTypeObject *newto) if (compatible_for_assignment(oldto, newto, "__class__")) { /* Changing the class will change the implicit dict keys, * so we must materialize the dictionary first. */ - if (oldto->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + if (_PyType_HasFeature(oldto, Py_TPFLAGS_INLINE_VALUES)) { PyDictObject *dict = _PyObject_GetManagedDict(self); if (dict == NULL) { dict = _PyObject_MaterializeManagedDict_LockHeld(self); @@ -6943,7 +6943,7 @@ object_set_class_world_stopped(PyObject *self, PyTypeObject *newto) } } - if (newto->tp_flags & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(newto, Py_TPFLAGS_HEAPTYPE)) { Py_INCREF(newto); } @@ -6988,7 +6988,7 @@ object_set_class(PyObject *self, PyObject *value, void *closure) _PyEval_StartTheWorld(interp); #endif if (res == 0) { - if (oldto->tp_flags & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(oldto, Py_TPFLAGS_HEAPTYPE)) { Py_DECREF(oldto); } @@ -7112,7 +7112,7 @@ object_getstate_default(PyObject *obj, int required) if (required) { Py_ssize_t basicsize = PyBaseObject_Type.tp_basicsize; if (Py_TYPE(obj)->tp_dictoffset && - (Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) + !_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT)) { basicsize += sizeof(PyObject *); } @@ -7894,8 +7894,8 @@ static void inherit_special(PyTypeObject *type, PyTypeObject *base) { /* Copying tp_traverse and tp_clear is connected to the GC flags */ - if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC) && - (base->tp_flags & Py_TPFLAGS_HAVE_GC) && + if (!_PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) && + _PyType_HasFeature(base, Py_TPFLAGS_HAVE_GC) && (!type->tp_traverse && !type->tp_clear)) { type_add_flags(type, Py_TPFLAGS_HAVE_GC); if (type->tp_traverse == NULL) @@ -7903,7 +7903,7 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) if (type->tp_clear == NULL) type->tp_clear = base->tp_clear; } - type_add_flags(type, base->tp_flags & Py_TPFLAGS_PREHEADER); + type_add_flags(type, PyType_GetFlags(base) & Py_TPFLAGS_PREHEADER); if (type->tp_basicsize == 0) type->tp_basicsize = base->tp_basicsize; @@ -8144,12 +8144,12 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) COPYSLOT(tp_alloc); COPYSLOT(tp_is_gc); COPYSLOT(tp_finalize); - if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) == - (base->tp_flags & Py_TPFLAGS_HAVE_GC)) { + if (_PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) == + _PyType_HasFeature(base, Py_TPFLAGS_HAVE_GC)) { /* They agree about gc. */ COPYSLOT(tp_free); } - else if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) && + else if (_PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) && type->tp_free == NULL && base->tp_free == PyObject_Free) { /* A bit of magic to plug in the correct default @@ -8180,17 +8180,17 @@ type_ready_pre_checks(PyTypeObject *type) * tp_vectorcall_offset > 0 * To avoid mistakes, we require this before inheriting. */ - if (type->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR) { + if (_PyType_HasFeature(type, Py_TPFLAGS_METHOD_DESCRIPTOR)) { _PyObject_ASSERT((PyObject *)type, type->tp_descr_get != NULL); } - if (type->tp_flags & Py_TPFLAGS_HAVE_VECTORCALL) { + if (_PyType_HasFeature(type, Py_TPFLAGS_HAVE_VECTORCALL)) { _PyObject_ASSERT((PyObject *)type, type->tp_vectorcall_offset > 0); _PyObject_ASSERT((PyObject *)type, type->tp_call != NULL); } /* Consistency checks for pattern matching * Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING are mutually exclusive */ - _PyObject_ASSERT((PyObject *)type, (type->tp_flags & COLLECTION_FLAGS) != COLLECTION_FLAGS); + _PyObject_ASSERT((PyObject *)type, (PyType_GetFlags(type) & COLLECTION_FLAGS) != COLLECTION_FLAGS); if (type->tp_name == NULL) { PyErr_Format(PyExc_SystemError, @@ -8208,7 +8208,7 @@ type_ready_set_base(PyTypeObject *type) PyTypeObject *base = type->tp_base; if (base == NULL && type != &PyBaseObject_Type) { base = &PyBaseObject_Type; - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { type->tp_base = (PyTypeObject*)Py_NewRef((PyObject*)base); } else { @@ -8251,7 +8251,7 @@ type_ready_set_type(PyTypeObject *type) static int type_ready_set_bases(PyTypeObject *type, int initial) { - if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)) { if (!initial) { assert(lookup_tp_bases(type) != NULL); return 0; @@ -8355,7 +8355,7 @@ type_ready_fill_dict(PyTypeObject *type) static int type_ready_preheader(PyTypeObject *type) { - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)) { if (type->tp_dictoffset > 0 || type->tp_dictoffset < -1) { PyErr_Format(PyExc_TypeError, "type %s has the Py_TPFLAGS_MANAGED_DICT flag " @@ -8365,7 +8365,7 @@ type_ready_preheader(PyTypeObject *type) } type->tp_dictoffset = -1; } - if (type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) { + if (_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_WEAKREF)) { if (type->tp_weaklistoffset != 0 && type->tp_weaklistoffset != MANAGED_WEAKREF_OFFSET) { @@ -8385,7 +8385,7 @@ type_ready_mro(PyTypeObject *type, int initial) { ASSERT_TYPE_LOCK_HELD(); - if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)) { if (!initial) { assert(lookup_tp_mro(type) != NULL); return 0; @@ -8403,20 +8403,20 @@ type_ready_mro(PyTypeObject *type, int initial) /* All bases of statically allocated type should be statically allocated, and static builtin types must have static builtin bases. */ - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { - assert(type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE); + if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { + assert(_PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)); Py_ssize_t n = PyTuple_GET_SIZE(mro); for (Py_ssize_t i = 0; i < n; i++) { PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(mro, i)); - if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(base, Py_TPFLAGS_HEAPTYPE)) { PyErr_Format(PyExc_TypeError, "type '%.100s' is not dynamically allocated but " "its base type '%.100s' is dynamically allocated", type->tp_name, base->tp_name); return -1; } - assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) || - (base->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + assert(!_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN) || + _PyType_HasFeature(base, _Py_TPFLAGS_STATIC_BUILTIN)); } } return 0; @@ -8450,8 +8450,8 @@ type_ready_inherit_as_structs(PyTypeObject *type, PyTypeObject *base) static void inherit_patma_flags(PyTypeObject *type, PyTypeObject *base) { - if ((type->tp_flags & COLLECTION_FLAGS) == 0) { - type_add_flags(type, base->tp_flags & COLLECTION_FLAGS); + if (!_PyType_HasFeature(type, COLLECTION_FLAGS)) { + type_add_flags(type, PyType_GetFlags(base) & COLLECTION_FLAGS); } } @@ -8484,7 +8484,7 @@ type_ready_inherit(PyTypeObject *type) } /* Sanity check for tp_free. */ - if (_PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) && + if (_PyType_IS_GC(type) && _PyType_HasFeature(type, Py_TPFLAGS_BASETYPE) && (type->tp_free == NULL || type->tp_free == PyObject_Free)) { /* This base class needs to call tp_free, but doesn't have @@ -8564,12 +8564,12 @@ type_ready_set_new(PyTypeObject *type, int initial) default also inherit object.__new__. */ if (type->tp_new == NULL && base == &PyBaseObject_Type - && !(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) + && !_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { type_add_flags(type, Py_TPFLAGS_DISALLOW_INSTANTIATION); } - if (!(type->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION)) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_DISALLOW_INSTANTIATION)) { if (type->tp_new != NULL) { if (initial || base == NULL || type->tp_new != base->tp_new) { // If "__new__" key does not exists in the type dictionary, @@ -8594,10 +8594,10 @@ type_ready_set_new(PyTypeObject *type, int initial) static int type_ready_managed_dict(PyTypeObject *type) { - if (!(type->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)) { return 0; } - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { PyErr_Format(PyExc_SystemError, "type %s has the Py_TPFLAGS_MANAGED_DICT flag " "but not Py_TPFLAGS_HEAPTYPE flag", @@ -8623,7 +8623,7 @@ type_ready_post_checks(PyTypeObject *type) { // bpo-44263: tp_traverse is required if Py_TPFLAGS_HAVE_GC is set. // Note: tp_clear is optional. - if (type->tp_flags & Py_TPFLAGS_HAVE_GC + if (_PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) && type->tp_traverse == NULL) { PyErr_Format(PyExc_SystemError, @@ -8632,7 +8632,7 @@ type_ready_post_checks(PyTypeObject *type) type->tp_name); return -1; } - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)) { if (type->tp_dictoffset != -1) { PyErr_Format(PyExc_SystemError, "type %s has the Py_TPFLAGS_MANAGED_DICT flag " @@ -8733,14 +8733,14 @@ type_ready(PyTypeObject *type, int initial) int PyType_Ready(PyTypeObject *type) { - if (type->tp_flags & Py_TPFLAGS_READY) { + if (_PyType_HasFeature(type, Py_TPFLAGS_READY)) { assert(_PyType_CheckConsistency(type)); return 0; } - assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + assert(!_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)); /* Historically, all static types were immutable. See bpo-43908 */ - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { type_add_flags(type, Py_TPFLAGS_IMMUTABLETYPE); /* Static types must be immortal */ _Py_SetImmortalUntracked((PyObject *)type); @@ -8748,7 +8748,7 @@ PyType_Ready(PyTypeObject *type) int res; BEGIN_TYPE_LOCK(); - if (!(type->tp_flags & Py_TPFLAGS_READY)) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_READY)) { res = type_ready(type, 1); } else { res = 0; @@ -8764,11 +8764,11 @@ init_static_type(PyInterpreterState *interp, PyTypeObject *self, int isbuiltin, int initial) { assert(_Py_IsImmortal((PyObject *)self)); - assert(!(self->tp_flags & Py_TPFLAGS_HEAPTYPE)); - assert(!(self->tp_flags & Py_TPFLAGS_MANAGED_DICT)); - assert(!(self->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF)); + assert(!_PyType_HasFeature(self, Py_TPFLAGS_HEAPTYPE)); + assert(!_PyType_HasFeature(self, Py_TPFLAGS_MANAGED_DICT)); + assert(!_PyType_HasFeature(self, Py_TPFLAGS_MANAGED_WEAKREF)); - if ((self->tp_flags & Py_TPFLAGS_READY) == 0) { + if (!_PyType_HasFeature(self, Py_TPFLAGS_READY)) { assert(initial); type_add_flags(self, _Py_TPFLAGS_STATIC_BUILTIN); @@ -8781,7 +8781,7 @@ init_static_type(PyInterpreterState *interp, PyTypeObject *self, } else { assert(!initial); - assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(_PyType_HasFeature(self, _Py_TPFLAGS_STATIC_BUILTIN)); assert(self->tp_version_tag != 0); } @@ -8801,7 +8801,7 @@ init_static_type(PyInterpreterState *interp, PyTypeObject *self, int _PyStaticType_InitForExtension(PyInterpreterState *interp, PyTypeObject *self) { - return init_static_type(interp, self, 0, ((self->tp_flags & Py_TPFLAGS_READY) == 0)); + return init_static_type(interp, self, 0, !_PyType_HasFeature(self, Py_TPFLAGS_READY)); } int @@ -11474,7 +11474,7 @@ add_operators(PyTypeObject *type) if (!ptr || !*ptr) continue; /* Also ignore when the type slot has been inherited. */ - if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN + if (_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN) && type->tp_base != NULL && slot_inherited(type, p, ptr)) { diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 24aa7bbb87c193..901386cb2f02af 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2204,7 +2204,7 @@ dummy_func( op(_CHECK_MANAGED_OBJECT_HAS_VALUES, (owner -- owner)) { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(Py_TYPE(owner_o)->tp_dictoffset < 0); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_INLINE_VALUES)); DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid)); } @@ -2264,7 +2264,7 @@ dummy_func( op(_LOAD_ATTR_WITH_HINT, (hint/1, owner -- attr)) { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_MANAGED_DICT)); PyDictObject *dict = _PyObject_GetManagedDict(owner_o); DEOPT_IF(dict == NULL); assert(PyDict_CheckExact((PyObject *)dict)); @@ -2414,7 +2414,7 @@ dummy_func( PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(Py_TYPE(owner_o)->tp_dictoffset < 0); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_INLINE_VALUES)); if (_PyObject_GetManagedDict(owner_o) || !FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid)) { UNLOCK_OBJECT(owner_o); @@ -2448,7 +2448,7 @@ dummy_func( op(_STORE_ATTR_WITH_HINT, (hint/1, value, owner --)) { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_MANAGED_DICT)); PyDictObject *dict = _PyObject_GetManagedDict(owner_o); DEOPT_IF(dict == NULL); DEOPT_IF(!LOCK_OBJECT(dict)); @@ -2919,12 +2919,12 @@ dummy_func( } inst(MATCH_MAPPING, (subject -- subject, res)) { - int match = PyStackRef_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; + int match = _PyType_HasFeature(PyStackRef_TYPE(subject), Py_TPFLAGS_MAPPING); res = match ? PyStackRef_True : PyStackRef_False; } inst(MATCH_SEQUENCE, (subject -- subject, res)) { - int match = PyStackRef_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; + int match = _PyType_HasFeature(PyStackRef_TYPE(subject), Py_TPFLAGS_SEQUENCE); res = match ? PyStackRef_True : PyStackRef_False; } @@ -3328,7 +3328,7 @@ dummy_func( op(_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, (owner -- owner)) { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_INLINE_VALUES)); PyDictValues *ivs = _PyObject_InlineValues(owner_o); DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(ivs->valid)); } @@ -3841,7 +3841,7 @@ dummy_func( PyTypeObject *tp = (PyTypeObject *)callable_o; DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(tp->tp_version_tag) != type_version); assert(tp->tp_new == PyBaseObject_Type.tp_new); - assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); + assert(_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)); assert(tp->tp_alloc == PyType_GenericAlloc); PyHeapTypeObject *cls = (PyHeapTypeObject *)callable_o; PyFunctionObject *init_func = (PyFunctionObject *)FT_ATOMIC_LOAD_PTR_ACQUIRE(cls->_spec_cache.init); diff --git a/Python/crossinterp.c b/Python/crossinterp.c index aa2c1cb78bce06..03dc5e1a136b66 100644 --- a/Python/crossinterp.c +++ b/Python/crossinterp.c @@ -475,7 +475,7 @@ _excinfo_init_type_from_exception(struct _excinfo_type *info, PyObject *exc) PyObject *strobj = NULL; PyTypeObject *type = Py_TYPE(exc); - if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_PyType_HasFeature(type, _Py_TPFLAGS_STATIC_BUILTIN)) { assert(_Py_IsImmortal((PyObject *)type)); info->builtin = type; } @@ -560,12 +560,11 @@ _excinfo_init_type_from_object(struct _excinfo_type *info, PyObject *exctype) return 0; } - static void _excinfo_clear_type(struct _excinfo_type *info) { if (info->builtin != NULL) { - assert(info->builtin->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(_PyType_HasFeature(info->builtin, _Py_TPFLAGS_STATIC_BUILTIN)); assert(_Py_IsImmortal((PyObject *)info->builtin)); } if (info->name != NULL) { diff --git a/Python/crossinterp_data_lookup.h b/Python/crossinterp_data_lookup.h index 48e5d9762cd697..1032fe7f1bc431 100644 --- a/Python/crossinterp_data_lookup.h +++ b/Python/crossinterp_data_lookup.h @@ -134,7 +134,7 @@ _xidregistry_unlock(dlregistry_t *registry) static inline dlregistry_t * _get_xidregistry_for_type(dlcontext_t *ctx, PyTypeObject *cls) { - if (cls->tp_flags & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(cls, Py_TPFLAGS_HEAPTYPE)) { return &ctx->local->registry; } return &ctx->global->registry; @@ -157,7 +157,7 @@ _xidregistry_find_type(dlregistry_t *xidregistry, PyTypeObject *cls) } assert(PyType_Check(registered)); assert(cur->cls == (PyTypeObject *)registered); - assert(cur->cls->tp_flags & Py_TPFLAGS_HEAPTYPE); + assert(_PyType_HasFeature(cur->cls, Py_TPFLAGS_HEAPTYPE)); Py_DECREF(registered); } if (cur->cls == cls) { @@ -200,7 +200,7 @@ _xidregistry_add_type(dlregistry_t *xidregistry, .refcount = 1, .getdata = getdata, }; - if (cls->tp_flags & Py_TPFLAGS_HEAPTYPE) { + if (_PyType_HasFeature(cls, Py_TPFLAGS_HEAPTYPE)) { // XXX Assign a callback to clear the entry from the registry? newhead->weakref = PyWeakref_NewRef((PyObject *)cls, NULL); if (newhead->weakref == NULL) { diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 29160b9f6634c5..1500e0337d49e3 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -3080,7 +3080,7 @@ owner = stack_pointer[-1]; PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(Py_TYPE(owner_o)->tp_dictoffset < 0); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_INLINE_VALUES)); if (!FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); @@ -3170,7 +3170,7 @@ owner = stack_pointer[-1]; uint16_t hint = (uint16_t)CURRENT_OPERAND0(); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_MANAGED_DICT)); PyDictObject *dict = _PyObject_GetManagedDict(owner_o); if (dict == NULL) { UOP_STAT_INC(uopcode, miss); @@ -3332,7 +3332,7 @@ owner = stack_pointer[-1]; PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(Py_TYPE(owner_o)->tp_dictoffset < 0); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_INLINE_VALUES)); if (_PyObject_GetManagedDict(owner_o) || !FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid)) { UNLOCK_OBJECT(owner_o); @@ -3379,7 +3379,7 @@ value = stack_pointer[-2]; uint16_t hint = (uint16_t)CURRENT_OPERAND0(); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_MANAGED_DICT)); PyDictObject *dict = _PyObject_GetManagedDict(owner_o); if (dict == NULL) { UOP_STAT_INC(uopcode, miss); @@ -3974,7 +3974,7 @@ _PyStackRef subject; _PyStackRef res; subject = stack_pointer[-1]; - int match = PyStackRef_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; + int match = _PyType_HasFeature(PyStackRef_TYPE(subject), Py_TPFLAGS_MAPPING); res = match ? PyStackRef_True : PyStackRef_False; stack_pointer[0] = res; stack_pointer += 1; @@ -3986,7 +3986,7 @@ _PyStackRef subject; _PyStackRef res; subject = stack_pointer[-1]; - int match = PyStackRef_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; + int match = _PyType_HasFeature(PyStackRef_TYPE(subject), Py_TPFLAGS_SEQUENCE); res = match ? PyStackRef_True : PyStackRef_False; stack_pointer[0] = res; stack_pointer += 1; @@ -4405,7 +4405,7 @@ _PyStackRef owner; owner = stack_pointer[-1]; PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_INLINE_VALUES)); PyDictValues *ivs = _PyObject_InlineValues(owner_o); if (!FT_ATOMIC_LOAD_UINT8(ivs->valid)) { UOP_STAT_INC(uopcode, miss); @@ -5164,7 +5164,7 @@ JUMP_TO_JUMP_TARGET(); } assert(tp->tp_new == PyBaseObject_Type.tp_new); - assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); + assert(_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)); assert(tp->tp_alloc == PyType_GenericAlloc); PyHeapTypeObject *cls = (PyHeapTypeObject *)callable_o; PyFunctionObject *init_func = (PyFunctionObject *)FT_ATOMIC_LOAD_PTR_ACQUIRE(cls->_spec_cache.init); diff --git a/Python/gc.c b/Python/gc.c index 7faf368f35898a..f0455813069be2 100644 --- a/Python/gc.c +++ b/Python/gc.c @@ -2281,7 +2281,7 @@ _PyObject_GC_New(PyTypeObject *tp) return NULL; } _PyObject_Init(op, tp); - if (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)) { _PyObject_InitInlineValues(op, tp); } return op; diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index 694f97d5c57334..69454def48b9d3 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -2566,7 +2566,7 @@ _PyObject_GC_New(PyTypeObject *tp) return NULL; } _PyObject_Init(op, tp); - if (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)) { _PyObject_InitInlineValues(op, tp); } return op; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 5216918560a487..8ec1a8d4110f09 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1500,7 +1500,7 @@ JUMP_TO_PREDICTED(CALL); } assert(tp->tp_new == PyBaseObject_Type.tp_new); - assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); + assert(_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)); assert(tp->tp_alloc == PyType_GenericAlloc); PyHeapTypeObject *cls = (PyHeapTypeObject *)callable_o; PyFunctionObject *init_func = (PyFunctionObject *)FT_ATOMIC_LOAD_PTR_ACQUIRE(cls->_spec_cache.init); @@ -7946,7 +7946,7 @@ { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(Py_TYPE(owner_o)->tp_dictoffset < 0); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_INLINE_VALUES)); if (!FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid)) { UPDATE_MISS_STATS(LOAD_ATTR); assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); @@ -8125,7 +8125,7 @@ // _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_INLINE_VALUES)); PyDictValues *ivs = _PyObject_InlineValues(owner_o); if (!FT_ATOMIC_LOAD_UINT8(ivs->valid)) { UPDATE_MISS_STATS(LOAD_ATTR); @@ -8311,7 +8311,7 @@ // _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_INLINE_VALUES)); PyDictValues *ivs = _PyObject_InlineValues(owner_o); if (!FT_ATOMIC_LOAD_UINT8(ivs->valid)) { UPDATE_MISS_STATS(LOAD_ATTR); @@ -8544,7 +8544,7 @@ { uint16_t hint = read_u16(&this_instr[4].cache); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_MANAGED_DICT)); PyDictObject *dict = _PyObject_GetManagedDict(owner_o); if (dict == NULL) { UPDATE_MISS_STATS(LOAD_ATTR); @@ -9739,7 +9739,7 @@ _PyStackRef subject; _PyStackRef res; subject = stack_pointer[-1]; - int match = PyStackRef_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; + int match = _PyType_HasFeature(PyStackRef_TYPE(subject), Py_TPFLAGS_MAPPING); res = match ? PyStackRef_True : PyStackRef_False; stack_pointer[0] = res; stack_pointer += 1; @@ -9758,7 +9758,7 @@ _PyStackRef subject; _PyStackRef res; subject = stack_pointer[-1]; - int match = PyStackRef_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; + int match = _PyType_HasFeature(PyStackRef_TYPE(subject), Py_TPFLAGS_SEQUENCE); res = match ? PyStackRef_True : PyStackRef_False; stack_pointer[0] = res; stack_pointer += 1; @@ -10689,7 +10689,7 @@ { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); assert(Py_TYPE(owner_o)->tp_dictoffset < 0); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_INLINE_VALUES); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_INLINE_VALUES)); if (_PyObject_GetManagedDict(owner_o) || !FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid)) { UNLOCK_OBJECT(owner_o); @@ -10808,7 +10808,7 @@ value = stack_pointer[-2]; uint16_t hint = read_u16(&this_instr[4].cache); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + assert(_PyType_HasFeature(Py_TYPE(owner_o), Py_TPFLAGS_MANAGED_DICT)); PyDictObject *dict = _PyObject_GetManagedDict(owner_o); if (dict == NULL) { UPDATE_MISS_STATS(STORE_ATTR); diff --git a/Python/specialize.c b/Python/specialize.c index c741c4f93f3138..d3297e5f752681 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -787,7 +787,7 @@ specialize_module_load_attr( PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { PyModuleObject *m = (PyModuleObject *)owner; - assert((Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); + assert(!_PyType_HasFeature(Py_TYPE(owner), Py_TPFLAGS_MANAGED_DICT)); PyDictObject *dict = (PyDictObject *)m->md_dict; if (dict == NULL) { SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_NO_DICT); @@ -849,7 +849,7 @@ classify_descriptor(PyObject *descriptor, bool has_getattr) return ABSENT; } PyTypeObject *desc_cls = Py_TYPE(descriptor); - if (!(desc_cls->tp_flags & Py_TPFLAGS_IMMUTABLETYPE)) { + if (!_PyType_HasFeature(desc_cls, Py_TPFLAGS_IMMUTABLETYPE)) { return MUTABLE; } if (desc_cls->tp_descr_set) { @@ -870,7 +870,7 @@ classify_descriptor(PyObject *descriptor, bool has_getattr) return OVERRIDING; } if (desc_cls->tp_descr_get) { - if (desc_cls->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR) { + if (_PyType_HasFeature(desc_cls, Py_TPFLAGS_METHOD_DESCRIPTOR)) { return METHOD; } if (Py_IS_TYPE(descriptor, &PyClassMethodDescr_Type)) { @@ -1037,11 +1037,11 @@ specialize_dict_access( kind == BUILTIN_CLASSMETHOD || kind == PYTHON_CLASSMETHOD || kind == METHOD); // No descriptor, or non overriding. - if ((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + if (!_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)) { SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NOT_MANAGED_DICT); return 0; } - if (type->tp_flags & Py_TPFLAGS_INLINE_VALUES && + if (_PyType_HasFeature(type, Py_TPFLAGS_INLINE_VALUES ) && FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner)->valid) && !(base_op == STORE_ATTR && _PyObject_GetManagedDict(owner) != NULL)) { @@ -1094,10 +1094,10 @@ static bool instance_has_key(PyObject *obj, PyObject *name, uint32_t *shared_keys_version) { PyTypeObject *cls = Py_TYPE(obj); - if ((cls->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + if (!_PyType_HasFeature(cls, Py_TPFLAGS_MANAGED_DICT)) { return false; } - if (cls->tp_flags & Py_TPFLAGS_INLINE_VALUES) { + if (_PyType_HasFeature(cls, Py_TPFLAGS_INLINE_VALUES)) { PyDictKeysObject *keys = ((PyHeapTypeObject *)cls)->ht_cached_keys; Py_ssize_t index = _PyDictKeys_StringLookupAndVersion(keys, name, shared_keys_version); @@ -1528,7 +1528,7 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr, return -1; } bool metaclass_check = false; - if ((Py_TYPE(cls)->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) { + if (!_PyType_HasFeature(Py_TYPE(cls), Py_TPFLAGS_IMMUTABLETYPE)) { metaclass_check = true; if (meta_version == 0) { SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS); @@ -1948,7 +1948,7 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs) { assert(PyType_Check(callable)); PyTypeObject *tp = _PyType_CAST(callable); - if (tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { + if (_PyType_HasFeature(tp, Py_TPFLAGS_IMMUTABLETYPE)) { int oparg = instr->op.arg; if (nargs == 1 && oparg == 1) { if (tp == &PyUnicode_Type) { @@ -2329,7 +2329,7 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs) PyTypeObject *container_type = Py_TYPE(lhs); PyObject *descriptor = _PyType_LookupRefAndVersion(container_type, &_Py_ID(__getitem__), &tp_version); if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type) { - if (!(container_type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + if (!_PyType_HasFeature(container_type, Py_TPFLAGS_HEAPTYPE)) { Py_DECREF(descriptor); return SPEC_FAIL_BINARY_OP_SUBSCR_NOT_HEAP_TYPE; } @@ -2585,7 +2585,7 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in PyTypeObject *container_type = Py_TYPE(lhs); PyObject *descriptor = _PyType_LookupRefAndVersion(container_type, &_Py_ID(__getitem__), &tp_version); if (descriptor && Py_TYPE(descriptor) == &PyFunction_Type && - container_type->tp_flags & Py_TPFLAGS_HEAPTYPE) + _PyType_HasFeature(container_type, Py_TPFLAGS_HEAPTYPE)) { PyFunctionObject *func = (PyFunctionObject *)descriptor; PyCodeObject *fcode = (PyCodeObject *)func->func_code;