diff --git a/Lib/ctypes/test/test_struct_fields.py b/Lib/ctypes/test/test_struct_fields.py index ee8415f3e63..fefeaea1496 100644 --- a/Lib/ctypes/test/test_struct_fields.py +++ b/Lib/ctypes/test/test_struct_fields.py @@ -54,6 +54,15 @@ class X(Structure): x.char = b'a\0b\0' self.assertEqual(bytes(x), b'a\x00###') + def test_gh99275(self): + class BrokenStructure(Structure): + def __init_subclass__(cls, **kwargs): + cls._fields_ = [] # This line will fail, `stgdict` is not ready + + with self.assertRaisesRegex(TypeError, + 'ctypes state is not initialized'): + class Subclass(BrokenStructure): ... + # __set__ and __get__ should raise a TypeError in case their self # argument is not a ctype instance. def test___set__(self): diff --git a/Misc/NEWS.d/next/Library/2022-11-09-12-16-35.gh-issue-99275.klOqoL.rst b/Misc/NEWS.d/next/Library/2022-11-09-12-16-35.gh-issue-99275.klOqoL.rst new file mode 100644 index 00000000000..2bf05a3bdfb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-11-09-12-16-35.gh-issue-99275.klOqoL.rst @@ -0,0 +1,2 @@ +Fix ``SystemError`` in :mod:`ctypes` when exception was not set during +``__initsubclass__``. diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index a819ce910d4..88999b8dff1 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -430,8 +430,11 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct } stgdict = PyType_stgdict(type); - if (!stgdict) + if (!stgdict) { + PyErr_SetString(PyExc_TypeError, + "ctypes state is not initialized"); return -1; + } /* If this structure/union is already marked final we cannot assign _fields_ anymore. */