Skip to content

Commit ca1e232

Browse files
committed
Get a strong reference to dict in instance_has_key
1 parent 816e22f commit ca1e232

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

Python/specialize.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,17 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
10401040
static int specialize_class_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name);
10411041
#endif
10421042

1043+
static PyDictObject *
1044+
get_managed_dict_ref(PyObject *obj)
1045+
{
1046+
PyDictObject *dict;
1047+
Py_BEGIN_CRITICAL_SECTION(obj);
1048+
dict = _PyObject_GetManagedDict(obj);
1049+
Py_XINCREF(dict);
1050+
Py_END_CRITICAL_SECTION();
1051+
return dict;
1052+
}
1053+
10431054
/* Returns true if instances of obj's class are
10441055
* likely to have `name` in their __dict__.
10451056
* For objects with inline values, we check in the shared keys.
@@ -1058,14 +1069,17 @@ instance_has_key(PyObject *obj, PyObject *name, uint32_t *shared_keys_version)
10581069
_PyDictKeys_StringLookupAndVersion(keys, name, shared_keys_version);
10591070
return index >= 0;
10601071
}
1061-
PyDictObject *dict = _PyObject_GetManagedDict(obj);
1072+
PyDictObject *dict = get_managed_dict_ref(obj);
10621073
if (dict == NULL || !PyDict_CheckExact(dict)) {
1074+
Py_XDECREF(dict);
10631075
return false;
10641076
}
10651077
if (dict->ma_values) {
1078+
Py_DECREF(dict);
10661079
return false;
10671080
}
10681081
Py_ssize_t index = _PyDict_LookupIndex(dict, name);
1082+
Py_DECREF(dict);
10691083
if (index < 0) {
10701084
return false;
10711085
}

0 commit comments

Comments
 (0)