mirror of
https://github.com/python/cpython.git
synced 2025-11-01 18:51:43 +00:00
GH-106485: Handle dict subclasses correctly when dematerializing __dict__ (GH-107837)
This commit is contained in:
parent
bafedfbebd
commit
1d976b2da2
7 changed files with 169 additions and 7 deletions
|
|
@ -15,6 +15,7 @@
|
|||
#include "pycore_bytesobject.h" // _PyBytes_Find()
|
||||
#include "pycore_compile.h" // _PyCompile_CodeGen, _PyCompile_OptimizeCfg, _PyCompile_Assemble, _PyCompile_CleanDoc
|
||||
#include "pycore_ceval.h" // _PyEval_AddPendingCall
|
||||
#include "pycore_dict.h" // _PyDictOrValues_GetValues
|
||||
#include "pycore_fileutils.h" // _Py_normpath
|
||||
#include "pycore_frame.h" // _PyInterpreterFrame
|
||||
#include "pycore_gc.h" // PyGC_Head
|
||||
|
|
@ -1530,6 +1531,40 @@ test_pymem_getallocatorsname(PyObject *self, PyObject *args)
|
|||
return PyUnicode_FromString(name);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
get_object_dict_values(PyObject *self, PyObject *obj)
|
||||
{
|
||||
PyTypeObject *type = Py_TYPE(obj);
|
||||
if (!_PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj);
|
||||
if (!_PyDictOrValues_IsValues(dorv)) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
PyDictValues *values = _PyDictOrValues_GetValues(dorv);
|
||||
PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys;
|
||||
assert(keys != NULL);
|
||||
int size = (int)keys->dk_nentries;
|
||||
assert(size >= 0);
|
||||
PyObject *res = PyTuple_New(size);
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
_Py_DECLARE_STR(anon_null, "<NULL>");
|
||||
for(int i = 0; i < size; i++) {
|
||||
PyObject *item = values->values[i];
|
||||
if (item == NULL) {
|
||||
item = &_Py_STR(anon_null);
|
||||
}
|
||||
else {
|
||||
Py_INCREF(item);
|
||||
}
|
||||
PyTuple_SET_ITEM(res, i, item);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef module_functions[] = {
|
||||
{"get_configs", get_configs, METH_NOARGS},
|
||||
|
|
@ -1594,6 +1629,7 @@ static PyMethodDef module_functions[] = {
|
|||
{"check_pyobject_uninitialized_is_freed",
|
||||
check_pyobject_uninitialized_is_freed, METH_NOARGS},
|
||||
{"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS},
|
||||
{"get_object_dict_values", get_object_dict_values, METH_O},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue