Skip to content

Commit f6bba23

Browse files
gh-157217: Unwrap mappingproxy locally in dict_merge
1 parent 7c09a6e commit f6bba23

1 file changed

Lines changed: 7 additions & 4 deletions

File tree

Objects/dictobject.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ As a consequence of this, split keys have a maximum size of 16.
121121
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
122122
#include "pycore_code.h" // stats
123123
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION, Py_END_CRITICAL_SECTION
124-
#include "pycore_descrobject.h" // _PyDictProxy_GetMapping()
125124
#include "pycore_dict.h" // export _PyDict_SizeOf()
126125
#include "pycore_freelist.h" // _PyFreeListState_GET()
127126
#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
@@ -4309,11 +4308,15 @@ dict_merge(PyObject *a, PyObject *b, int override, PyObject **dupkey)
43094308
/* Mapping proxies (including type.__dict__) wrap a real dict. Unwrap
43104309
* so we take the locked dict-to-dict path instead of iterating the
43114310
* proxy without holding the underlying dict's critical section.
4312-
* See gh-157217.
4311+
* Layout must match mappingproxyobject in descrobject.c. See gh-157217.
43134312
*/
4313+
typedef struct {
4314+
PyObject_HEAD
4315+
PyObject *mapping;
4316+
} mappingproxyobject;
43144317
PyObject *source = b;
4315-
if (PyObject_TypeCheck(b, &PyDictProxy_Type)) {
4316-
source = _PyDictProxy_GetMapping(b);
4318+
if (Py_IS_TYPE(b, &PyDictProxy_Type)) {
4319+
source = ((mappingproxyobject *)b)->mapping;
43174320
}
43184321

43194322
int res = 0;

0 commit comments

Comments
 (0)