Commit 02ec289f authored by Thomas Heller's avatar Thomas Heller

Raise a TypeError if conflicting positional and named arguments are

passed to a Structure or Union constructor.
parent 902d3075
......@@ -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):
......
......@@ -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.
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment