[3.6] bpo-31490: Fix an assertion failure in ctypes in case an _anony… · python/cpython@bdb215b (original) (raw)

File tree

3 files changed

lines changed

3 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
1 1 import unittest
2 +import test.support
2 3 from ctypes import *
3 4
4 5 class AnonTest(unittest.TestCase):
@@ -35,6 +36,18 @@ def test_anon_nonmember(self):
35 36 {"_fields_": [],
36 37 "_anonymous_": ["x"]}))
37 38
39 +@test.support.cpython_only
40 +def test_issue31490(self):
41 +# There shouldn't be an assertion failure in case the class has an
42 +# attribute whose name is specified in _anonymous_ but not in _fields_.
43 +
44 +# AttributeError: 'x' is specified in _anonymous_ but not in _fields_
45 +with self.assertRaises(AttributeError):
46 +class Name(Structure):
47 +_fields_ = []
48 +_anonymous_ = ["x"]
49 +x = 42
50 +
38 51 def test_nested(self):
39 52 class ANON_S(Structure):
40 53 _fields_ = [("a", c_int)]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1 +Fix an assertion failure in `ctypes` class definition, in case the class has
2 +an attribute whose name is specified in ``_anonymous_`` but not in
3 +``_fields_``. Patch by Oren Milman.
Original file line number Diff line number Diff line change
@@ -282,7 +282,15 @@ MakeAnonFields(PyObject *type)
282 282 Py_DECREF(anon_names);
283 283 return -1;
284 284 }
285 -assert(Py_TYPE(descr) == &PyCField_Type);
285 +if (Py_TYPE(descr) != &PyCField_Type) {
286 +PyErr_Format(PyExc_AttributeError,
287 +"'%U' is specified in _anonymous_ but not in "
288 +"_fields_",
289 +fname);
290 +Py_DECREF(anon_names);
291 +Py_DECREF(descr);
292 +return -1;
293 + }
286 294 descr->anonymous = 1;
287 295
288 296 /* descr is in the field descriptor. */