PyAPI_FUNC(void *) PyObject_GetItemData(PyObject *obj);
PyAPI_FUNC(int) PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg);
-PyAPI_FUNC(void) _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict);
+PyAPI_FUNC(int) _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict);
PyAPI_FUNC(void) PyObject_ClearManagedDict(PyObject *obj);
#define TYPE_MAX_WATCHERS 8
}
}
-void
+int
_PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict)
{
assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
assert(_PyObject_InlineValuesConsistencyCheck(obj));
+ int err = 0;
PyTypeObject *tp = Py_TYPE(obj);
if (tp->tp_flags & Py_TPFLAGS_INLINE_VALUES) {
PyDictObject *dict = _PyObject_GetManagedDict(obj);
Py_END_CRITICAL_SECTION();
if (dict == NULL) {
- return;
+ return 0;
}
#else
set_dict_inline_values(obj, (PyDictObject *)new_dict);
- return;
+ return 0;
#endif
}
// We've locked dict, but the actual dict could have changed
// since we locked it.
dict = _PyObject_ManagedDictPointer(obj)->dict;
-
- FT_ATOMIC_STORE_PTR(_PyObject_ManagedDictPointer(obj)->dict,
- (PyDictObject *)Py_XNewRef(new_dict));
-
- _PyDict_DetachFromObject(dict, obj);
-
+ err = _PyDict_DetachFromObject(dict, obj);
+ if (err == 0) {
+ FT_ATOMIC_STORE_PTR(_PyObject_ManagedDictPointer(obj)->dict,
+ (PyDictObject *)Py_XNewRef(new_dict));
+ }
Py_END_CRITICAL_SECTION2();
- Py_XDECREF(dict);
+ if (err == 0) {
+ Py_XDECREF(dict);
+ }
}
else {
PyDictObject *dict;
Py_XDECREF(dict);
}
assert(_PyObject_InlineValuesConsistencyCheck(obj));
+ return err;
}
void
PyObject_ClearManagedDict(PyObject *obj)
{
- _PyObject_SetManagedDict(obj, NULL);
+ if (_PyObject_SetManagedDict(obj, NULL) < 0) {
+ PyErr_WriteUnraisable(NULL);
+ }
}
int
_PyDict_DetachFromObject(PyDictObject *mp, PyObject *obj)
{
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(obj);
+ assert(_PyObject_ManagedDictPointer(obj)->dict == mp);
+ assert(_PyObject_InlineValuesConsistencyCheck(obj));
if (FT_ATOMIC_LOAD_PTR_RELAXED(mp->ma_values) != _PyObject_InlineValues(obj)) {
return 0;