diff options
author | Thomas Heller <theller@ctypes.org> | 2009-09-18 19:46:56 (GMT) |
---|---|---|
committer | Thomas Heller <theller@ctypes.org> | 2009-09-18 19:46:56 (GMT) |
commit | 35888e2b3c0c36e6a6286416a60324da14b5560e (patch) | |
tree | 32b81c91693d8e98c4474387b6b27ccc66ef61d7 /Modules | |
parent | e40c4de982625ef1cea86a3ea2e84160a04d3cca (diff) | |
download | cpython-35888e2b3c0c36e6a6286416a60324da14b5560e.zip cpython-35888e2b3c0c36e6a6286416a60324da14b5560e.tar.gz cpython-35888e2b3c0c36e6a6286416a60324da14b5560e.tar.bz2 |
Merged revisions 74918 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k
................
r74918 | thomas.heller | 2009-09-18 21:05:13 +0200 (Fr, 18 Sep 2009) | 11 lines
Merged revisions 74917 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r74917 | thomas.heller | 2009-09-18 20:55:17 +0200 (Fr, 18 Sep 2009) | 3 lines
Issue #5042: Structure sub-subclass does now initialize correctly with
base class positional arguments.
........
Also made small stylistic changes.
................
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_ctypes/_ctypes.c | 131 |
1 files changed, 73 insertions, 58 deletions
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index a62b716..41264d3 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -3936,82 +3936,97 @@ IBUG(char *msg) return -1; } +/* + This function is called to initialize a Structure or Union with positional + arguments. It calls itself recursively for all Structure or Union base + classes, then retrieves the _fields_ member to associate the argument + position with the correct field name. + + Returns -1 on error, or the index of next argument on success. + */ static int -Struct_init(PyObject *self, PyObject *args, PyObject *kwds) +_init_pos_args(PyObject *self, PyTypeObject *type, + PyObject *args, PyObject *kwds, + int index) { - int i; + StgDictObject *dict; PyObject *fields; + int i; + + if (PyType_stgdict((PyObject *)type->tp_base)) { + index = _init_pos_args(self, type->tp_base, + args, kwds, + index); + if (index == -1) + return -1; + } + + dict = PyType_stgdict((PyObject *)type); + fields = PyDict_GetItemString((PyObject *)dict, "_fields_"); + if (fields == NULL) + return index; + + for (i = 0; + i < dict->length && (i+index) < PyTuple_GET_SIZE(args); + ++i) { + PyObject *pair = PySequence_GetItem(fields, i); + PyObject *name, *val; + int res; + if (!pair) + return -1; + name = PySequence_GetItem(pair, 0); + if (!name) { + Py_DECREF(pair); + return -1; + } + val = PyTuple_GET_ITEM(args, i + index); + if (kwds && PyDict_GetItem(kwds, name)) { + char *field = PyBytes_AsString(name); + if (field == NULL) { + PyErr_Clear(); + field = "???"; + } + PyErr_Format(PyExc_TypeError, + "duplicate values for field '%s'", + field); + Py_DECREF(pair); + Py_DECREF(name); + return -1; + } + + res = PyObject_SetAttr(self, name, val); + Py_DECREF(pair); + Py_DECREF(name); + if (res == -1) + return -1; + } + return index + dict->length; +} + +static int +Struct_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + StgDictObject *stgdict = PyObject_stgdict(self); /* Optimization possible: Store the attribute names _fields_[x][0] * in C accessible fields somewhere ? */ -/* Check this code again for correctness! */ - if (!PyTuple_Check(args)) { PyErr_SetString(PyExc_TypeError, "args not a tuple?"); return -1; } if (PyTuple_GET_SIZE(args)) { - fields = PyObject_GetAttrString(self, "_fields_"); - if (!fields) { - PyErr_Clear(); - fields = PyTuple_New(0); - if (!fields) - return -1; - } - - if (PyTuple_GET_SIZE(args) > PySequence_Length(fields)) { - Py_DECREF(fields); + int res = _init_pos_args(self, Py_TYPE(self), + args, kwds, 0); + if (res == -1) + return -1; + if (res < PyTuple_GET_SIZE(args)) { PyErr_SetString(PyExc_TypeError, "too many initializers"); return -1; } - - for (i = 0; i < PyTuple_GET_SIZE(args); ++i) { - PyObject *pair = PySequence_GetItem(fields, i); - PyObject *name; - PyObject *val; - if (!pair) { - Py_DECREF(fields); - return IBUG("_fields_[i] failed"); - } - - name = PySequence_GetItem(pair, 0); - if (!name) { - Py_DECREF(pair); - Py_DECREF(fields); - return IBUG("_fields_[i][0] failed"); - } - - if (kwds && PyDict_GetItem(kwds, name)) { - char *field = PyBytes_AsString(name); - if (field == NULL) { - PyErr_Clear(); - field = "???"; - } - PyErr_Format(PyExc_TypeError, - "duplicate values for field %s", - field); - Py_DECREF(pair); - Py_DECREF(name); - Py_DECREF(fields); - return -1; - } - - val = PyTuple_GET_ITEM(args, i); - if (-1 == PyObject_SetAttr(self, name, val)) { - Py_DECREF(pair); - Py_DECREF(name); - Py_DECREF(fields); - return -1; - } - - Py_DECREF(name); - Py_DECREF(pair); - } - Py_DECREF(fields); } if (kwds) { |