Raise a TypeError if conflicting positional and named arguments are

passed to a Structure or Union constructor.
This commit is contained in:
Thomas Heller 2008-01-16 19:37:33 +00:00
parent 902d30752f
commit 02ec289f3e
3 changed files with 27 additions and 0 deletions

View File

@ -215,6 +215,15 @@ class StructureTestCase(unittest.TestCase):
# too long
self.assertRaises(ValueError, Person, "1234567", 5)
def test_conflicting_initializers(self):
class POINT(Structure):
_fields_ = [("x", c_int), ("y", c_int)]
# conflicting positional and keyword args
self.assertRaises(TypeError, POINT, 2, 3, x=4)
self.assertRaises(TypeError, POINT, 2, 3, y=4)
# Should this raise TypeError instead?
self.assertRaises(ValueError, POINT, 2, 3, 4)
def test_keyword_initializers(self):
class POINT(Structure):

View File

@ -364,6 +364,9 @@ Core and builtins
Library
-------
- Issue #1831: ctypes now raises a TypeError if conflicting positional
and named arguments are passed to a Structure or Union initializer.
- Convert the internal ctypes array type cache to a WeakValueDict so
that array types do not live longer than needed.

View File

@ -3578,6 +3578,21 @@ Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
return IBUG("_fields_[i][0] failed");
}
if (kwds && PyDict_GetItem(kwds, name)) {
char *field = PyString_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);