Skip to content

gh-129817: Use _PyType_HasFeature() to check tp_flags. #130892

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Include/internal/pycore_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
}

Expand All @@ -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);
}

Expand Down
3 changes: 2 additions & 1 deletion Include/internal/pycore_typeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion Modules/_testinternalcapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
32 changes: 16 additions & 16 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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 {
Expand All @@ -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++) {
Expand Down Expand Up @@ -7265,15 +7265,15 @@ 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));
Py_END_CRITICAL_SECTION();
#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)) {
Expand Down Expand Up @@ -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);

Expand All @@ -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
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand Down
18 changes: 9 additions & 9 deletions Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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) {
Expand All @@ -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 {
Expand Down Expand Up @@ -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;
}
Expand Down
10 changes: 6 additions & 4 deletions Objects/structseq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading
Loading