Monkey Patching class derived from ctypes.Union doesn't work

后端 未结 1 1019
半阙折子戏
半阙折子戏 2021-01-20 15:31

I am trying to \"monkey patch\" a class derived from Python ctypes \"Union\", but I am unable to do so - getting weird errors and sometimes seg-faults. The same thing works

相关标签:
1条回答
  • 2021-01-20 15:57

    I think there's an actual CPython bug here. The __setattr__ implementation for type objects for struct types uses PyType_Type.tp_setattro:

    static int
    PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value)
    {
        /* XXX Should we disallow deleting _fields_? */
        if (-1 == PyType_Type.tp_setattro(self, key, value))
            return -1;
    
        if (value && PyUnicode_Check(key) &&
            _PyUnicode_EqualToASCIIString(key, "_fields_"))
            return PyCStructUnionType_update_stgdict(self, value, 1);
        return 0;
    }
    

    but the one for type objects for union types uses PyObject_GenericSetAttr:

    static int
    UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
    {
        /* XXX Should we disallow deleting _fields_? */
        if (-1 == PyObject_GenericSetAttr(self, key, value))
            return -1;
    
        if (PyUnicode_Check(key) &&
            _PyUnicode_EqualToASCIIString(key, "_fields_"))
            return PyCStructUnionType_update_stgdict(self, value, 0);
        return 0;
    }
    

    The use of PyType_Type.tp_setattro is necessary to update type slots and invalidate the internal type attribute cache. PyObject_GenericSetAttr doesn't know it should do either of those things, causing potential memory corruption due to "zombie" cached attributes. It looks like the same bug was fixed in early 2008 for structs, but they forgot to handle unions.

    0 讨论(0)
提交回复
热议问题